NX monorepo中esbuild构建Node应用无dependencies问题排查
问题:NX esbuild构建Node应用时生成的package.json缺少dependencies字段
问题背景
在NX monorepo中,通过nx g @nrwl/node:application nodeapp1创建Node.js CLI应用后,使用esbuild执行nx serve nodeapp1或nx build nodeapp1时,生成的dist/apps/nodeapp1/package.json完全没有dependencies字段,切换为webpack构建则无此问题。
生成的dist/apps/nodeapp1/package.json内容如下:
{ "name": "nodeapp1", "version": "0.0.1", "main": "./main.js" }
相关文件内容
apps/nodeapp1/src/main.ts
import * as figlet from 'figlet'; console.log(figlet.textSync('figlet', 'ANSI Shadow'));
apps/nodeapp1/project.json(默认配置未修改)
{ "name": "nodeapp1", "$schema": "../../node_modules/nx/schemas/project-schema.json", "sourceRoot": "apps/nodeapp1/src", "projectType": "application", "targets": { "build": { "executor": "@nrwl/esbuild:esbuild", "outputs": ["{options.outputPath}"], "defaultConfiguration": "production", "options": { "platform": "node", "outputPath": "dist/apps/nodeapp1", "format": ["cjs"], "bundle": false, "main": "apps/nodeapp1/src/main.ts", "tsConfig": "apps/nodeapp1/tsconfig.app.json", "assets": ["apps/nodeapp1/src/assets"], "generatePackageJson": true, "esbuildOptions": { "sourcemap": true, "outExtension": { ".js": ".js" } } }, "configurations": { "development": {}, "production": { "esbuildOptions": { "sourcemap": false, "outExtension": { ".js": ".js" } } } } }, "serve": { "executor": "@nrwl/js:node", "defaultConfiguration": "development", "options": { "buildTarget": "nodeapp1:build" }, "configurations": { "development": { "buildTarget": "nodeapp1:build:development" }, "production": { "buildTarget": "nodeapp1:build:production" } } }, "lint": { "executor": "@nrwl/linter:eslint", "outputs": ["{options.outputFile}"], "options": { "lintFilePatterns": ["apps/nodeapp1/**/*.ts"] } }, "test": { "executor": "@nrwl/jest:jest", "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "apps/nodeapp1/jest.config.ts", "passWithNoTests": true }, "configurations": { "ci": { "ci": true, "codeCoverage": true } } } }, "tags": [] }
已尝试的操作
- 在nx.json中添加配置:
"pluginsConfig": { "@nrwl/js": { "analyzeSourceFiles": true } }
- 尝试在project.json中添加
updateBuildableProjectDepsInPackageJson和buildableProjectDepsInPackageJsonType配置,但怀疑仅适用于Angular应用 - 尝试在project.json的build.options中添加
"thirdParty": false,执行构建时出现栈溢出错误:
Maximum call stack size exceeded > NX Maximum call stack size exceeded at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:7:19) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:29:13) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:29:13) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:29:13) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:29:13) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:29:13) at recur (node_modules\@nrwl\esbuild\src\executors\esbuild\lib\get-extra-dependencies.js:7:19)
解决方案
问题核心是bundle: false配置下,NX esbuild执行器默认不会自动分析第三方依赖。按以下步骤调整配置:
- 修改project.json的build配置,在
options中添加"external": "all",同时保留generatePackageJson: true:
"build": { "executor": "@nrwl/esbuild:esbuild", // 其他原有配置不变 "options": { "platform": "node", "outputPath": "dist/apps/nodeapp1", "format": ["cjs"], "bundle": false, "external": "all", // 新增该行 "main": "apps/nodeapp1/src/main.ts", "tsConfig": "apps/nodeapp1/tsconfig.app.json", "assets": ["apps/nodeapp1/src/assets"], "generatePackageJson": true, // esbuildOptions等其他配置不变 } }
- 确保tsconfig.app.json配置正确,保证依赖分析能识别第三方包:
{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", "types": ["node"] }, "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], "include": ["src/**/*.ts"] }
- 清理缓存并重新构建:
执行nx reset清除NX缓存,再运行nx build nodeapp1,此时生成的package.json会自动包含项目使用的第三方依赖(如figlet)到dependencies字段中。
原理说明
当bundle: false时,esbuild不会将依赖打包进输出文件,此时通过external: "all"标记所有依赖为外部依赖,NX的依赖分析器才能正确识别项目中使用的第三方包,并将其添加到生成的package.json中。之前尝试的thirdParty: false会触发内部递归分析bug导致栈溢出,不建议使用。
内容的提问来源于stack exchange,提问作者LaVache
相关产品推荐
相关产品推荐

