I'm tinkering with the tree shaking example from the webpack document. But it seems that tree shaking doesn't work once I add babel-loader to the mix.
Here is an overview of my project:
index.js:
import { cube } from "./math";
function component() {
const element = document.createElement('pre');
element.innerHTML = [
'Hello webpack!',
'5 cubed is equal to ' + cube(5)
].join('\n\n');
return element;
}
document.body.appendChild(component());
math.js:
export function square(x) {
console.log('square');
return x * x;
}
export function cube(x) {
console.log('cube');
return x * x * x;
}
.babelrc:
{
"presets": [
["env", { "modules": false }],
"react"
],
"plugins": ["react-hot-loader/babel"]
}
package.json:
{
"dependencies": {
"react": "^16.3.1",
"react-dom": "^16.3.1",
"react-hot-loader": "^4.0.1"
},
"name": "react-webpack-starter",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack -p --optimize-minimize"
},
"sideEffects": false,
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14",
"webpack-dev-server": "^3.1.3"
}
}
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'index_bundle.js'
},
mode: 'production',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
As index.js is not consuming the square function, the square function should be pruned out of the bundle. However, when I open up the bundle.js and search for 'square', I can still find the square function and the console log statement. After I comment out the babel-loader specification in webpack config and npm run build again, the "square" word is nowhere to be seen in the generated bundle file.
I did specify modules: false in .babelrc.
Can anyone tell me what could be causing this problem?
Here's the repo for reproduction:
https://github.com/blogrocks/treeshaking-issue.git
My problem finally got resolved. I should have specified "cross-env NODE_ENV=production" when running webpack. And it's not even sufficient to use DefinePlugin to set NODE_ENV to "production" in plugins. It seems babel-loader keys off the "NODE_ENV=production" from the command.
Oh, I finally find that it is react-hot-loader that is keying off NODE_ENV=production from the command!!