webpack构建后如何保留所有功能?

Rod*_*ues 3 html javascript minify webpack

Webpack 检查函数的使用情况并删除(作为死代码)“未使用”的函数。但是,如果我在 HTML 中使用该函数,则如果没有脚本调用该函数,该函数将被删除。

例如,我有 script.js:

function doSomething() {
    console.log("clicked button");
}

function explicitUsedFunction() {
    console.log("Hey, function called!");
}

explicitUsedFunction();
Run Code Online (Sandbox Code Playgroud)

和index.html:

<html>
    <head>
        <title>Test</title>
        <script src="script.js"></script>
    </head>
    <body>
        <button onclick="doSomething()">Button</button>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

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
                }
            })
        ]
    }
};
Run Code Online (Sandbox Code Playgroud)

我使用 TerserPlugin 来保留函数名称(因为 HTML 不会被修改)。因此,bundle.js 文件将是:

!function explicitUsedFunction(){console.log("Hey, function called!")}();
Run Code Online (Sandbox Code Playgroud)

doSomething 函数被删除,问题是,如何使用 Webpack 保留所有声明的函数在bundle.js 中?

关于答案需要理解的一些要点:

  • 上面的示例只是为了方便代码阅读,我不会对按钮使用 addEventListener (因为如果我有大约 20 个不同的按钮(使用该函数),则对所有按钮使用 addEventListener 并不是一个有用的答案)
  • 我没有使用 import/export 关键字,因为只是一个由 script 标记导入的简单 javascript 文件,使用 import/export 关键字会导致“SyntaxError:无效令牌”

Rod*_*ues 10

经过与 webpack 的多次斗争后,我找到了一个简单的解决方案。我需要两件事:将所有函数发送到缩小文件并使事件函数在窗口范围内可访问。我刚刚为我需要的每个功能添加了以下行:

function doSomething() {
    console.log("clicked button");
}

function explicitUsedFunction() {
    console.log("Hey, function called!");
}

explicitUsedFunction();

/*NEW LINE HERE:*/
window.doSomething = doSomething;
Run Code Online (Sandbox Code Playgroud)

通过这个简单的更改,我告诉 webpack 该函数已被使用,我不再需要 Terser (webpack.config.js):

const path = require('path');

module.exports = {
    mode: 'production',
    entry: ["./script.js"],
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
};
Run Code Online (Sandbox Code Playgroud)