Colisan
Colisan

Reputation: 253

Webpack5 does not seem to tree-shake unused exports

I set up a small project with the following files

- src/
  - lib/
    - lib1.ts
      - export : func_lib1_1, func_lib1_2
    - lib2.ts
      - export : func_lib2_1, func_lib2_2
  - pkg1/
    - pkg1.ts
      - import & use : func_lib1_1, func_lib2_1
  - pkg2/
    - pkg2.ts
      - import & use : func_lib1_1
  - pkg3/
    - pkg3.ts
      - import & use : func_lib1_1

I configurated the various build/package/optimisation settings as per the official documentation :

webpack.config.js

    mode: "production",
    optimization: {
        usedExports: true,
    },

package.json

    "sideEffects": false,

pkgX.ts

    import { func_lib1_1 } from "../lib/lib1";
    
    console.log("pkgX");
    console.log(func_lib1_1());

But in the resuting bundles I still see the unused function func_lib1_2 and func_lib2_2 being inclued:

pkg1.bundle.js

    /***/ 119:
    /***/ ((__unused_webpack_module, exports) => {
    
    Object.defineProperty(exports, "__esModule", ({ value: true }));
    exports.func_lib1_2 = exports.func_lib1_1 = void 0;
    function func_lib1_1() {
        return "func_lib1_1";
    }
    exports.func_lib1_1 = func_lib1_1;
    function func_lib1_2() {
        return "unused, shouldn't be bundled";
    }
    exports.func_lib1_2 = func_lib1_2;
    
    /***/ }),

Do you know why? What can I do to fix this and get the by-the-book tree-shaking that I seek?

Minimal repro setup available here

Thanks in advance

Update : more infos from optimizationBailout: true

  modules by path ./src/lib/*.ts 666 bytes
    ./src/lib/lib1.ts 333 bytes [built] [code generated]
      Statement (ExpressionStatement) with side effects in source code at 2:0-62
      ModuleConcatenation bailout: Module is not an ECMAScript module
    ./src/lib/lib2.ts 333 bytes [built] [code generated]
      Statement (ExpressionStatement) with side effects in source code at 2:0-62
    ModuleConcatenation bailout: Module is not an ECMAScript module
  ./src/pkg1/pkg1.ts 263 bytes [built] [code generated]
    Statement (ExpressionStatement) with side effects in source code at 2:0-62
    ModuleConcatenation bailout: Module is not an ECMAScript module
  ./src/pkg2/pkg2.ts 182 bytes [built] [code generated]
    Statement (ExpressionStatement) with side effects in source code at 2:0-62
    ModuleConcatenation bailout: Module is not an ECMAScript module
  ./src/pkg3/pkg3.ts 182 bytes [built] [code generated]
    Statement (ExpressionStatement) with side effects in source code at 2:0-62
    ModuleConcatenation bailout: Module is not an ECMAScript module

This is intriguing. Is there something wrong with the way I declare my exports?

Update 2 : it works without ts-loader!

I tried changing all files to .js and removing the whole ts-loader thing. Tree-shaking now work as intented.

The updated question now is : how to make it work with typescript?

Similar questions that may be revelant, but with different context

Upvotes: 3

Views: 8067

Answers (1)

Colisan
Colisan

Reputation: 253

I figured it out myself, auto-answer for the record :

The tsconfig.json was wrong, it wasn't preserving the ES6 module syntaxe so webpack couldn't treeshake properly.

More details on the correct configuration (optionally including Babel too) can be found here

Upvotes: 6

Related Questions