@knighted/duel 2.0.0-rc.0 → 2.0.0-rc.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 +24 -4
- package/dist/cjs/duel.cjs +28 -18
- package/dist/cjs/init.cjs +8 -1
- package/dist/cjs/init.d.cts +2 -1
- package/dist/cjs/util.cjs +6 -2
- package/dist/esm/duel.js +29 -19
- package/dist/esm/init.d.ts +2 -1
- package/dist/esm/init.js +8 -1
- package/dist/esm/util.js +7 -3
- package/package.json +16 -11
package/README.md
CHANGED
|
@@ -10,8 +10,10 @@ Tool for building a Node.js [dual package](https://nodejs.org/api/packages.html#
|
|
|
10
10
|
|
|
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
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- No extra configuration files needed, uses `package.json` and `tsconfig.json` files.
|
|
14
|
+
- Transforms the [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs).
|
|
15
|
+
- Works with monorepos.
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
## Requirements
|
|
17
19
|
|
|
@@ -68,12 +70,27 @@ If you prefer to have both builds in directories inside of your defined `outDir`
|
|
|
68
70
|
|
|
69
71
|
Assuming an `outDir` of `dist`, running the above will create `dist/esm` and `dist/cjs` directories.
|
|
70
72
|
|
|
73
|
+
### Module transforms
|
|
74
|
+
|
|
75
|
+
TypeScript will throw compiler errors when using `import.meta` globals while targeting a CommonJS dual build, but _will not_ throw compiler errors when the inverse is true, i.e. using CommonJS globals (`__filename`, `__dirname`, etc.) while targeting an ES module dual build. There is an [open issue](https://github.com/microsoft/TypeScript/issues/58658) regarding this unexpected behavior. You can use the `--modules` option to have the [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs) transformed by `duel` prior to running compilation with `tsc` so that there are no compilation or runtime errors.
|
|
76
|
+
|
|
77
|
+
Note, there is a slight performance penalty since your project needs to be copied first to run the transforms before compiling with `tsc`.
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "duel --modules"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This feature is still a work in progress regarding transforming `exports` when targeting an ES module build (relies on [`@knighted/module`](https://github.com/knightedcodemonkey/module)).
|
|
86
|
+
|
|
71
87
|
## Options
|
|
72
88
|
|
|
73
89
|
The available options are limited, because you should define most of them inside your project's `tsconfig.json` file.
|
|
74
90
|
|
|
75
91
|
- `--project, -p` The path to the project's configuration file. Defaults to `tsconfig.json`.
|
|
76
92
|
- `--pkg-dir, -k` The directory to start looking for a package.json file. Defaults to the cwd.
|
|
93
|
+
- `--modules, -m` Transform module globals for dual build target. Defaults to false.
|
|
77
94
|
- `--dirs, -d` Outputs both builds to directories inside of `outDir`. Defaults to `false`.
|
|
78
95
|
|
|
79
96
|
You can run `duel --help` to get the same info. Below is the output of that:
|
|
@@ -84,6 +101,7 @@ Usage: duel [options]
|
|
|
84
101
|
Options:
|
|
85
102
|
--project, -p [path] Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.
|
|
86
103
|
--pkg-dir, -k [path] The directory to start looking for a package.json file. Defaults to cwd.
|
|
104
|
+
--modules, -m Transform module globals for dual build target. Defaults to false.
|
|
87
105
|
--dirs, -d Output both builds to directories inside of outDir. [esm, cjs].
|
|
88
106
|
--help, -h Print this message.
|
|
89
107
|
```
|
|
@@ -94,7 +112,7 @@ These are definitely edge cases, and would only really come up if your project m
|
|
|
94
112
|
|
|
95
113
|
- This is going to work best if your CJS-first project uses file extensions in _relative_ specifiers. This is completely acceptable in CJS projects, and [required in ESM projects](https://nodejs.org/api/esm.html#import-specifiers). This package makes no attempt to rewrite bare specifiers, or remap any relative specifiers to a directory index.
|
|
96
114
|
|
|
97
|
-
- Unfortunately, TypeScript doesn't really build [dual packages](https://nodejs.org/api/packages.html#dual-commonjses-module-packages) very well
|
|
115
|
+
- Unfortunately, TypeScript doesn't really build [dual packages](https://nodejs.org/api/packages.html#dual-commonjses-module-packages) very well. One instance of unexpected behavior is when the compiler throws errors for ES module globals when running a dual CJS build, but not for the inverse case, despite both causing runtime errors in Node.js. See the [open issue](https://github.com/microsoft/TypeScript/issues/58658). You can circumvent this with `duel` by using the `--modules` option if your project uses module globals such as `import.meta` properties or `__dirname`, `__filename`, etc. in a CommonJS project.
|
|
98
116
|
|
|
99
117
|
- 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`.
|
|
100
118
|
|
|
@@ -102,4 +120,6 @@ These are definitely edge cases, and would only really come up if your project m
|
|
|
102
120
|
|
|
103
121
|
## Notes
|
|
104
122
|
|
|
105
|
-
As far as I can tell, `duel` is one (if not the only) way to get a correct dual package build using `tsc`
|
|
123
|
+
As far as I can tell, `duel` is one (if not the only) way to get a correct dual package build using `tsc` without requiring multiple `tsconfig.json` files or extra configuration. The Microsoft backed TypeScript team [keep](https://github.com/microsoft/TypeScript/pull/54546) [talking](https://github.com/microsoft/TypeScript/issues/54593) about dual build support, but they continue to [refuse to rewrite specifiers](https://github.com/microsoft/TypeScript/issues/16577).
|
|
124
|
+
|
|
125
|
+
Fortunately, Node.js has added `--experimental-require-module` so that you can [`require()` ES modules](https://nodejs.org/api/esm.html#require) if they don't use top level await, which sets the stage for possibly no longer requiring dual builds.
|
package/dist/cjs/duel.cjs
CHANGED
|
@@ -28,7 +28,7 @@ const handleErrorAndExit = message => {
|
|
|
28
28
|
const duel = async (args) => {
|
|
29
29
|
const ctx = await (0, init_js_1.init)(args);
|
|
30
30
|
if (ctx) {
|
|
31
|
-
const { projectDir, tsconfig, configPath, dirs, pkg } = ctx;
|
|
31
|
+
const { projectDir, tsconfig, configPath, modules, dirs, pkg } = ctx;
|
|
32
32
|
const tsc = await (0, find_up_1.findUp)(async (dir) => {
|
|
33
33
|
const tscBin = (0, node_path_1.join)(dir, 'node_modules', '.bin', 'tsc');
|
|
34
34
|
if (await (0, find_up_1.pathExists)(tscBin)) {
|
|
@@ -38,7 +38,7 @@ const duel = async (args) => {
|
|
|
38
38
|
const runBuild = (project, outDir) => {
|
|
39
39
|
return new Promise((resolve, reject) => {
|
|
40
40
|
const args = outDir ? ['-p', project, '--outDir', outDir] : ['-p', project];
|
|
41
|
-
const build = (0, node_child_process_1.spawn)(tsc, args, { stdio: 'inherit' });
|
|
41
|
+
const build = (0, node_child_process_1.spawn)(tsc, args, { stdio: 'inherit', shell: node_process_1.platform === 'win32' });
|
|
42
42
|
build.on('error', err => {
|
|
43
43
|
reject(new Error(`Failed to compile: ${err.message}`));
|
|
44
44
|
});
|
|
@@ -109,16 +109,36 @@ const duel = async (args) => {
|
|
|
109
109
|
handleErrorAndExit(message);
|
|
110
110
|
}
|
|
111
111
|
if (success) {
|
|
112
|
-
const compileFiles = (0, util_js_1.getCompileFiles)(tsc, projectDir);
|
|
113
112
|
const subDir = (0, node_path_1.join)(projectDir, `_${hex}_`);
|
|
114
|
-
const dualConfigPath = (0, node_path_1.join)(subDir, `tsconfig.${hex}.json`);
|
|
115
113
|
const absoluteDualOutDir = (0, node_path_1.join)(projectDir, isCjsBuild ? (0, node_path_1.join)(outDir, 'cjs') : (0, node_path_1.join)(outDir, 'esm'));
|
|
116
114
|
const tsconfigDual = getOverrideTsConfig();
|
|
117
115
|
const pkgRename = 'package.json.bak';
|
|
116
|
+
let dualConfigPath = (0, node_path_1.join)(projectDir, `tsconfig.${hex}.json`);
|
|
118
117
|
let errorMsg = '';
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
if (modules) {
|
|
119
|
+
const compileFiles = (0, util_js_1.getCompileFiles)(tsc, projectDir);
|
|
120
|
+
dualConfigPath = (0, node_path_1.join)(subDir, `tsconfig.${hex}.json`);
|
|
121
|
+
await (0, promises_1.mkdir)(subDir);
|
|
122
|
+
await Promise.all(compileFiles.map(file => (0, promises_1.cp)(file, (0, node_path_1.join)(subDir, (0, node_path_1.relative)(projectDir, file).replace(/^(\.\.\/)*/, '')))));
|
|
123
|
+
/**
|
|
124
|
+
* Transform ambiguous modules for the target dual build.
|
|
125
|
+
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
126
|
+
*/
|
|
127
|
+
const toTransform = await (0, glob_1.glob)(`${subDir}/**/*{.js,.jsx,.ts,.tsx}`, {
|
|
128
|
+
ignore: 'node_modules/**',
|
|
129
|
+
});
|
|
130
|
+
for (const file of toTransform) {
|
|
131
|
+
/**
|
|
132
|
+
* Maybe include the option to transform modules implicitly
|
|
133
|
+
* (modules: true) so that `exports` are correctly converted
|
|
134
|
+
* when targeting a CJS dual build. Depends on @knighted/module
|
|
135
|
+
* supporting he `modules` option.
|
|
136
|
+
*
|
|
137
|
+
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
138
|
+
*/
|
|
139
|
+
await (0, module_1.transform)(file, { out: file, type: isCjsBuild ? 'commonjs' : 'module' });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
122
142
|
/**
|
|
123
143
|
* Create a new package.json with updated `type` field.
|
|
124
144
|
* Create a new tsconfig.json.
|
|
@@ -128,16 +148,6 @@ const duel = async (args) => {
|
|
|
128
148
|
type: isCjsBuild ? 'commonjs' : 'module',
|
|
129
149
|
}));
|
|
130
150
|
await (0, promises_1.writeFile)(dualConfigPath, JSON.stringify(tsconfigDual));
|
|
131
|
-
/**
|
|
132
|
-
* Transform ambiguous modules for the target dual build.
|
|
133
|
-
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
134
|
-
*/
|
|
135
|
-
const toTransform = await (0, glob_1.glob)(`${subDir}/**/*{.js,.jsx,.ts,.tsx}`, {
|
|
136
|
-
ignore: 'node_modules/**',
|
|
137
|
-
});
|
|
138
|
-
for (const file of toTransform) {
|
|
139
|
-
await (0, module_1.transform)(file, { out: file, type: isCjsBuild ? 'commonjs' : 'module' });
|
|
140
|
-
}
|
|
141
151
|
// Build dual
|
|
142
152
|
(0, util_js_1.log)('Starting dual build...');
|
|
143
153
|
try {
|
|
@@ -169,6 +179,6 @@ const duel = async (args) => {
|
|
|
169
179
|
};
|
|
170
180
|
exports.duel = duel;
|
|
171
181
|
const realFileUrlArgv1 = await (0, util_js_1.getRealPathAsFileUrl)(node_process_1.argv[1]);
|
|
172
|
-
if (
|
|
182
|
+
if (import.meta.url === realFileUrlArgv1) {
|
|
173
183
|
await duel();
|
|
174
184
|
}
|
package/dist/cjs/init.cjs
CHANGED
|
@@ -32,6 +32,11 @@ const init = async (args) => {
|
|
|
32
32
|
short: 'k',
|
|
33
33
|
default: (0, node_process_1.cwd)(),
|
|
34
34
|
},
|
|
35
|
+
modules: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
short: 'm',
|
|
38
|
+
default: false,
|
|
39
|
+
},
|
|
35
40
|
dirs: {
|
|
36
41
|
type: 'boolean',
|
|
37
42
|
short: 'd',
|
|
@@ -55,11 +60,12 @@ const init = async (args) => {
|
|
|
55
60
|
(0, util_js_1.log)('Options:');
|
|
56
61
|
(0, util_js_1.log)("--project, -p [path] \t Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.");
|
|
57
62
|
(0, util_js_1.log)('--pkg-dir, -k [path] \t The directory to start looking for a package.json file. Defaults to cwd.');
|
|
63
|
+
(0, util_js_1.log)('--modules, -m \t\t Transform module globals for dual build target. Defaults to false.');
|
|
58
64
|
(0, util_js_1.log)('--dirs, -d \t\t Output both builds to directories inside of outDir. [esm, cjs].');
|
|
59
65
|
(0, util_js_1.log)('--help, -h \t\t Print this message.');
|
|
60
66
|
}
|
|
61
67
|
else {
|
|
62
|
-
const { project, 'target-extension': targetExt, 'pkg-dir': pkgDir, dirs } = parsed;
|
|
68
|
+
const { project, 'target-extension': targetExt, 'pkg-dir': pkgDir, modules, dirs, } = parsed;
|
|
63
69
|
let configPath = (0, node_path_1.resolve)(project);
|
|
64
70
|
let stats = null;
|
|
65
71
|
let pkg = null;
|
|
@@ -108,6 +114,7 @@ const init = async (args) => {
|
|
|
108
114
|
return {
|
|
109
115
|
pkg,
|
|
110
116
|
dirs,
|
|
117
|
+
modules,
|
|
111
118
|
tsconfig,
|
|
112
119
|
projectDir,
|
|
113
120
|
configPath,
|
package/dist/cjs/init.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export function init(args: any): Promise<false | {
|
|
2
2
|
pkg: import("read-package-up", { with: { "resolution-mode": "import" } }).NormalizedReadResult;
|
|
3
|
-
dirs: boolean
|
|
3
|
+
dirs: boolean;
|
|
4
|
+
modules: boolean;
|
|
4
5
|
tsconfig: any;
|
|
5
6
|
projectDir: string;
|
|
6
7
|
configPath: string;
|
package/dist/cjs/util.cjs
CHANGED
|
@@ -5,6 +5,7 @@ const node_url_1 = require("node:url");
|
|
|
5
5
|
const promises_1 = require("node:fs/promises");
|
|
6
6
|
const node_child_process_1 = require("node:child_process");
|
|
7
7
|
const node_process_1 = require("node:process");
|
|
8
|
+
const node_os_1 = require("node:os");
|
|
8
9
|
const log = (color = '\x1b[30m', msg = '') => {
|
|
9
10
|
// eslint-disable-next-line no-console
|
|
10
11
|
console.log(`${color}%s\x1b[0m`, msg);
|
|
@@ -19,11 +20,14 @@ const getRealPathAsFileUrl = async (path) => {
|
|
|
19
20
|
};
|
|
20
21
|
exports.getRealPathAsFileUrl = getRealPathAsFileUrl;
|
|
21
22
|
const getCompileFiles = (tscBinPath, wd = (0, node_process_1.cwd)()) => {
|
|
22
|
-
const { stdout } = (0, node_child_process_1.spawnSync)(tscBinPath, ['--listFilesOnly'], {
|
|
23
|
+
const { stdout } = (0, node_child_process_1.spawnSync)(tscBinPath, ['--listFilesOnly'], {
|
|
24
|
+
cwd: wd,
|
|
25
|
+
shell: node_process_1.platform === 'win32',
|
|
26
|
+
});
|
|
23
27
|
// Exclude node_modules and empty strings.
|
|
24
28
|
return stdout
|
|
25
29
|
.toString()
|
|
26
|
-
.split(
|
|
30
|
+
.split(node_os_1.EOL)
|
|
27
31
|
.filter(path => !/node_modules|^$/.test(path));
|
|
28
32
|
};
|
|
29
33
|
exports.getCompileFiles = getCompileFiles;
|
package/dist/esm/duel.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { argv } from 'node:process';
|
|
2
|
+
import { argv, platform } from 'node:process';
|
|
3
3
|
import { join, dirname, resolve, relative } from 'node:path';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
-
import { writeFile, rm, rename,
|
|
5
|
+
import { writeFile, rm, rename, mkdir, cp } from 'node:fs/promises';
|
|
6
6
|
import { randomBytes } from 'node:crypto';
|
|
7
7
|
import { performance } from 'node:perf_hooks';
|
|
8
8
|
import { glob } from 'glob';
|
|
@@ -25,7 +25,7 @@ const handleErrorAndExit = message => {
|
|
|
25
25
|
const duel = async (args) => {
|
|
26
26
|
const ctx = await init(args);
|
|
27
27
|
if (ctx) {
|
|
28
|
-
const { projectDir, tsconfig, configPath, dirs, pkg } = ctx;
|
|
28
|
+
const { projectDir, tsconfig, configPath, modules, dirs, pkg } = ctx;
|
|
29
29
|
const tsc = await findUp(async (dir) => {
|
|
30
30
|
const tscBin = join(dir, 'node_modules', '.bin', 'tsc');
|
|
31
31
|
if (await pathExists(tscBin)) {
|
|
@@ -35,7 +35,7 @@ const duel = async (args) => {
|
|
|
35
35
|
const runBuild = (project, outDir) => {
|
|
36
36
|
return new Promise((resolve, reject) => {
|
|
37
37
|
const args = outDir ? ['-p', project, '--outDir', outDir] : ['-p', project];
|
|
38
|
-
const build = spawn(tsc, args, { stdio: 'inherit' });
|
|
38
|
+
const build = spawn(tsc, args, { stdio: 'inherit', shell: platform === 'win32' });
|
|
39
39
|
build.on('error', err => {
|
|
40
40
|
reject(new Error(`Failed to compile: ${err.message}`));
|
|
41
41
|
});
|
|
@@ -106,16 +106,36 @@ const duel = async (args) => {
|
|
|
106
106
|
handleErrorAndExit(message);
|
|
107
107
|
}
|
|
108
108
|
if (success) {
|
|
109
|
-
const compileFiles = getCompileFiles(tsc, projectDir);
|
|
110
109
|
const subDir = join(projectDir, `_${hex}_`);
|
|
111
|
-
const dualConfigPath = join(subDir, `tsconfig.${hex}.json`);
|
|
112
110
|
const absoluteDualOutDir = join(projectDir, isCjsBuild ? join(outDir, 'cjs') : join(outDir, 'esm'));
|
|
113
111
|
const tsconfigDual = getOverrideTsConfig();
|
|
114
112
|
const pkgRename = 'package.json.bak';
|
|
113
|
+
let dualConfigPath = join(projectDir, `tsconfig.${hex}.json`);
|
|
115
114
|
let errorMsg = '';
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
if (modules) {
|
|
116
|
+
const compileFiles = getCompileFiles(tsc, projectDir);
|
|
117
|
+
dualConfigPath = join(subDir, `tsconfig.${hex}.json`);
|
|
118
|
+
await mkdir(subDir);
|
|
119
|
+
await Promise.all(compileFiles.map(file => cp(file, join(subDir, relative(projectDir, file).replace(/^(\.\.\/)*/, '')))));
|
|
120
|
+
/**
|
|
121
|
+
* Transform ambiguous modules for the target dual build.
|
|
122
|
+
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
123
|
+
*/
|
|
124
|
+
const toTransform = await glob(`${subDir}/**/*{.js,.jsx,.ts,.tsx}`, {
|
|
125
|
+
ignore: 'node_modules/**',
|
|
126
|
+
});
|
|
127
|
+
for (const file of toTransform) {
|
|
128
|
+
/**
|
|
129
|
+
* Maybe include the option to transform modules implicitly
|
|
130
|
+
* (modules: true) so that `exports` are correctly converted
|
|
131
|
+
* when targeting a CJS dual build. Depends on @knighted/module
|
|
132
|
+
* supporting he `modules` option.
|
|
133
|
+
*
|
|
134
|
+
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
135
|
+
*/
|
|
136
|
+
await transform(file, { out: file, type: isCjsBuild ? 'commonjs' : 'module' });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
119
139
|
/**
|
|
120
140
|
* Create a new package.json with updated `type` field.
|
|
121
141
|
* Create a new tsconfig.json.
|
|
@@ -125,16 +145,6 @@ const duel = async (args) => {
|
|
|
125
145
|
type: isCjsBuild ? 'commonjs' : 'module',
|
|
126
146
|
}));
|
|
127
147
|
await writeFile(dualConfigPath, JSON.stringify(tsconfigDual));
|
|
128
|
-
/**
|
|
129
|
-
* Transform ambiguous modules for the target dual build.
|
|
130
|
-
* @see https://github.com/microsoft/TypeScript/issues/58658
|
|
131
|
-
*/
|
|
132
|
-
const toTransform = await glob(`${subDir}/**/*{.js,.jsx,.ts,.tsx}`, {
|
|
133
|
-
ignore: 'node_modules/**',
|
|
134
|
-
});
|
|
135
|
-
for (const file of toTransform) {
|
|
136
|
-
await transform(file, { out: file, type: isCjsBuild ? 'commonjs' : 'module' });
|
|
137
|
-
}
|
|
138
148
|
// Build dual
|
|
139
149
|
log('Starting dual build...');
|
|
140
150
|
try {
|
package/dist/esm/init.d.ts
CHANGED
package/dist/esm/init.js
CHANGED
|
@@ -26,6 +26,11 @@ const init = async (args) => {
|
|
|
26
26
|
short: 'k',
|
|
27
27
|
default: cwd(),
|
|
28
28
|
},
|
|
29
|
+
modules: {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
short: 'm',
|
|
32
|
+
default: false,
|
|
33
|
+
},
|
|
29
34
|
dirs: {
|
|
30
35
|
type: 'boolean',
|
|
31
36
|
short: 'd',
|
|
@@ -49,11 +54,12 @@ const init = async (args) => {
|
|
|
49
54
|
log('Options:');
|
|
50
55
|
log("--project, -p [path] \t Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.");
|
|
51
56
|
log('--pkg-dir, -k [path] \t The directory to start looking for a package.json file. Defaults to cwd.');
|
|
57
|
+
log('--modules, -m \t\t Transform module globals for dual build target. Defaults to false.');
|
|
52
58
|
log('--dirs, -d \t\t Output both builds to directories inside of outDir. [esm, cjs].');
|
|
53
59
|
log('--help, -h \t\t Print this message.');
|
|
54
60
|
}
|
|
55
61
|
else {
|
|
56
|
-
const { project, 'target-extension': targetExt, 'pkg-dir': pkgDir, dirs } = parsed;
|
|
62
|
+
const { project, 'target-extension': targetExt, 'pkg-dir': pkgDir, modules, dirs, } = parsed;
|
|
57
63
|
let configPath = resolve(project);
|
|
58
64
|
let stats = null;
|
|
59
65
|
let pkg = null;
|
|
@@ -102,6 +108,7 @@ const init = async (args) => {
|
|
|
102
108
|
return {
|
|
103
109
|
pkg,
|
|
104
110
|
dirs,
|
|
111
|
+
modules,
|
|
105
112
|
tsconfig,
|
|
106
113
|
projectDir,
|
|
107
114
|
configPath,
|
package/dist/esm/util.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { pathToFileURL } from 'node:url';
|
|
2
2
|
import { realpath } from 'node:fs/promises';
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
|
-
import { cwd } from 'node:process';
|
|
4
|
+
import { cwd, platform } from 'node:process';
|
|
5
|
+
import { EOL } from 'node:os';
|
|
5
6
|
const log = (color = '\x1b[30m', msg = '') => {
|
|
6
7
|
// eslint-disable-next-line no-console
|
|
7
8
|
console.log(`${color}%s\x1b[0m`, msg);
|
|
@@ -13,11 +14,14 @@ const getRealPathAsFileUrl = async (path) => {
|
|
|
13
14
|
return asFileUrl;
|
|
14
15
|
};
|
|
15
16
|
const getCompileFiles = (tscBinPath, wd = cwd()) => {
|
|
16
|
-
const { stdout } = spawnSync(tscBinPath, ['--listFilesOnly'], {
|
|
17
|
+
const { stdout } = spawnSync(tscBinPath, ['--listFilesOnly'], {
|
|
18
|
+
cwd: wd,
|
|
19
|
+
shell: platform === 'win32',
|
|
20
|
+
});
|
|
17
21
|
// Exclude node_modules and empty strings.
|
|
18
22
|
return stdout
|
|
19
23
|
.toString()
|
|
20
|
-
.split(
|
|
24
|
+
.split(EOL)
|
|
21
25
|
.filter(path => !/node_modules|^$/.test(path));
|
|
22
26
|
};
|
|
23
27
|
export { log, logError, getRealPathAsFileUrl, getCompileFiles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/duel",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.2",
|
|
4
4
|
"description": "TypeScript dual packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/esm/duel.js",
|
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
},
|
|
19
19
|
"engineStrict": true,
|
|
20
20
|
"scripts": {
|
|
21
|
-
"prettier": "prettier -w src/*.js test/*.js",
|
|
21
|
+
"prettier": "prettier -w *.js src/*.js test/*.js",
|
|
22
22
|
"lint": "eslint src/*.js test/*.js",
|
|
23
|
-
"test": "
|
|
23
|
+
"test:integration": "node --test --test-reporter=spec test/integration.js",
|
|
24
|
+
"test:monorepos": "node --test --test-reporter=spec test/monorepos.js",
|
|
25
|
+
"test": "c8 --reporter=text --reporter=text-summary --reporter=lcov node --test --test-reporter=spec test/integration.js test/monorepos.js",
|
|
24
26
|
"build": "node src/duel.js --dirs",
|
|
25
27
|
"prepack": "npm run build"
|
|
26
28
|
},
|
|
@@ -51,19 +53,22 @@
|
|
|
51
53
|
"url": "https://github.com/knightedcodemonkey/duel/issues"
|
|
52
54
|
},
|
|
53
55
|
"peerDependencies": {
|
|
54
|
-
"typescript": ">=
|
|
56
|
+
"typescript": ">=5.5.0-dev || >=5.6.0-dev || >=5.7.0-dev || next"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"eslint
|
|
59
|
+
"@eslint/js": "^9.6.0",
|
|
60
|
+
"@types/node": "^22.7.4",
|
|
61
|
+
"c8": "^10.1.2",
|
|
62
|
+
"eslint": "^9.5.0",
|
|
63
|
+
"eslint-plugin-n": "^17.9.0",
|
|
64
|
+
"globals": "^15.6.0",
|
|
61
65
|
"prettier": "^3.2.4",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
66
|
+
"tsx": "^4.19.1",
|
|
67
|
+
"typescript": "^5.6.2",
|
|
68
|
+
"vite": "^5.4.8"
|
|
64
69
|
},
|
|
65
70
|
"dependencies": {
|
|
66
|
-
"@knighted/module": "^1.0.0-alpha.
|
|
71
|
+
"@knighted/module": "^1.0.0-alpha.4",
|
|
67
72
|
"@knighted/specifier": "^2.0.0-rc.1",
|
|
68
73
|
"find-up": "^6.3.0",
|
|
69
74
|
"glob": "^10.3.3",
|