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:testnpx nx run my-express-api:buildnpx 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
相关产品推荐
相关产品推荐

