You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+50-10
Original file line number
Diff line number
Diff line change
@@ -8,36 +8,76 @@ Node.js tool for creating a TypeScript dual package.
8
8
9
9
Early stages of development. Inspired by https://github.com/microsoft/TypeScript/issues/49462.
10
10
11
+
## Requirements
12
+
13
+
* Node >= 16.19.0.
14
+
* TypeScript, `npm i typescript`.
15
+
11
16
## Example
12
17
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
+
```
14
23
15
-
**tsconfig.json**
24
+
Then, given a `package.json` that defines `"type": "module"` and a `tsconfig.json` file that looks like the following:
16
25
17
26
```json
18
27
{
19
28
"compilerOptions": {
20
-
"target": "ESNext",
21
29
"module": "NodeNext",
22
30
"moduleResolution": "NodeNext",
23
31
"declaration": true,
32
+
"esModuleInterop": true,
33
+
"outDir": "dist",
24
34
"strict": true,
25
-
"outDir": "dist"
26
35
},
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"
28
45
}
29
46
```
30
47
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:
32
49
33
50
```console
34
-
user@comp ~ $ duel -p tsconfig.json -x .cjs
51
+
user@comp ~ $ npm run build
35
52
```
36
53
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.
38
55
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
+
```
40
78
41
79
## Gotchas
42
80
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`.
0 commit comments