node 打包工具

痛点:源代码暴露在服务器上,如果服务器被入侵,源代码可能泄露

解决方案—打包工具

1.pkg

  • 特点:简单易用,支持将 Node.js 应用打包为 Windows、Linux、macOS 平台的可执行文件,无需安装 Node.js 即可运行。

使用教程

  • 安装:npm install -g pkg
  • 打包:
1
2
3
4
5
# 打包当前平台(根据运行命令的系统自动识别)
pkg index.js

# 指定多平台打包(Windows、Linux、macOS)
pkg -t node18-win-x64,node18-linux-x64,node18-macos-x64 index.js

注意:pkg 默认只会打包你的源码和相关依赖,node_modules 中的依赖默认不会被自动包含,尤其是需要动态加载的模块。如果需要包含依赖,可以使用 --include 参数指定依赖文件。

2. nexe

  • 特点:与 pkg 类似,但更灵活,支持自定义 Node.js 版本和编译选项,适合需要深度定制的场景
  • 安装:npm install -g nexe
  • 打包:
1
2
3
4
5
# 打包当前平台
nexe index.js

# 指定输出文件名和平台
nexe index.js -o myapp --target windows-x64-18.17.0

高级配置(通过 nexe.config.json):

1
2
3
4
5
6
{
"input": "index.js",
"output": "dist/myapp",
"target": "linux-x64-18.17.0",
"resources": ["assets/**/*"] // 打包静态资源
}

1-2 都需要借助github

3. electron-packager

  • 特点:专为 Electron 应用设计,可将前端 + Node.js 混合应用打包为桌面程序,支持多平台。
  • 安装:npm install -g electron-packager
  • 使用教程:
  1. 假设已有一个 Electron 项目(目录结构如下):
1
2
3
4
my-electron-app/
├── main.js # Electron 主进程
├── package.json
└── index.html # 渲染进程页面
  1. 打包命令:
1
2
3
4
5
# 打包当前平台(名称、版本从 package.json 读取)
electron-packager . --out=dist

# 指定平台和架构
electron-packager . MyApp --platform=win32 --arch=x64 --out=dist
  1. 打包后在 dist 目录生成对应平台的应用文件夹,可直接运行。

4. webpack + @vercel/ncc

  • 特点:适合将 Node.js 应用打包为单个 JS 文件(非可执行文件),便于部署到服务器(需 Node.js 环境)。

    • 合并所有依赖到单个文件
    • 支持 ES 模块和 CommonJS
    • 自动处理 JSON、CSS 等资源
    • 移除未使用的代码(Tree-shaking)
  • 安装:·npm install -g @vercel/ncc

  • 使用教程:

  1. 对单个文件打包:
1
ncc build index.js -o dist

输出目录 dist 中会生成 index.js(合并所有依赖的单个文件)。

  1. 运行打包后的文件:
1
node dist/index.js
  1. 对多个文件打包:
1
ncc build src/index.js src/utils.js -o dist

输出目录 dist 中会生成 index.js 和 utils.js(合并所有依赖的单个文件)。

灵活配置方式

ncc 允许通过两种方式扩展配置:

  1. 命令行参数(简单配置)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 指定入口文件和输出目录
ncc build src/main.js -o dist/out

# 生成 source map(便于调试)
ncc build src/index.js --source-map

# watch 模式(文件变化自动重新打包)
ncc build src/index.js --watch

# 保留注释(默认会移除注释)
ncc build src/index.js --comments

# 外部化依赖(不打包指定模块,运行时仍需安装)
ncc build src/index.js --external express --external mongoose

# 定义环境变量
ncc build src/index.js --define process.env.NODE_ENV=production
  1. 自定义 Webpack 配置文件(复杂配置)
  • 在项目根目录创建 ncc.config.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module.exports = {
// 扩展 Webpack 配置
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// 1. 添加自定义 loader 处理特定文件
config.module.rules.push({
test: /\.csv$/,
use: ["csv-loader"], // 需要先安装 csv-loader: npm i csv-loader
});

// 2. 处理静态资源(如图片)
config.module.rules.push({
test: /\.(png|jpe?g|gif)$/i,
type: "asset/inline", // 内嵌为 base64
// 或输出为文件:type: 'asset/resource', generator: { filename: 'images/[hash][ext]' }
});

// 3. 添加 Webpack 插件
config.plugins.push(
new webpack.BannerPlugin({
banner: "Copyright © 2023 My Project", // 给打包文件添加版权注释
raw: false,
entryOnly: true,
})
);

// 4. 配置别名(简化导入路径)
config.resolve.alias = {
...config.resolve.alias,
"@utils": path.resolve(__dirname, "src/utils"),
};

// 5. 排除特定模块不被打包
config.externals.push("pg-native"); // 类似 --external 命令行参数

return config; // 必须返回修改后的配置
},

// 配置输出目录结构
output: {
// 自定义文件名(默认是 index.js)
filename: "main.js",
// 自定义文件夹(默认是 dist)
path: "build",
// 公共路径(如果部署到 CDN)
publicPath: "/assets/",
},
};
  • 安装依赖
    如果使用了自定义 loader 或插件,需要安装对应的依赖:
1
npm install csv-loader webpack --save-dev
  • 打包
1
ncc build src/index.js
  • 结合 package.json 脚本
1
2
3
4
5
6
7
{
"scripts": {
"build": "ncc build src/index.js",
"build:watch": "ncc build src/index.js --watch",
"build:prod": "ncc build src/index.js --source-map --define process.env.NODE_ENV=production"
}
}

选择建议

  • 简单场景(纯 Node.js 脚本):优先用 pkg 或 nexe。
  • 桌面应用(带 UI):用 electron-packager。
  • 服务器部署(需保留 Node.js 依赖):用 webpack + ncc。