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
"sideEffect": false
to package.json
optimization.usedExports: true
to webpack.config.js
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 :
/*#__PURE__*/
marker on X
not being used ?a.js
? 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.
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
}
}
})
]
}
}