Vite项目本地构建正常但CI构建失败:Buffer相关问题
问题现象
- 本地执行
npm run build完全正常,CI环境下执行相同命令却报错 - CI报错信息:
Error: "Buffer" is not exported by "__vite-browser-external", imported by "src/index.html?html-proxy&index=0.js".
file: /home/runner/work/explorer/explorer/src/index.html?html-proxy&index=0.js:2:13
1:
2: import { Buffer } from "buffer";
^
3: window.Buffer = Buffer;
Error: error during build:
RollupError: "Buffer" is not exported by "__vite-browser-external", imported by "src/index.html?html-proxy&index=0.js".
背景说明
那段引发错误的import { Buffer } from "buffer"; window.Buffer = Buffer;代码,是为了解决本地vite serve时的报错添加的。移除这段代码后,CI构建就能正常运行,但本地开发又会出现原来的报错。
当前Vite配置
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import viteTsconfigPaths from 'vite-tsconfig-paths' import svgrPlugin from 'vite-plugin-svgr' import { createHtmlPlugin } from 'vite-plugin-html' import EnvironmentPlugin from 'vite-plugin-environment' import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill' export default defineConfig({ root: './src', envDir: '..', build: { // relative to the root outDir: '../build', }, // relative to the root publicDir: '../public', server: { open: true, port: 3000, proxy: { '/api': 'http://localhost:5001', }, }, define: { 'process.env': {} }, resolve: { alias: { events: 'events', stream: 'stream-browserify', zlib: 'browserify-zlib', 'util/': 'util', }, }, optimizeDeps: { esbuildOptions: { define: { // Node.js global to browser globalThis global: 'globalThis', }, // Enable esbuild polyfill plugins plugins: [ NodeGlobalsPolyfillPlugin({ buffer: true, }), ], }, }, plugins: [ svgrPlugin({ exportAsDefault: true, }), react({ // Use React plugin in all *.jsx and *.tsx files include: '**/*.{jsx,tsx}', }), createHtmlPlugin({ inject: { data: { VITE_GA_ID: process.env.VITE_GA_ID, VITE_ZENDESK_KEY: process.env.VITE_ZENDESK_KEY, }, }, }), EnvironmentPlugin('all'), NodeGlobalsPolyfillPlugin({ buffer: true, process: true, }), viteTsconfigPaths(), ], test: { globals: true, setupFiles: 'src/setupTests.js', }, })
使用命令
- 构建命令:
DISABLE_NEW_JSX_TRANSFORM=true vite build --emptyOutDir - 启动命令:
DISABLE_NEW_JSX_TRANSFORM=true vite serve
解决方案
核心原因
Vite在开发模式(vite serve)和生产构建模式下对Node.js全局变量的处理逻辑不一样:
- 开发模式下,
NodeGlobalsPolyfillPlugin会自动polyfill Buffer,但可能存在全局变量挂载不及时的情况,所以你添加了手动导入的代码 - 生产构建时,Vite会把
buffer标记为浏览器外部依赖(__vite-browser-external),但这个外部模块并没有导出Buffer,导致Rollup抛出错误
修复方案
方案1:仅在开发环境执行Buffer挂载代码
把手动导入的代码改成只在开发环境运行:
if (import.meta.env.DEV) { import('buffer').then(({ Buffer }) => { window.Buffer = Buffer; }); }
这样既解决了本地开发的报错问题,又不会干扰CI的生产构建。
方案2:优化Vite配置,统一处理Buffer
- 先安装
buffer包:
npm install buffer --save
- 修改Vite配置中的
resolve.alias,把buffer指向实际安装的包:
resolve: { alias: { // ... 保留其他原有别名 buffer: 'buffer', }, }
- 移除手动导入Buffer的代码,因为配置中的
NodeGlobalsPolyfillPlugin已经会自动处理全局Buffer的polyfill。
调整后,开发和生产环境都能正常处理Buffer,不用再写额外的手动导入代码。
内容的提问来源于stack exchange,提问作者mvadari

