Webpack 5编译生成空Bundle问题求助
问题解决:Webpack 5生产环境编译后Bundle为空
问题描述
使用Webpack 5编译common.js,生产环境输出的bundle仅为!function(){"use strict"}();,完全是空的。怀疑是Tree Shaking导致,但手动调用函数后问题依旧。
问题原因
- Tree Shaking生效:生产环境下Webpack默认开启Tree Shaking,你的代码使用ES模块导出,但这些导出的函数既没有在模块内部被调用,也没有暴露到全局环境,Webpack判定它们是未使用代码,直接移除。
- 不必要的配置干扰:
output.asyncChunks: true是针对异步加载chunk的配置,同步入口场景下这个配置会干扰Webpack对入口chunk的处理逻辑。
修复方案
方案1:将函数挂载到全局window(适合手动引入HTML的场景)
修改common.js,把导出的函数挂载到window对象上,让Webpack识别到这是一个被使用的副作用:
import './common.scss' import './Admin/admin.scss' const debounce = (fn, time = 700) => { let timeout; return function () { const functionCall = () => fn.apply(this, arguments); clearTimeout(timeout); timeout = setTimeout(functionCall, time); } } function IsJson(str) { try { JSON.parse(str); } catch (e) { return false; } return true; } function replaceNbsps(str) { var re = new RegExp(' ?', "g"); return str.replace(re, " "); } function replaceNs(str) { var re = new RegExp('\\n?', "g"); return str.replace(re, ""); } function replaceTs(str) { var re = new RegExp('\\t?', "g"); return str.replace(re, ""); } function replaceSpace(str) { var re = new RegExp('\s', "g"); return str.replace(re, ""); } function replaceBackSpace(str) { return str.trim(); } function trimStr(str) { str = replaceNbsps(str) str = replaceNs(str) str = replaceTs(str) str = replaceSpace(str) str = replaceBackSpace(str) return str } // 挂载到全局window,供外部HTML调用 window.utils = { trimStr, debounce, IsJson } // 保留ES导出(可选,若同时用于模块导入场景) export {trimStr,debounce,IsJson}
方案2:修改Webpack配置(更规范的全局暴露方式)
调整Webpack配置,移除干扰项并配置library让入口模块的导出自动成为全局变量:
const src = path.resolve(__dirname, 'public/src') const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const webpack = require("webpack"); require('dotenv').config().parsed; const env = process.env const config = { target: ["web", "es5"], entry: { common: path.resolve(src, 'common.js'), }, output: { path: path.resolve(__dirname, "public/dist"), filename: '[name].js', // 移除不必要的asyncChunks配置 // asyncChunks: true, clean: true, // 配置library,让导出内容以全局变量形式暴露 library: { name: 'utils', type: 'window' } }, devServer: { allowedHosts: "all", host: "localhost", port: 4000, hot: true, watchFiles: { paths: ['public/src/**/*.*'], }, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization" } }, plugins: [ new MiniCssExtractPlugin(), new webpack.DefinePlugin({ 'process.env.SU_EMAIL': JSON.stringify(env.SU_EMAIL) }), ], module: { rules: [ { test: /\.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', } }, { test: /\.(?:ico|gif|png|jpg|jpeg|svg|woff|woff2|eot|ttf|otf)$/i, type: 'asset/resource', }, { test: /\.(sa|sc|c)ss$/, use: [ { loader: MiniCssExtractPlugin.loader, options: {}, }, 'css-loader', 'sass-loader', ] }, ] }, }; module.exports = (env, argv) => { console.log('mode:', argv.mode) if (argv.mode ==='production') { config.devtool = "nosources-source-map" } else { config.devtool = "source-map" } return config; };
可选:强制关闭Tree Shaking(不推荐)
如果以上方案不适用,可以临时关闭Tree Shaking,但会导致代码体积增大,仅作为应急方案:
在Webpack配置的config对象中添加:
optimization: { usedExports: false, // 若同时不想压缩代码,可开启下面一行 // minimize: false }
内容的提问来源于stack exchange,提问作者Виталий Вороник
相关产品推荐
相关产品推荐

