I am trying to test out Webpack's tree shaking feature, but it does not appear to be working.
Here are my files:
index.ts
import { good } from './exports';
console.log(good);
exports.ts
export const good = 'good';
export const secret = 'iamasecret';
tsconfig.json
{}
webpack.config.ts
import { Configuration } from 'webpack';
import * as TerserPlugin from "terser-webpack-plugin";
const config: Configuration = {
mode: 'production',
entry: './index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ]
},
optimization: {
usedExports: true,
minimizer: [new TerserPlugin()],
}
}
export default config;
package.json
{
"name": "webpacktest",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/terser-webpack-plugin": "^2.2.0",
"@types/webpack": "^4.41.11",
"terser-webpack-plugin": "^2.3.5",
"ts-loader": "^7.0.0",
"ts-node": "^8.8.2",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
},
"sideEffects": false
}
When I run npx webpack
it bundles the files into dist/main.js
. When I open that file, the secret string is in there despite it being an unused export. Is there a way that I can stop it from being included in the final bundle?
Tree shaking, also known as dead code elimination, is the practice of removing unused code in your production build. It's important to ship as little code to your end-users as possible.
Basic Webpack ConfigurationWebpack only does tree shaking when doing minification, which will only occur in production model. Second, you must set the optimization option “usedExports” to true. This means that Webpack will identify any code it thinks isn't being used and mark it during the initial bundling step.
It relies on the import and export statements to detect if code modules are exported and imported for use between JavaScript files. In modern JavaScript applications, we use module bundlers (e.g., webpack or Rollup) to automatically remove dead code when bundling multiple JavaScript files into single files.
While webpack will automatically attempt to remove unused code in the bundle it produces (learn more about tree-shaking here), there is a handy plugin to help us detect unused files and exports in our code in the process of writing it — webpack-deadcode-plugin.
Ok, so I figured it out. I needed to install the packages @babel/core
, @babel/preset-env
, and babel-loader
as dev-dependencies, and change my Webpack config rule for handling TypeScript files to:
{
test: /\.tsx?$/,
use: ['babel-loader','ts-loader'],
exclude: /node_modules/,
},
Next, I created a .babelrc
file with the following content:
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
Finally, I changed/added the following lines to my tsconfig.json
under compilerOptions
:
"module": "es6",
"moduleResolution": "node",
Using babel-loader
, setting the .babelrc
config, and using "module": "es6"
, allowed for my TypeScript code to be tree-shaken. "moduleResolution": "node"
fixed an issue where I was getting errors that certain modules could not be resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With