admin管理员组

文章数量:1287786

Webpack checks the usage of functions and remove (as dead code) the "unused" functions. But if I'm using the function inside HTML, the same function will be removed if none scripts calls it.

For example, I have the script.js:

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

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

explicitUsedFunction();

And index.html:

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

doSomething function is used by onclick button event.

here is my 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
                }
            })
        ]
    }
};

I'm using TerserPlugin to keep function name (because HTML will not be modified). So, the bundle.js file will be:

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

doSomething function was removed, the question is, how can I keep all declared functions in bundle.js using Webpack?

Some points about answer need be understood:

  • the example above is just for easy code reading, I don't will use addEventListener to the button (because if I have about 20 different buttons (using the function) is not a helpful answer addEventListener to all buttons)
  • I'm not using import/export keyword because is just a simple javascript file imported by script tag, the use of import/export keyword causes "SyntaxError: Invalid token"

Webpack checks the usage of functions and remove (as dead code) the "unused" functions. But if I'm using the function inside HTML, the same function will be removed if none scripts calls it.

For example, I have the script.js:

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

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

explicitUsedFunction();

And index.html:

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

doSomething function is used by onclick button event.

here is my 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
                }
            })
        ]
    }
};

I'm using TerserPlugin to keep function name (because HTML will not be modified). So, the bundle.js file will be:

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

doSomething function was removed, the question is, how can I keep all declared functions in bundle.js using Webpack?

Some points about answer need be understood:

  • the example above is just for easy code reading, I don't will use addEventListener to the button (because if I have about 20 different buttons (using the function) is not a helpful answer addEventListener to all buttons)
  • I'm not using import/export keyword because is just a simple javascript file imported by script tag, the use of import/export keyword causes "SyntaxError: Invalid token"
Share Improve this question asked Oct 24, 2020 at 14:10 Rodrigo G RodriguesRodrigo G Rodrigues 4611 gold badge5 silver badges19 bronze badges 4
  • 1 The best way to do this is to not use old-style onXyz-attribute event handlers. Use modern event handling instead (addEventListener, etc.), and Webpack will see that the function is used. – T.J. Crowder Commented Oct 24, 2020 at 14:16
  • See also Disable tree shaking in Webpack 4 – T.J. Crowder Commented Oct 24, 2020 at 14:18
  • If I use a function inside any scripts, it will be output to bundle.js. But as I mentioned, the use of addEventListener is not useful if I have a bunch of buttons and elements that uses the function and I need to manage if this elements were loaded into DOM (I can't use addEventListener to a node that is not loaded). The disable tree shaking forces me to set mode='development', which makes files bigger than normal minification. Using "sideEffects" does not change anything too. – Rodrigo G Rodrigues Commented Oct 24, 2020 at 14:51
  • In that situation, consider using event delegation. – T.J. Crowder Commented Oct 24, 2020 at 14:53
Add a ment  | 

1 Answer 1

Reset to default 13

After a lot of fights with webpack, I found a simple solution. I need 2 things: send all function to minified file and make event functions acessible on window's scope. I just added the following line for every function I need:

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

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

explicitUsedFunction();

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

with this simple change I tell to webpack that the function was used and I dont need Terser anymore (webpack.config.js):

const path = require('path');

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

本文标签: javascriptHow to keep all functions after webpack buildStack Overflow