You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NX+Express项目配置:如何同时兼容ESM库与本地工作区库

NX工作区Express应用兼容ESM库与本地工作区库配置方案

我近期创建了一个NX工作区并添加了Express应用,默认配置下运行正常。但一旦引入ESM库(例如nanoid v4+),服务器便无法启动,报错信息如下:

Error [ERR_REQUIRE_ESM]: require() of ES Module /workspace/node_modules/nanoid/index.js not supported

需要配置NX工作区与Express应用,使其既能导入ESM库,又能导入本地工作区库,且可成功执行以下命令:

  • npx nx run my-express-api:test
  • npx nx run my-express-api:build
  • npx nx run my-express-api:serve

尝试1:默认配置

使用开箱即用的配置,出现如下错误:

Error [ERR_REQUIRE_ESM]: require() of ES Module /workspace/node_modules/nanoid/index.js not supported.

Instead change the require of index.js in null to a dynamic import() which is available in all CommonJS modules.
    at Module._load (/workspace/node_modules/@nx/js/src/executors/node/node-with-require-overrides.js:18:31)
    at Array.__webpack_modules__ (/workspace/dist/apps/my-express-api/main.js:26:18)
    at __webpack_require__ (/workspace/dist/apps/my-express-api/main.js:49:41)
    at /workspace/dist/apps/my-express-api/main.js:69:18
    at /workspace/dist/apps/my-express-api/main.js:81:3
    at Object.<anonymous> (/workspace/dist/apps/my-express-api/main.js:83:12)
    at Module._load (/workspace/node_modules/@nx/js/src/executors/node/node-with-require-overrides.js:10:31)

涉及配置文件:express应用的tsconfig.app.json、webpack.config.js、project.json,以及根工作区的package.json。


尝试2:修改tsconfig/webpack配置

该修改可导入ESM库,但无法导入本地工作区库,报错如下:

ERROR in ./apps/my-express-api/src/main.ts 9:0-35
Module not found: Error: Can't resolve 'test-lib' in '/workspace/apps/my-express-api/src'
resolve 'test-lib' in '/workspace/apps/my-express-api/src'
  Parsed request is a module
  using description file: /workspace/apps/my-express-api/package.json (relative path: ./src)
    resolve as module
      /workspace/apps/my-express-api/src/node_modules doesn't exist or is not a directory
      /workspace/apps/my-express-api/node_modules doesn't exist or is not a directory
      /workspace/apps/node_modules doesn't exist or is not a directory
      looking for modules in /workspace/node_modules
        single file module
          using description file: /workspace/package.json (relative path: ./node_modules/test-lib)
            no extension
              /workspace/node_modules/test-lib doesn't exist
            .js
              /workspace/node_modules/test-lib.js doesn't exist
            .mjs
              /workspace/node_modules/test-lib.mjs doesn't exist
            .ts
              /workspace/node_modules/test-lib.ts doesn't exist
            .mts
              /workspace/node_modules/test-lib.mts doesn't exist
        /workspace/node_modules/test-lib doesn't exist
      /node_modules doesn't exist or is not a directory

涉及配置文件:project.json、jest.config.json、package.json、tsconfig.json、tsconfig.app.json、webpack.config.cjs。


尝试3:使用@nx/esbuild:esbuild

该方案可导入ESM库并正常构建/启动应用,但导入工作区JS库时出现错误:

error TS2307: Cannot find module '@myorg/mylib' or its corresponding type declarations.

涉及配置文件:project.json、package.json、tsconfig.app.json、tsconfig.base.json。


最终可行配置方案

1. 调整根工作区package.json

在根package.json中添加type: "module",同时确保所有配置文件(如webpack、jest)使用.cjs后缀:

{
  "name": "my-workspace",
  "type": "module",
  // 其他原有配置...
}

2. 配置Express应用的tsconfig.app.json

确保编译输出为ESM,同时正确映射工作区库的路径:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "NodeNext",
    "target": "ES2022",
    "outDir": "../../dist/out-tsc",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "paths": {
      "@myorg/*": ["libs/*/src/index.ts"]
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

3. 调整project.json的构建与服务配置

使用@nx/esbuild:esbuild执行器,并配置正确的格式与路径解析:

{
  "name": "my-express-api",
  "targets": {
    "build": {
      "executor": "@nx/esbuild:esbuild",
      "options": {
        "platform": "node",
        "format": ["esm"],
        "outputFileName": "main.js",
        "bundle": true,
        "main": "apps/my-express-api/src/main.ts",
        "tsConfig": "apps/my-express-api/tsconfig.app.json",
        "assets": ["apps/my-express-api/src/assets"],
        "generatePackageJson": true,
        "external": ["express"]
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "options": {
        "buildTarget": "my-express-api:build",
        "runtimeArgs": ["--experimental-specifier-resolution=node"]
      }
    },
    "test": {
      "executor": "@nx/jest:jest",
      "options": {
        "jestConfig": "apps/my-express-api/jest.config.cjs",
        "passWithNoTests": true
      }
    }
  }
}

4. 配置jest.config.cjs

确保Jest兼容ESM,添加相关转换配置:

module.exports = {
  displayName: 'my-express-api',
  preset: '../../jest.preset.js',
  testEnvironment: 'node',
  transform: {
    '^.+\\.[tj]s$': ['ts-jest', { useESM: true }]
  },
  moduleNameMapper: {
    '^@myorg/(.*)$': '<rootDir>/../libs/$1/src/index.ts'
  },
  extensionsToTreatAsEsm: ['.ts']
};

5. 调整工作区库的tsconfig.lib.json

确保库也编译为ESM格式:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "NodeNext",
    "target": "ES2022",
    "outDir": "../../dist/out-tsc",
    "declaration": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

验证命令

执行以下命令验证配置有效性:

  • npx nx run my-express-api:test:测试通过
  • npx nx run my-express-api:build:构建生成ESM格式产物
  • npx nx run my-express-api:serve:服务器正常启动,可同时导入ESM库与本地工作区库

内容的提问来源于stack exchange,提问作者BSimpson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:30:39