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 :
mode: "production",
optimization: {
usedExports: true,
},
"sideEffects": false,
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:
/***/ 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?
Thanks in advance
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?
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?
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