2

I'm using Webpack for a project (and I'm starting to regret that) and tree shaking is not working.

I created a simple test library which I bundle using Rollup since Webpack cannot generate esm libraries (see here for more info about that: https://github.com/webpack/webpack/issues/2933).

Here is the content of my library (which uses Typescript):

export class Test1 {
    addOne(x: number) {
        console.log('addOne');
        return x + 1;
    }
}

export class Test2 {
    addTwo(x: number) {
        console.log('addTwo');
        return x + 2;
    }
}

Once I bundle it with Rollup, I get this:

var n = function () {
        function n() {}
        return n.prototype.addOne = function (n) {
            return console.log("addOne"), n + 1
        }, n
    }(),
    o = function () {
        function n() {}
        return n.prototype.addTwo = function (n) {
            return console.log("addTwo"), n + 2
        }, n
    }();
export {
    n as Test1, o as Test2
};

Then, I use webpack to bundle my test app that is using this library. Here is the code of the app:

'use strict';

import { Test1 } from './test.esm';

const f = new Test1();
console.log(f.addOne(1));

Once I look at the generated bundle, the Test2 code is tree shaken and does not appear in the bundle.

So far, so good.

If then I add a new function to my Test2 class, like this:

export class Test1 {
    addOne(x: number) {
        console.log('addOne');
        return x + 1;
    }
}

export class Test2 {
    addTwo(x: number) {
        console.log('addTwo');
        return x + 2;
    }

    addThree(x: number) {
        console.log('addThree');
        return x + 3;
    }
}

I get the following output from Rollup:

var o = function () {
        function o() {}
        return o.prototype.addOne = function (o) {
            return console.log("addOne"), o + 1
        }, o
    }(),
    n = function () {
        function o() {}
        return o.prototype.addTwo = function (o) {
            return console.log("addTwo"), o + 2
        }, o.prototype.addThree = function (o) {
            return console.log("addThree"), o + 3
        }, o
    }();
export {
    o as Test1, n as Test2
};

If then I generate my app bundle with webpack and this new library, without changing anything to the code of the app using the lib, the content of Test2 is added to the output. What am I doing wrong here?

I'm using webpack 5.12.3.

My webpack config is:

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');



module.exports = merge(common, {
    mode: 'production',
});
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    resolve: {
        fallback: {
            'fs': false,
        }
    },
    entry: {
        'sample-face': './src/sample-face.js',
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new CleanWebpackPlugin(),
        new CopyPlugin({
            patterns: [
                { from: 'src/index.html', to: path.resolve(__dirname, 'dist') },
                { from: 'src/sample-face.html', to: path.resolve(__dirname, 'dist') },
                { from: 'src/assets', to: path.resolve(__dirname, 'dist/assets') },
            ]
        })
    ]
};
Cyril GC
  • 51
  • 5
  • Probably not what you expected to hear, but: if this is your code, why use webpack? Just use [esbuild](https://esbuild.github.io), it's a million times faster, and nowhere near the clustermuck that webpack configs turn into even for tiny projects. – Mike 'Pomax' Kamermans Mar 13 '21 at 02:05
  • You're probably right. I used Webpack at the beginning of this project thinking it would be easier, and also because I believe Angular (which I use everyday) uses it under the hood. I then learned I can't use Webpack to generate my lib. Bu since I already had everything in place for the rest, I wanted to keep using webpack for generating the app. I'll probably change and use something else. I was going to use Rollup since I use it already for the lib part but I'll check esbuild as well. I'd still like to know why it's not working since webpack claims they support tree shaking. – Cyril GC Mar 13 '21 at 02:18
  • I'd still recommend looking at esbuild first - the fact that you really only need to write out the cli instruction (e.g. as an npm script) without any config is very, very nice. Plus it really is incredibly much faster than webpack or rollup. That said, I'm pretty sure this is yet another example of webpack just being webpack, but maybe someone else will still be able to spot why it's being so terrible. – Mike 'Pomax' Kamermans Mar 14 '21 at 05:48

0 Answers0