@kjn/tsc-dual-build v1.1.0
@kjn/tsc-dual-build
Helps you build ESModules and CommonJS modules with ease.
HOW-TO-USE
Install script using npm
npm i @kjn/tsc-dual-build@latestExecute dual-build
npx tsc-dual-build ./tsconfig.jsonRecommended
Update package.json > scripts > build
"scripts": {
"build": "tsc-dual-build tsconfig.json"
}Now you can simply npm run build to execute a dual build
> tsc-dual-build
2ď¸âŁ tsc-dual-build <tsConfigFile>
đ¨ tsc-build
module: "es2022"
outDir: "./dist/esm"
đ¨ tsc-build
module: "commonjs"
outDir: "./dist/cjs"
âď¸ Exporting package.json
created "dist/esm/package.json"
created "dist/cjs/package.json"
đ tsc-dual-build finishedAbout
Will compile the following project structure
./src
/**.*ts
./package.json
./tsconfig.jsoninto something like this
./dist
/esm
index.js
package.json
/cjs
index.js
package.json
types.d.tsThe idea is that we'll create 2 seperate folders, 1 for ESM and 1 for CJS. In both these folders we'll place a local package.json file that contains the configuration solely for the module syntax of the directory.
e.g. ./dist/esm/package.json contains
- type: "module"
- main: "./dist/esm/index.js"
whereas ./dist/cjs/package.json contains
- type: "commonjs"
- main: "./dist/commonjs/index.js".
Additionally we assert that the root package.json contains the correct configuration to handle both imports and requires by enforcing the exports key to be present and setup correctly.
For tsc-dual-build to work you'd need 2 things
- extend your
tsconfig.jsonwith the required properties - assert
package.jsoncontains the correct entry points forimportandrequire
tsconfig.json
{
"compilesOptions": {
/** placeholder */
},
"include": [
/** placeholder */
],
/** Recommended setup */
"tscDualBuild": {
"esm": {
"module": "es2022",
"outDir": "./dist/esm"
},
"cjs": {
"module": "commonjs",
"outDir": "./dist/cjs"
},
"types": {
"outDir": "./dist"
}
}
}The (recommended) setup above will built
- your
ECMAScriptmodule usinges2022syntax of tsconfig. and will write its output to the folder./dist/esm/\*\* - your
CommonJSmodule usingCommonJSsyntax of tsconfig. and will write its output to the folder./dist/cjs/\*\*
The module and outDir properties are fully customisable aslong as they're valid tsconfig settings.
package.json
For the tsconfig.json above we can configure the root package.json as follows:
{
"name": "<placeholder>",
"version": "<placeholder>",
"dependencies": {
// <placeholder>
},
// ..
// ..
// etc..
// ..
"exports": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
},
"types": "./dist/index.d.ts
}Limitations
This project was build with a specific structure and setup in mind, therefore it might not be the golden hammer you're looking for.
Right now we're only supporting DUAL exports. There is simply no need to support more exports as most modern applications require either CommonJS OR ESM modules. Additionally at the time of writing we don't really care about old systems and many edge-cases that come with.
Another limitation that limits the use of this project would be that this setup assumes that there is only a single entry point for the codebase. IF you need more entry points this project won't work out of the box for you.