@knighted/duel 1.0.0-rc.3 → 1.0.0-rc.4
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 +4 -6
- package/dist/duel.cjs +7 -2
- package/dist/duel.js +7 -2
- package/dist/init.cjs +1 -2
- package/dist/init.js +1 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -11,12 +11,10 @@ Node.js tool for building a TypeScript dual package.
|
|
|
11
11
|
* Bidirectional ESM ↔️ CJS dual builds inferred from the package.json `type`.
|
|
12
12
|
* Correctly preserves module systems for `.mts` and `.cts` file extensions.
|
|
13
13
|
* Use only one package.json and tsconfig.json.
|
|
14
|
-
* Run builds in parallel.
|
|
15
14
|
|
|
16
15
|
## Requirements
|
|
17
16
|
|
|
18
17
|
* Node >= 16.19.0.
|
|
19
|
-
* A tsconfig.json with `outDir` defined.
|
|
20
18
|
|
|
21
19
|
## Example
|
|
22
20
|
|
|
@@ -72,7 +70,7 @@ Assuming an `outDir` of `dist`, running the above will create `dist/esm` and `di
|
|
|
72
70
|
|
|
73
71
|
### Parallel builds
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
This is experimental, as your mileage may vary based on the size of your `node_modules` directory.
|
|
76
74
|
|
|
77
75
|
```json
|
|
78
76
|
"scripts": {
|
|
@@ -80,7 +78,7 @@ For a slightly faster build, you can run them in parallel. This is experimental,
|
|
|
80
78
|
}
|
|
81
79
|
```
|
|
82
80
|
|
|
83
|
-
You _might_
|
|
81
|
+
You _might_ reduce your build times, but only if your project has minimal dependencies. This requires first copying your project to a parent directory of `--project` if it exists as a writable folder. Common [gitignored directories for Node.js projects](https://github.com/github/gitignore/blob/main/Node.gitignore) are not copied, with the exception of `node_modules`. See the [notes](#notes) as to why this can't be improved much further. In most cases, you're better off with serial builds.
|
|
84
82
|
|
|
85
83
|
## Options
|
|
86
84
|
|
|
@@ -89,7 +87,7 @@ The available options are limited, because you should define most of them inside
|
|
|
89
87
|
* `--project, -p` The path to the project's configuration file. Defaults to `tsconfig.json`.
|
|
90
88
|
* `--pkg-dir, -k` The directory to start looking for a package.json file. Defaults to the cwd.
|
|
91
89
|
* `--dirs, -d` Outputs both builds to directories inside of `outDir`. Defalts to `false`.
|
|
92
|
-
* `--parallel, -l` Run the builds in parallel.
|
|
90
|
+
* `--parallel, -l` Run the builds in parallel. Defaults to `false`.
|
|
93
91
|
|
|
94
92
|
You can run `duel --help` to get the same info. Below is the output of that:
|
|
95
93
|
|
|
@@ -118,5 +116,5 @@ These are definitely edge cases, and would only really come up if your project m
|
|
|
118
116
|
|
|
119
117
|
## Notes
|
|
120
118
|
|
|
121
|
-
As far as I can tell, `duel` is one (if not the only) way to get a correct dual package build using only `tsc` while using only **one package.json** file and **one tsconfig.json** file, _and also_ preserving module system by file extension. The Microsoft backed TypeScript team [keep](https://github.com/microsoft/TypeScript/issues/54593) [talking](https://github.com/microsoft/TypeScript/pull/54546) about dual build support, but their philosophy is mainly one of self
|
|
119
|
+
As far as I can tell, `duel` is one (if not the only) way to get a correct dual package build using only `tsc` while using only **one package.json** file and **one tsconfig.json** file, _and also_ preserving module system by file extension. The Microsoft backed TypeScript team [keep](https://github.com/microsoft/TypeScript/issues/54593) [talking](https://github.com/microsoft/TypeScript/pull/54546) about dual build support, but their philosophy is mainly one of self-preservation, rather than collaboration. For instance, they continue to [refuse to rewrite specifiers](https://github.com/microsoft/TypeScript/issues/16577). The downside of their decisions, and the fact that `npm` does not support using alternative names for the package.json file, is that `duel` must copy your project
|
|
122
120
|
directory before attempting to run the builds in parallel.
|
package/dist/duel.cjs
CHANGED
|
@@ -49,6 +49,7 @@ const duel = async args => {
|
|
|
49
49
|
} = ctx;
|
|
50
50
|
const pkgDir = (0, _nodePath.dirname)(pkg.path);
|
|
51
51
|
const outDir = tsconfig.compilerOptions?.outDir ?? 'dist';
|
|
52
|
+
const absoluteOutDir = (0, _nodePath.resolve)(projectDir, outDir);
|
|
52
53
|
const originalType = pkg.packageJson.type ?? 'commonjs';
|
|
53
54
|
const isCjsBuild = originalType !== 'commonjs';
|
|
54
55
|
const targetExt = isCjsBuild ? '.cjs' : '.mjs';
|
|
@@ -91,6 +92,10 @@ const duel = async args => {
|
|
|
91
92
|
const logSuccess = start => {
|
|
92
93
|
(0, _util.log)(`Successfully created a dual ${isCjsBuild ? 'CJS' : 'ESM'} build in ${Math.round(_nodePerf_hooks.performance.now() - start)}ms.`);
|
|
93
94
|
};
|
|
95
|
+
await (0, _promises.rm)(absoluteOutDir, {
|
|
96
|
+
force: true,
|
|
97
|
+
recursive: true
|
|
98
|
+
});
|
|
94
99
|
if (parallel) {
|
|
95
100
|
const paraName = `_${hex}_`;
|
|
96
101
|
const paraParent = (0, _nodePath.join)(projectDir, '..');
|
|
@@ -111,6 +116,7 @@ const duel = async args => {
|
|
|
111
116
|
return;
|
|
112
117
|
}
|
|
113
118
|
(0, _util.log)('Preparing parallel build...');
|
|
119
|
+
const prepStart = _nodePerf_hooks.performance.now();
|
|
114
120
|
await (0, _promises.cp)(projectDir, paraTempDir, {
|
|
115
121
|
recursive: true,
|
|
116
122
|
/**
|
|
@@ -128,6 +134,7 @@ const duel = async args => {
|
|
|
128
134
|
await (0, _promises.writeFile)((0, _nodePath.join)(paraTempDir, 'package.json'), JSON.stringify({
|
|
129
135
|
type: isCjsBuild ? 'commonjs' : 'module'
|
|
130
136
|
}));
|
|
137
|
+
(0, _util.log)(`Prepared in ${Math.round(_nodePerf_hooks.performance.now() - prepStart)}ms.`);
|
|
131
138
|
(0, _util.log)('Starting parallel dual builds...');
|
|
132
139
|
let success = false;
|
|
133
140
|
const startTime = _nodePerf_hooks.performance.now();
|
|
@@ -140,7 +147,6 @@ const duel = async args => {
|
|
|
140
147
|
(0, _util.logError)(message);
|
|
141
148
|
}
|
|
142
149
|
if (success) {
|
|
143
|
-
const absoluteOutDir = (0, _nodePath.resolve)(projectDir, outDir);
|
|
144
150
|
const absoluteDualOutDir = (0, _nodePath.join)(paraTempDir, dualOutDir);
|
|
145
151
|
const filenames = await (0, _glob.glob)(`${absoluteDualOutDir}/**/*{.js,.d.ts}`, {
|
|
146
152
|
ignore: 'node_modules/**'
|
|
@@ -169,7 +175,6 @@ const duel = async args => {
|
|
|
169
175
|
if (success) {
|
|
170
176
|
const dualConfigPath = (0, _nodePath.join)(projectDir, `tsconfig.${hex}.json`);
|
|
171
177
|
const dualOutDir = isCjsBuild ? (0, _nodePath.join)(outDir, 'cjs') : (0, _nodePath.join)(outDir, 'esm');
|
|
172
|
-
// Using structuredClone() would require node >= 17.0.0
|
|
173
178
|
const tsconfigDual = getOverrideTsConfig(dualOutDir);
|
|
174
179
|
const pkgRename = 'package.json.bak';
|
|
175
180
|
|
package/dist/duel.js
CHANGED
|
@@ -43,6 +43,7 @@ const duel = async args => {
|
|
|
43
43
|
} = ctx;
|
|
44
44
|
const pkgDir = dirname(pkg.path);
|
|
45
45
|
const outDir = tsconfig.compilerOptions?.outDir ?? 'dist';
|
|
46
|
+
const absoluteOutDir = resolve(projectDir, outDir);
|
|
46
47
|
const originalType = pkg.packageJson.type ?? 'commonjs';
|
|
47
48
|
const isCjsBuild = originalType !== 'commonjs';
|
|
48
49
|
const targetExt = isCjsBuild ? '.cjs' : '.mjs';
|
|
@@ -85,6 +86,10 @@ const duel = async args => {
|
|
|
85
86
|
const logSuccess = start => {
|
|
86
87
|
log(`Successfully created a dual ${isCjsBuild ? 'CJS' : 'ESM'} build in ${Math.round(performance.now() - start)}ms.`);
|
|
87
88
|
};
|
|
89
|
+
await rm(absoluteOutDir, {
|
|
90
|
+
force: true,
|
|
91
|
+
recursive: true
|
|
92
|
+
});
|
|
88
93
|
if (parallel) {
|
|
89
94
|
const paraName = `_${hex}_`;
|
|
90
95
|
const paraParent = join(projectDir, '..');
|
|
@@ -105,6 +110,7 @@ const duel = async args => {
|
|
|
105
110
|
return;
|
|
106
111
|
}
|
|
107
112
|
log('Preparing parallel build...');
|
|
113
|
+
const prepStart = performance.now();
|
|
108
114
|
await cp(projectDir, paraTempDir, {
|
|
109
115
|
recursive: true,
|
|
110
116
|
/**
|
|
@@ -122,6 +128,7 @@ const duel = async args => {
|
|
|
122
128
|
await writeFile(join(paraTempDir, 'package.json'), JSON.stringify({
|
|
123
129
|
type: isCjsBuild ? 'commonjs' : 'module'
|
|
124
130
|
}));
|
|
131
|
+
log(`Prepared in ${Math.round(performance.now() - prepStart)}ms.`);
|
|
125
132
|
log('Starting parallel dual builds...');
|
|
126
133
|
let success = false;
|
|
127
134
|
const startTime = performance.now();
|
|
@@ -134,7 +141,6 @@ const duel = async args => {
|
|
|
134
141
|
logError(message);
|
|
135
142
|
}
|
|
136
143
|
if (success) {
|
|
137
|
-
const absoluteOutDir = resolve(projectDir, outDir);
|
|
138
144
|
const absoluteDualOutDir = join(paraTempDir, dualOutDir);
|
|
139
145
|
const filenames = await glob(`${absoluteDualOutDir}/**/*{.js,.d.ts}`, {
|
|
140
146
|
ignore: 'node_modules/**'
|
|
@@ -163,7 +169,6 @@ const duel = async args => {
|
|
|
163
169
|
if (success) {
|
|
164
170
|
const dualConfigPath = join(projectDir, `tsconfig.${hex}.json`);
|
|
165
171
|
const dualOutDir = isCjsBuild ? join(outDir, 'cjs') : join(outDir, 'esm');
|
|
166
|
-
// Using structuredClone() would require node >= 17.0.0
|
|
167
172
|
const tsconfigDual = getOverrideTsConfig(dualOutDir);
|
|
168
173
|
const pkgRename = 'package.json.bak';
|
|
169
174
|
|
package/dist/init.cjs
CHANGED
|
@@ -109,8 +109,7 @@ const init = async args => {
|
|
|
109
109
|
return false;
|
|
110
110
|
}
|
|
111
111
|
if (!tsconfig.compilerOptions?.outDir) {
|
|
112
|
-
(0, _util.
|
|
113
|
-
return false;
|
|
112
|
+
(0, _util.log)('No `outDir` defined in tsconfig.json. Build output will be in "dist".');
|
|
114
113
|
}
|
|
115
114
|
const projectDir = (0, _nodePath.dirname)(configPath);
|
|
116
115
|
return {
|
package/dist/init.js
CHANGED
|
@@ -103,8 +103,7 @@ const init = async args => {
|
|
|
103
103
|
return false;
|
|
104
104
|
}
|
|
105
105
|
if (!tsconfig.compilerOptions?.outDir) {
|
|
106
|
-
|
|
107
|
-
return false;
|
|
106
|
+
log('No `outDir` defined in tsconfig.json. Build output will be in "dist".');
|
|
108
107
|
}
|
|
109
108
|
const projectDir = dirname(configPath);
|
|
110
109
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/duel",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.4",
|
|
4
4
|
"description": "TypeScript dual packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"tsc",
|
|
29
29
|
"typescript",
|
|
30
30
|
"dual package",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"cts",
|
|
32
|
+
"mts"
|
|
33
33
|
],
|
|
34
34
|
"files": [
|
|
35
35
|
"dist"
|