Jean
Jean

Reputation: 21605

why does webpack 4 include the whole file for single named import?

Given the following two files :

//a.js
export const X = /*#__PURE__*/ "X";

const a = function () {
  return "About a!";
};
a.foo = function () {
  return "foo";
};
export default a;

and

//main.js
import { X } from "./a";
import { Y } from "./b";

console.log(X, Y);

I have added

but running webpack -p still includes the whole a.js file in the bundle. Rollup only includes X from a.js (demo)

Removing the a.foo definition "fixes" the issue but is not a solution outside the demo repository. I have read the tree-shaking documentation page multiple times, read [countless issues about tree shaking on the webpack issue tracker, I still cant figure out the following :

You can also checkout the sandbox repository to see the full webpack configuration and the corresponding next.js/react issue (see pages/index.jsx) which led me to this specific issue.

Upvotes: 3

Views: 1841

Answers (2)

Jean
Jean

Reputation: 21605

After raising the issue on webpack's issue tracker ~sokra provided an answer:

Seems like a single compression pass in terser is not enough to compress this code.

The default number of passes is 1 but once raised to 3, a.js is no longer fully inlined. This is how this can be achieved at the cost of a longer build time.

const TerserWebpackPlugin = require("terser-webpack-plugin");

/** @type {import("webpack").Configuration} */
module.exports = {
    optimization: {
        minimizer: [
            new TerserWebpackPlugin({
                terserOptions: {
                    compress: {
                        passes: 3
                    }
                }
            })
        ]
    }
}

Upvotes: 1

noirbizarre
noirbizarre

Reputation: 3429

My guess: export default affects tree shaking. See: https://medium.com/@bluepnume/javascript-tree-shaking-like-a-pro-7bf96e139eb7#43e1

Try not remove the default.

Upvotes: 0

Related Questions