Skip to content

Commit b16bb2e

Browse files
docs: update readme. (#3)
1 parent dbf5227 commit b16bb2e

File tree

3 files changed

+55
-17
lines changed

3 files changed

+55
-17
lines changed

README.md

+50-10
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,76 @@ Node.js tool for creating a TypeScript dual package.
88

99
Early stages of development. Inspired by https://github.com/microsoft/TypeScript/issues/49462.
1010

11+
## Requirements
12+
13+
* Node >= 16.19.0.
14+
* TypeScript, `npm i typescript`.
15+
1116
## Example
1217

13-
Consider a project that is ESM-first, i.e. `"type": "module"` in package.json, that also wants to create a separate CJS build. It might have a tsconfig.json file that looks like the following.
18+
First, install the package to create the `duel` executable inside your `node_modules/.bin` directory.
19+
20+
```console
21+
user@comp ~ $ npm i @knighted/duel
22+
```
1423

15-
**tsconfig.json**
24+
Then, given a `package.json` that defines `"type": "module"` and a `tsconfig.json` file that looks like the following:
1625

1726
```json
1827
{
1928
"compilerOptions": {
20-
"target": "ESNext",
2129
"module": "NodeNext",
2230
"moduleResolution": "NodeNext",
2331
"declaration": true,
32+
"esModuleInterop": true,
33+
"outDir": "dist",
2434
"strict": true,
25-
"outDir": "dist"
2635
},
27-
"include": ["src/*.ts"]
36+
"include": ["src"]
37+
}
38+
```
39+
40+
You can create a build for the project defined by the above configuration, **and also a separate dual CJS build** by defining the following npm run script in your `package.json`:
41+
42+
```json
43+
"scripts": {
44+
"build": "duel"
2845
}
2946
```
3047

31-
Running the following will use the tsconfig.json defined above and create a separate CJS build in `dist/cjs`.
48+
And then running it:
3249

3350
```console
34-
user@comp ~ $ duel -p tsconfig.json -x .cjs
51+
user@comp ~ $ npm run build
3552
```
3653

37-
Now you can update your `exports` in package.json to match the build output.
54+
If everything worked, you should have an ESM build inside of `dist` and a CJS build inside of `dist/cjs`. Now you can update your `exports` in package.json to match the build output.
3855

39-
It should work similarly for a CJS first project. Except, your tsconfig.json would be slightly different and you'd want to pass `-x .mjs`.
56+
It should work similarly for a CJS first project. Except, your `tsconfig.json` would define `--module` and `--moduleResolution` differently, and you'd want to pass `-x .mjs`.
57+
58+
See the available [options](#options).
59+
60+
61+
## Options
62+
63+
The available options are limited, because you should define most of them inside your project's `tsconfig.json` file.
64+
65+
* `--project, -p` The path to the project's configuration file. Defaults to `tsconfig.json`.
66+
* `--target-extension, -x` The desired target extension which determines the type of dual build. Defaults to `.cjs`.
67+
68+
You can run `duel --help` to get more info. Below is the output of that:
69+
70+
```console
71+
Usage: duel [options]
72+
73+
Options:
74+
--project, -p Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.
75+
--target-extension, -x Sets the file extension for the dual build. [.cjs,.mjs]
76+
--help, -h Print this message.
77+
```
4078

4179
## Gotchas
4280

43-
Unfortunately, TypeScript doesn't really understand dual packages very well. For instance, it will **always** create CJS exports when `--module commonjs` is used, even on files with an `.mts` extension. One reference issue is https://github.com/microsoft/TypeScript/issues/54573.
81+
* Unfortunately, TypeScript doesn't really understand dual packages very well. For instance, it will **always** create CJS exports when `--module commonjs` is used, even on files with an `.mts` extension. One reference issue is https://github.com/microsoft/TypeScript/issues/54573. If you use `.mts` extensions to enforce an ESM module system, this might break in the corresponding dual CJS build.
82+
* If targeting a dual CJS build, and you are using [top level `await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await), you will most likely encounter the compilation error `error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.` during the CJS build. This is because `duel` creates a temporary `tsconfig.json` from your original and overwrites the `--module` and `--moduleResolution` based on the provided `--target-ext`.
83+
* If doing an `import type` across module systems, i.e. from `.mts` into `.cts`, or vice versa, you might encounter the compilation error ``error TS1452: 'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`.``. This is a [known issue](https://github.com/microsoft/TypeScript/issues/49055) and TypeScript currently suggests installing the nightly build, i.e. `npm i typescript@next`.

package-lock.json

+3-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@knighted/duel",
3-
"version": "1.0.0-alpha.1",
3+
"version": "1.0.0-alpha.2",
44
"description": "TypeScript dual packages.",
55
"type": "module",
66
"main": "dist",
@@ -56,8 +56,7 @@
5656
},
5757
"dependencies": {
5858
"@knighted/specifier": "^1.0.0-alpha.5",
59-
"glob": "^10.3.3",
60-
"magic-string": "^0.30.1"
59+
"glob": "^10.3.3"
6160
},
6261
"prettier": {
6362
"arrowParens": "avoid",

0 commit comments

Comments
 (0)