Closed unional closed 2 years ago
Try to add import
with specific imports to ESM version.
By default, webpack/esbuild tree-shake everything from the ESM lib.
It's not related to tree shaking. The weird thing is the output is different just by renaming the folder. Did size-limit
cache build artifacts/result somewhere?
Did size-limit cache build artifacts/result somewhere?
Should not, but esbuild may have some cache (remove node_modules
and install it again to be sure).
I take a look at it. Removing node_modules
doesn't make a difference.
I have created a branch to demo it: https://github.com/unional/tersify/tree/size-limit
Don't have other ideas why it behaves like that.
And I double checked the folder content between esm and tslib are identical.
I cloned repo, called yarn install & yarn build
and checked esm/
and tslib/
content. They are very different.
esm/index.js
:
export * from './tersible.js';
export { tersify } from './tersify.js';
export * from './types.js';
//# sourceMappingURL=index.js.map
tslib/index.js
:
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.tersify = void 0;
__exportStar(require("./tersible.js"), exports);
var tersify_js_1 = require("./tersify.js");
Object.defineProperty(exports, "tersify", { enumerable: true, get: function () { return tersify_js_1.tersify; } });
__exportStar(require("./types.js"), exports);
//# sourceMappingURL=index.js.map
tslib
doesnβt use ESM and tree shaking is not working. This is why you have so different size.
That branch I build it the tslib
extending cjs
instead of esm
. Sorry. You can see they are the same, but the size-limit result is different:
./cjs/index.js
Size limit: 5 kB
Size: 4.26 kB with all dependencies, minified and gzipped
./esm/index.js
Size limit: 5 kB
Size: 2.98 kB with all dependencies, minified and gzipped
./tslib/index.js
Size limit: 50 kB
Size: 39.05 kB with all dependencies, minified and gzipped
// tsconfig.tslib.json
{
"extends": "./tsconfig.cjs.json",
"compilerOptions": {
// "importHelpers": /true,
"outDir": "tslib"
}
}
./cjs/index.js
Size limit: 5 kB
Size: 4.26 kB with all dependencies, minified and gzipped
./esm/index.js
Size limit: 5 kB
Size: 2.98 kB with all dependencies, minified and gzipped
./tslib/index.js
Size limit: 50 kB
Size: 36.82 kB with all dependencies, minified and gzipped
This is the result when tsconfig.tslib.json
is:
{
"extends": "./tsconfig.esm.json",
"compilerOptions": {
// "importHelpers": /true,
"outDir": "tslib"
}
}
So you can see the the size from the two builds are actually different (39.05 vs 36.82),
and they are both different to the same cjs
and esm
folder (4.26, 2.98).
But the folder content is the same
Why I had Object.defineProperty(exports, "__esModule", { value: true });
in build dir?
I think you have a problem in environment. You build system is too complicated. It leads to unexpected results.
I recommend to avoid build step for open source projects (I never build my open source project). It will simplify the process a lot and save you from bugs.
Why I had
Object.defineProperty(exports, "__esModule", { value: true });
in build dir?
That is the output from TypeScript.
The cjs
build is compiling the code into ES5 ("target": "ES5"
) by TypeScript.
I use the Compare Folder
extensions from VSCode to compare and show the two folders are identical:
You can compare the esm
one if you want, which compiles it to "target": "ES2019"
so you don't see those extra stuff.
I just pushed a change to branch so that the tslib
is based off of esm
to make it easier to compare for you.
I recommend to avoid build step for open source projects (I never build my open source project). It will simplify the process a lot and save you from bugs.
It's written in TypeScript so build step is a must. π·
It's written in TypeScript so build step is a must.
Compile only to ESM. Why do you need tslib
and cjs
outputs?
The cjs
is for older NodeJS, browsers and tooling. It will be phase out eventually, but not yet. There are still many problems with ESM only packages (especially in the TypeScript ecosystem).
https://unional.github.io/typescript-guidelines/blog/2022-tsc-esm-fix
Why do you need
tslib
For comparing the build size of including the tslib
package with the importHelpers: true
flag for TypeScript.
It's a TypeScript thing.
browsers and toolings
You do not need it. Bundlers for browsers work with ESM.
older NodeJS
All current (with security updates) versions support ESM.
You do not need it. Bundlers for browsers work with ESM.
Not really, you can see my blog (ts-loader
needs workaround. I'm working on a fix for it).
And jest
still have to do workarounds for ESM modules.
I have figured out what's the problem. It's the browser spec.
./cjs
and ./esm
folder have browser spec specified, but not ./tslib
.
So during build, the ./tslib
one bundles the NodeJS code instead of the browser code, resulting a much larger bundle as it is including acron
.
π π¦
https://github.com/unional/tersify
What's interesting thing is the files being checked are the same.
There is the
tsconfig.tslib.json
:And I double checked the folder content between
esm
andtslib
are identical.I even just swapped the folder names by doing rename, and it reports the same. the
tslib
one is still 36.82 kB, even with the content of theesm
folder.I have also tried keeping only one
size-limit
config. What I have found is that when the folder is notesm
, it reports 36.82 kB... π€· π·