Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack tree shaking still bundles unused exports

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?

like image 415
user3670473 Avatar asked Apr 15 '20 19:04

user3670473


People also ask

Does tree shaking remove unused imports?

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.

Does webpack do tree shaking by default?

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.

How webpack detect the dead code that can help in tree shaking?

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.

Does webpack remove dead code?

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.


1 Answers

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.

like image 95
user3670473 Avatar answered Oct 14 '22 14:10

user3670473