【问题标题】:How to keep all functions after webpack build?webpack构建后如何保留所有功能?
【发布时间】: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


【解决方案1】:

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

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

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

explicitUsedFunction();

/*NEW LINE HERE:*/
window.doSomething = doSomething;

通过这个简单的更改,我告诉 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'
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多