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

从Webpack迁移至@nx/esbuild,替代generate-package-json-webpack-plugin方案咨询

Nx + Esbuild 替代 generate-package-json-webpack-plugin 的方案

问题背景

将基于Angular 19的Nx工作区从Webpack迁移到Esbuild后,原Webpack配置中依赖generate-package-json-webpack-plugin生成定制化package.json的功能无法复用。Nx自带的generate-package-json: true选项仅能生成基础文件,无法满足以下需求:

  • 指定name、version、private字段
  • 限制依赖为固定列表
  • 从环境变量注入BUILD_VERSION

推荐方案

方案一:自定义Esbuild插件

Esbuild支持自定义插件,可在构建流程内直接生成符合需求的package.json,步骤如下:

  1. 创建自定义插件文件(比如tools/esbuild-plugins/generate-package-json-plugin.js):
const fs = require('fs');
const path = require('path');
const rootPackageJson = require('../../package.json');

module.exports = function generatePackageJsonPlugin(options) {
  return {
    name: 'generate-custom-package-json',
    setup(build) {
      build.onEnd(async (result) => {
        if (result.errors.length > 0) return;

        const BUILD_VERSION = process.env.BUILD_VERSION || '0.0.0';
        // 固定依赖列表
        const implicitDeps = [
          '@nestjs/platform-express',
          'class-transformer',
          'passport',
          'reflect-metadata',
        ];
        const dependencies = implicitDeps.reduce((acc, dep) => {
          acc[dep] = rootPackageJson.dependencies[dep];
          return acc;
        }, {});

        const packageJsonContent = {
          name: options.name,
          version: BUILD_VERSION,
          private: true,
          dependencies,
        };

        const outputPath = path.join(options.outputPath, 'package.json');
        fs.writeFileSync(outputPath, JSON.stringify(packageJsonContent, null, 2));
      });
    },
  };
};
  1. 在project.json中配置Esbuild加载该插件:
"name": "api",
"targets": {
  "build": {
    "executor": "@nx/esbuild:esbuild",
    "options": {
      "target": "node",
      "outputPath": "dist/apps/api",
      "main": "apps/api/src/main.ts",
      "tsConfig": "apps/api/tsconfig.app.json",
      "generatePackageJson": false, // 关闭默认生成逻辑
      "plugins": [
        {
          "name": "./tools/esbuild-plugins/generate-package-json-plugin.js",
          "options": {
            "name": "api",
            "outputPath": "dist/apps/api"
          }
        }
      ]
    }
  }
}

方案二:构建后Node脚本处理

如果不想编写Esbuild插件,可利用构建后脚本修改默认生成的package.json,实现成本更低:

  1. 创建处理脚本(比如tools/scripts/post-build-fix-package.js):
const fs = require('fs');
const path = require('path');
const rootPackageJson = require('../../package.json');

const packageJsonPath = path.join(__dirname, '../../dist/apps/api/package.json');
const BUILD_VERSION = process.env.BUILD_VERSION || '0.0.0';
const implicitDeps = [
  '@nestjs/platform-express',
  'class-transformer',
  'passport',
  'reflect-metadata',
];

// 读取默认生成的package.json
const existingPackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));

// 覆盖字段并过滤依赖
const customPackageJson = {
  ...existingPackageJson,
  name: 'api',
  version: BUILD_VERSION,
  private: true,
  dependencies: implicitDeps.reduce((acc, dep) => {
    acc[dep] = rootPackageJson.dependencies[dep];
    return acc;
  }, {}),
};

// 写入修改后的内容
fs.writeFileSync(packageJsonPath, JSON.stringify(customPackageJson, null, 2));
console.log('Custom package.json generated successfully');
  1. 在project.json中添加postbuild目标,绑定到构建流程:
"name": "api",
"targets": {
  "build": {
    "executor": "@nx/esbuild:esbuild",
    "options": {
      "target": "node",
      "outputPath": "dist/apps/api",
      "main": "apps/api/src/main.ts",
      "tsConfig": "apps/api/tsconfig.app.json",
      "generatePackageJson": true // 保留默认生成,后续通过脚本修改
    }
  },
  "postbuild": {
    "executor": "nx:run-commands",
    "options": {
      "commands": ["node tools/scripts/post-build-fix-package.js"]
    },
    "dependsOn": ["build"]
  }
}

执行构建时直接运行nx run api:postbuild即可自动完成构建+package.json定制。

方案对比

  • 自定义Esbuild插件:集成度更高,构建流程内完成操作,无需额外命令触发
  • 构建后脚本:实现逻辑更简单,无需了解Esbuild插件API,适合快速迭代调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:35:19