Publish CJS and ES transpiled files in different versions
See original GitHub issueIs your feature request related to a problem? Please describe.
Each modular package on npm ships with both CJS and ES transpiles files.
$ npm install @aws-sdk/client-s3
$ du -sh node_modules/@aws-sdk/client-s3
6.1M node_modules/@aws-sdk/client-s3
$ du -sh node_modules/@aws-sdk/client-s3/dist-cjs
1.6M node_modules/@aws-sdk/client-s3/dist-cjs
$ du -sh node_modules/@aws-sdk/client-s3/dist-es
1.3M node_modules/@aws-sdk/client-s3/dist-es
$ cat node_modules/@aws-sdk/client-s3/package.json| grep '"main"'
"main": "./dist-cjs/index.js",
$ cat node_modules/@aws-sdk/client-s3/package.json| grep '"module"'
"module": "./dist-es/index.js",
Since dist-cjs
is used in Node.js and dist-es
is consumed by browser, they can be shipped into two different packages/versions.
Describe the solution you’d like
Ship browser and Node.js versions in different package names (say with suffix -node
and -browser
)
This suggestion was followed in preview versions of AWS SDK for JavaScript (v3). For example: @aws-sdk/client-s3-node
It was discontinued primarily because it’s not scalable.
- It generates duplicate code which needs to be maintained in repository.
- Supporting new environment (say ReactNative) would require adding new package per client (say with suffix
-rn
). - Supporting new module module system (say ESM) would require adding new package per client (say
node-esm
)
Ship different dist in prerelease tags
This suggestion includes using prerelease tags for shipping specific versions where reducing npm install size is important. For example:
- Ship all
dist-*
in versionX.Y.Z
- Ship only
dist-node-cjs
in versionX.Y.Z-node-cjs
- Ship only
dist-node-esm
in versionX.Y.Z-node-esm
- Ship only
dist-node-types
in versionX.Y.Z-node-types
The separate tags are not required for browser and react-native environments, as they are expected to use bundlers and are not dependent on npm install size.
In environments where npm install size is not a concern, developers can use X.Y.Z
version as follows:
// package.json
{
"dependencies": {
//...
"@aws-sdk/client-s3": "X.Y.Z",
//...
}
}
In environments where npm install size is a concern (while using ESM on Node.js), developers can use X.Y.Z-node-esm
version as follows:
// package.json
{
"dependencies": {
//...
"@aws-sdk/client-s3": "X.Y.Z-node-esm",
//...
}
}
For developers requiring types for while using prerelease versions, then can just add X.Y.Z-node-esm
in devDependencies as follows:
// package.json
{
"dependencies": {
//...
"@aws-sdk/client-s3": "X.Y.Z-node-esm",
//...
},
"devDependencies": {
//...
"@aws-sdk/client-s3": "X.Y.Z-types",
//...
}
}
The different versions will be managed in the repo by creating custom package.json
files for each prerelease tag, similar to how it’s done in tsconfig. The release script will use custom package.json
when publishing packages on npm.
package.json
: will include all configurations.package.node.cjs.json
: will include configurations and dependencies only for CommonJS.package.node.esm.json
: will include configurations and dependencies only for ESM.package.types.json
: will include configurations and dependencies only for types.
Describe alternatives you’ve considered
Scrapping of dist-*
folders which are not being used in postinstall script.
Additional context
Request proposed earlier in:
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:8 (7 by maintainers)
Revisiting. We only need Node.js specific variant to reduce install size. The browser specific variant is not needed, as most users use bundlers.
Revisiting this idea: looking at semver 2.0 specifications, it would be more helpful to use build metadata instead of prerelease tags.
For example:
dist-*
in versionX.Y.Z
dist-node-cjs
in versionX.Y.Z+node-cjs
dist-node-esm
in versionX.Y.Z+node-esm
dist-node-types
in versionX.Y.Z+node-types