What is this
This is a ttypescript transformer:
- Transpile each source files again after it's normal emit. And create commonjs files, next to esm versions, with
.cjs
extension. - append
.js
after every top-levelimport
s (dynamic ones currently not support) - convert
import.meta.url
to"file://" + __filename
in.cjs
files - convert
import ... from "commonjs-library"
toimport x from "commonjs-library"; const ... = x;
in.js
files
Usage
Method A: heft
- Install
@rushstack/heft
, see it's documents - set
"emitCjsExtensionForCommonJS": true,
inconfig/typescript.json
- Add the transformer to your
tsconfig.json
:{ "compilerOptions": { "module": "esnext", // highly recommend "plugins": [ { "transform": "@build-script/typescript-transformer-dual-package" // "cjs": ".cjs", // "mjs": ".js" // "verbose": true } ] } }
Method B: ttypescript
- Install
typescript
,ttypescript
, and this transformernpm install --save-dev typescript ttypescript @build-script/typescript-transformer-dual-package
- Add the transformer to your
tsconfig.json
:{ "compilerOptions": { "module": "esnext", // this is required (maybe lower version, but commonjs/system etc is not valid) // ... other options "plugins": [ { "transform": " @build-script/typescript-transformer-dual-package", // "compilerOptions": { // [optional] // normally you do not need to set this. //... override parent compilerOptions when compile commonjs // some options can not override // }, "verbose": false // [optional] print debug output } ] } }
- Write typescript as you want. But:
-
Do not use any
require
in your code!,await import()
instead (this rule not includingmodule::createRequire
) - Do not add
\.(c|m)?js
at end ofimport
statement. (bad:import "./some-file.js"
)
-
Do not use any
- Compile with
ttsc
, instead oftsc
(package tools likewebpack
also support ttypescript, please refer to their docs)npm install ttypescript ttsc -p path/to/tsconfig.json
- Update your
package.json
like that:{ "type": "module", "main": "lib/api.cjs", "module": "lib/api.js", // maybe "esnext", "browser" etc "bin": { "some-cli-command": "lib/bin.cjs" }, "exports": { ".": { "require": "lib/api.cjs", "import": "lib/api.js" } } }
Related pages:
- TypeScript Transform:
- If someday typescript directlly support transformer from commandline or tsconfig,
ttypescript
can be removed. - Typescript Compiler Api Document
- https://ts-ast-viewer.com/
- ttypescript
- If someday typescript directlly support transformer from commandline or tsconfig,
- RushStack
- Add custom extension:
- TypeScript#27957
- TypeScript#18442
- Initial idea comes from: Zoltu/typescript-transformer-append-js-extension
- Node.JS:
-
exports
field in package.json: Conditional Exports
-
How
-
tsc
/ttsc
run- Load my package
- Create
Program
, setup all transformers, including this one
- When
Program
emit
, for each output file, my transformer run:- Modify all
ImportDeclaration
andExportDeclaration
, add.js
to them - Create another
Program
- it will compile emitted file Again, with new compilerOptions, which "module" is "commonjs"
- add
.cjs
to allImportDeclaration
andExportDeclaration
- Modify all