@knighted/duel 1.0.0-alpha.0 → 1.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -10
- package/dist/duel.cjs +2 -5
- package/dist/duel.js +5 -7
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
48
|
+
And then running it:
|
|
32
49
|
|
|
33
50
|
```console
|
|
34
|
-
user@comp ~ $
|
|
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
|
|
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`.
|
package/dist/duel.cjs
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.duel = void 0;
|
|
8
8
|
var _nodeProcess = require("node:process");
|
|
9
|
-
var _nodeUrl = require("node:url");
|
|
10
9
|
var _nodePath = require("node:path");
|
|
11
10
|
var _nodeChild_process = require("node:child_process");
|
|
12
11
|
var _promises = require("node:fs/promises");
|
|
@@ -16,10 +15,8 @@ var _glob = require("glob");
|
|
|
16
15
|
var _specifier = require("@knighted/specifier");
|
|
17
16
|
var _init = require("./init.cjs");
|
|
18
17
|
var _util = require("./util.cjs");
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const root = (0, _nodePath.join)(_dirname, '..');
|
|
22
|
-
const tsc = (0, _nodePath.join)(root, 'node_modules', '.bin', 'tsc');
|
|
18
|
+
// TypeScript is defined as a peer dependency.
|
|
19
|
+
const tsc = (0, _nodePath.join)((0, _nodeProcess.cwd)(), 'node_modules', '.bin', 'tsc');
|
|
23
20
|
const runBuild = project => {
|
|
24
21
|
const {
|
|
25
22
|
status,
|
package/dist/duel.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { argv } from 'node:process';
|
|
3
|
-
import {
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
2
|
+
import { argv, cwd } from 'node:process';
|
|
3
|
+
import { join } from 'node:path';
|
|
5
4
|
import { spawnSync } from 'node:child_process';
|
|
6
5
|
import { writeFile, rm } from 'node:fs/promises';
|
|
7
6
|
import { randomBytes } from 'node:crypto';
|
|
@@ -10,10 +9,9 @@ import { glob } from 'glob';
|
|
|
10
9
|
import { specifier } from '@knighted/specifier';
|
|
11
10
|
import { init } from './init.js';
|
|
12
11
|
import { getRealPathAsFileUrl, logError, log } from './util.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const tsc = join(root, 'node_modules', '.bin', 'tsc');
|
|
12
|
+
|
|
13
|
+
// TypeScript is defined as a peer dependency.
|
|
14
|
+
const tsc = join(cwd(), 'node_modules', '.bin', 'tsc');
|
|
17
15
|
const runBuild = project => {
|
|
18
16
|
const {
|
|
19
17
|
status,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/duel",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.2",
|
|
4
4
|
"description": "TypeScript dual packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist",
|
|
@@ -56,8 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@knighted/specifier": "^1.0.0-alpha.5",
|
|
59
|
-
"glob": "^10.3.3"
|
|
60
|
-
"magic-string": "^0.30.1"
|
|
59
|
+
"glob": "^10.3.3"
|
|
61
60
|
},
|
|
62
61
|
"prettier": {
|
|
63
62
|
"arrowParens": "avoid",
|