如何构建无需node_modules的生产级NestJS应用
如何打包NestJS应用以在生产环境中无需node_modules?
方案1:使用NestJS内置的Webpack打包
NestJS原生支持Webpack打包,可将所有依赖(包括第三方包)打包进单个文件,彻底摆脱对node_modules的依赖。
步骤:
- 在项目根目录创建
webpack.config.js:
const webpack = require('webpack'); const path = require('path'); const nodeExternals = require('webpack-node-externals'); module.exports = { entry: './src/main.ts', target: 'node', externals: [nodeExternals({ allowlist: ['webpack/hot/poll?100'] })], module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, output: { path: path.join(__dirname, 'dist'), filename: 'main.js', }, };
- 修改
package.json中的构建脚本:
{ "scripts": { "build:prod": "webpack --mode production" } }
- 安装所需开发依赖:
npm install --save-dev webpack webpack-cli ts-loader webpack-node-externals
- Docker多阶段构建示例:
# 构建阶段 FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build:prod # 运行阶段(仅需Node环境,无node_modules) FROM node:18-alpine WORKDIR /app COPY --from=builder /app/dist/main.js ./ CMD ["node", "main.js"]
方案2:使用ESBuild快速打包
ESBuild比Webpack构建速度快数倍,打包体积更小,适合NestJS这类后端应用场景。
步骤:
- 安装ESBuild依赖:
npm install --save-dev esbuild
- 创建
esbuild.config.js:
const { build } = require('esbuild'); build({ entryPoints: ['src/main.ts'], bundle: true, platform: 'node', target: 'node18', outfile: 'dist/main.js', external: [], // 留空则打包所有依赖,需排除特定包可在此添加 }).catch(() => process.exit(1));
- 修改
package.json脚本:
{ "scripts": { "build:prod": "node esbuild.config.js" } }
- Docker构建逻辑同方案1,仅需复制打包后的
main.js即可。
方案3:使用pkg打包为可执行文件
pkg工具可将Node.js应用连同Node.js runtime一起打包成单个可执行文件,无需在容器中安装Node环境,彻底摆脱node_modules和Node依赖。
步骤:
- 安装pkg:
npm install --save-dev pkg
- 修改
package.json添加配置和脚本:
{ "pkg": { "scripts": "dist/**/*.js", "assets": "dist/**/*.json", "targets": ["node18-alpine-x64"] }, "scripts": { "build:prod": "nest build && pkg . --out-path=dist" } }
- Docker部署示例:
FROM alpine:latest WORKDIR /app COPY --from=builder /app/dist/your-app-name ./ RUN chmod +x your-app-name CMD ["./your-app-name"]
注意事项
- 若项目使用了原生模块(如
bcrypt、sharp),需确保打包工具适配对应平台,或在pkg中指定匹配的target,避免运行时错误。 - 存在动态
require的代码,需额外配置打包工具以确保依赖被正确识别打包。
内容的提问来源于stack exchange,提问作者Vikrant Banwal
相关产品推荐
相关产品推荐

