如何用Vite.js将Node.js后端代码打包为单文件?
如何用Vite将Node.js后端代码打包为仅排除核心模块的单文件
要实现仅将Node.js核心模块设为外部依赖,同时把第三方依赖(如Koa)打包进单文件,你需要调整Vite的ssr.noExternal配置,明确指定非核心模块都需要被打包,而非默认将node_modules中的包全部排除。
修改后的Vite构建脚本
import path from 'path'; import { build } from 'vite'; import builtinModules from 'builtin-modules'; async function main() { const result = await build({ mode: 'production', appType: 'custom', root: path.join(process.cwd(), 'backend'), ssr: { format: 'esm', target: 'node', // 仅将Node核心模块设为外部依赖 external: builtinModules, // 除核心模块外,所有模块都打包进文件 noExternal: (id) => !builtinModules.includes(id) }, build: { manifest: false, rollupOptions: { input: 'backend/main.mjs', output: { // 确保输出为单文件 format: 'esm', entryFileNames: 'bundle.js' } }, outDir: '../dist/backend', ssr: true, emptyOutDir: true }, plugins: [], }); } main();
关键配置说明
ssr.external: builtinModules:明确将所有Node.js核心模块标记为外部依赖,不打包进最终文件,直接在运行时从Node环境加载。ssr.noExternal: (id) => !builtinModules.includes(id):通过函数判断,所有非核心模块(包括第三方依赖如Koa)都不被外部化,会被打包进单文件中。- 调整
rollupOptions.output.entryFileNames确保输出文件名固定为bundle.js(原配置中的assetFileNames针对资源文件,此处需用entryFileNames指定入口文件输出名)。
预期输出效果
修改配置后,打包生成的bundle.js会包含Koa的完整代码,仅保留对核心模块path的导入,示例如下:
import path from "path"; // 此处为打包后的Koa完整代码 const Koa = /* ...Koa模块的打包实现... */; async function main() { console.log("Source folder", path.join(__dirname, "src")); const app = new Koa(); app.listen(3e3); } main();
额外提示
如果代码中使用了__dirname,在ESM格式的打包文件中会报错(ESM模块无__dirname变量),可通过以下方式替代:
import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename);
内容的提问来源于stack exchange,提问作者Harshal Patil
相关产品推荐
相关产品推荐

