【发布时间】:2021-02-07 08:36:46
【问题描述】:
Webpack 检查函数的使用并删除(作为死代码)“未使用”的函数。但是如果我在 HTML 中使用该函数,如果没有脚本调用它,相同的函数将被删除。
例如,我有script.js:
function doSomething() {
console.log("clicked button");
}
function explicitUsedFunction() {
console.log("Hey, function called!");
}
explicitUsedFunction();
还有index.html:
<html>
<head>
<title>Test</title>
<script src="script.js"></script>
</head>
<body>
<button onclick="doSomething()">Button</button>
</body>
</html>
doSomething函数被onclick按钮事件使用。
这是我的 webpack.config.js:
const path = require('path');
const TerserMinimizer = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
entry: ["./script.js"],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
optimization: {
minimize: true,
minimizer: [
new TerserMinimizer({
terserOptions: {
keep_classnames: true,
keep_fnames: true
}
})
]
}
};
我使用 TerserPlugin 来保留函数名(因为 HTML 不会被修改)。因此,bundle.js 文件将是:
!function explicitUsedFunction(){console.log("Hey, function called!")}();
doSomething 函数被删除,问题是,如何使用 Webpack 将所有声明的函数保留在 bundle.js 中?
关于答案的几点需要理解:
- 上面的例子只是为了便于代码阅读,我不会对按钮使用 addEventListener(因为如果我有大约 20 个不同的按钮(使用该函数)不是一个有用的答案 addEventListener to all buttons)
- 我没有使用 import/export 关键字,因为它只是一个通过 script 标签导入的简单 javascript 文件,使用 import/export 关键字会导致“SyntaxError: Invalid token”
【问题讨论】:
-
最好的方法是不使用旧式的
onXyz-attribute 事件处理程序。改用现代事件处理(addEventListener等),Webpack 会看到该函数被使用。 -
如果我在任何脚本中使用函数,它将被输出到 bundle.js。但是正如我所提到的,如果我有一堆按钮和元素使用该函数,并且我需要管理这些元素是否已加载到 DOM 中,那么使用 addEventListener 是没有用的(我不能将 addEventListener 用于不是加载)。禁用摇树强制我设置 mode='development',这使得文件比正常缩小更大。使用“sideEffects”也不会改变任何东西。
-
在这种情况下,考虑使用event delegation。
标签: javascript html webpack minify