@napi-rs/cli 3.8.5 → 3.9.0
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/dist/cli.js +37 -7
- package/dist/index.cjs +37 -7
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +37 -7
- package/docs/build.md +36 -34
- package/package.json +15 -6
- package/src/api/__tests__/build.spec.ts +90 -0
- package/src/api/__tests__/templates.spec.ts +22 -0
- package/src/api/build.ts +57 -3
- package/src/api/templates/js-binding.ts +0 -1
- package/src/commands/__tests__/build.spec.ts +24 -0
- package/src/def/build.ts +30 -4
package/docs/build.md
CHANGED
|
@@ -22,37 +22,39 @@ new NapiCli().build({
|
|
|
22
22
|
|
|
23
23
|
## Options
|
|
24
24
|
|
|
25
|
-
| Options | CLI Options | type
|
|
26
|
-
| ----------------- | --------------------- |
|
|
27
|
-
| | --help,-h |
|
|
28
|
-
| target | --target,-t | string
|
|
29
|
-
| cwd | --cwd | string
|
|
30
|
-
| manifestPath | --manifest-path | string
|
|
31
|
-
| configPath | --config-path,-c | string
|
|
32
|
-
| packageJsonPath | --package-json-path | string
|
|
33
|
-
| targetDir | --target-dir | string
|
|
34
|
-
| outputDir | --output-dir,-o | string
|
|
35
|
-
| platform | --platform | boolean
|
|
36
|
-
| jsPackageName | --js-package-name | string
|
|
37
|
-
| constEnum | --const-enum | boolean
|
|
38
|
-
| runtimeStringEnum | --runtime-string-enum | boolean
|
|
39
|
-
| jsBinding | --js
|
|
40
|
-
| noJsBinding | --no-js | boolean
|
|
41
|
-
| dts | --dts | string
|
|
42
|
-
| dtsHeader | --dts-header | string
|
|
43
|
-
| noDtsHeader | --no-dts-header | boolean
|
|
44
|
-
| dtsCache | --dts-cache | boolean
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
25
|
+
| Options | CLI Options | type | required | default | description |
|
|
26
|
+
| ----------------- | --------------------- | ------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| | --help,-h | | | | get help |
|
|
28
|
+
| target | --target,-t | string | false | | Build for the target triple, bypassed to `cargo build --target` |
|
|
29
|
+
| cwd | --cwd | string | false | | The working directory of where napi command will be executed in, all other paths options are relative to this path |
|
|
30
|
+
| manifestPath | --manifest-path | string | false | | Path to `Cargo.toml` |
|
|
31
|
+
| configPath | --config-path,-c | string | false | | Path to `napi` config json file |
|
|
32
|
+
| packageJsonPath | --package-json-path | string | false | | Path to `package.json` |
|
|
33
|
+
| targetDir | --target-dir | string | false | | Directory for all crate generated artifacts, see `cargo build --target-dir` |
|
|
34
|
+
| outputDir | --output-dir,-o | string | false | | Path to where all the built files would be put. Default to the crate folder |
|
|
35
|
+
| platform | --platform | boolean | false | | Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node` |
|
|
36
|
+
| jsPackageName | --js-package-name | string | false | | Package name in generated js binding file. Only works with `--platform` flag |
|
|
37
|
+
| constEnum | --const-enum | boolean | false | | Whether generate const enum for typescript bindings |
|
|
38
|
+
| runtimeStringEnum | --runtime-string-enum | boolean | false | | Emit `#[napi(string_enum)]` enums as runtime enums (`export declare enum`) under `--no-const-enum`. Default: type-only union. |
|
|
39
|
+
| jsBinding | --js,--js-binding | string | false | | Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output-dir`. |
|
|
40
|
+
| noJsBinding | --no-js | boolean | false | | Whether to disable the generation JS binding file. Only works with `--platform` flag. |
|
|
41
|
+
| dts | --dts | string | false | | Path and filename of generated type def file. Relative to `--output-dir` |
|
|
42
|
+
| dtsHeader | --dts-header | string | false | | Custom file header for generated type def file. Only works when `typedef` feature enabled. |
|
|
43
|
+
| noDtsHeader | --no-dts-header | boolean | false | | Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled. |
|
|
44
|
+
| dtsCache | --dts-cache | boolean | false | true | Whether to enable the dts cache, default to true |
|
|
45
|
+
| format | --format | 'esm' \| 'commonjs' | false | | The module format of the generated JS binding file. Only works with `--platform` flag. Defaults to `commonjs`. |
|
|
46
|
+
| esm | --esm | boolean | false | | Alias for `--format esm`. |
|
|
47
|
+
| commonjs | --commonjs | boolean | false | | Alias for `--format commonjs`. |
|
|
48
|
+
| strip | --strip,-s | boolean | false | | Whether strip the library to achieve the minimum file size |
|
|
49
|
+
| release | --release,-r | boolean | false | | Build in release mode |
|
|
50
|
+
| verbose | --verbose,-v | boolean | false | | Verbosely log build command trace |
|
|
51
|
+
| bin | --bin | string | false | | Build only the specified binary |
|
|
52
|
+
| package | --package,-p | string | false | | Build the specified library or the one at cwd |
|
|
53
|
+
| profile | --profile | string | false | | Build artifacts with the specified profile |
|
|
54
|
+
| crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross compile by replacing the cargo subcommand: Windows MSVC targets from a non-Windows host build with `cargo-xwin` (`windows-gnu` targets are rejected, `cargo-xwin` cannot handle them), non-Windows targets build with `cargo-zigbuild` (requires `zig` on PATH). The selected subcommand is auto-installed on first use. Cannot be combined with `--use-cross`, `--use-napi-cross` or `--watch` |
|
|
55
|
+
| useCross | --use-cross | boolean | false | | [experimental] not recommended, prefer `--cross-compile` or `--use-napi-cross`: build in a Docker or Podman container with [cross](https://github.com/cross-rs/cross), which must be installed manually and needs a running container engine. Cannot be combined with `--cross-compile`, `--use-napi-cross` or `--watch` |
|
|
56
|
+
| useNapiCross | --use-napi-cross | boolean | false | | [experimental] download a prebuilt gcc cross toolchain from `@napi-rs/cross-toolchain` (glibc 2.17) and set linker and C compiler environment variables. Linux glibc targets only (x64, arm64, armv7, ppc64le, s390x) on a Linux x64 or arm64 host, any other target or host errors. Cannot be combined with `--cross-compile` or `--use-cross` |
|
|
57
|
+
| watch | --watch,-w | boolean | false | | watch the crate changes and build continuously with `cargo-watch` crates |
|
|
58
|
+
| features | --features,-F | string[] | false | | Space-separated list of features to activate |
|
|
59
|
+
| allFeatures | --all-features | boolean | false | | Activate all available features |
|
|
60
|
+
| noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the `default` feature |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napi-rs/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "Cli tools for napi-rs",
|
|
5
5
|
"author": "LongYinan <lynweklm@gmail.com>",
|
|
6
6
|
"homepage": "https://napi.rs/",
|
|
@@ -63,11 +63,10 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@inquirer/prompts": "^8.5.2",
|
|
65
65
|
"@napi-rs/cross-toolchain": "^1.0.3",
|
|
66
|
-
"@napi-rs/wasm-tools": "^1.0
|
|
66
|
+
"@napi-rs/wasm-tools": "^1.1.0",
|
|
67
67
|
"@octokit/rest": "^22.0.1",
|
|
68
68
|
"clipanion": "^4.0.0-rc.4",
|
|
69
69
|
"colorette": "^2.0.20",
|
|
70
|
-
"emnapi": "2.0.0-alpha.3",
|
|
71
70
|
"es-toolkit": "^1.47.0",
|
|
72
71
|
"js-yaml": "^4.2.0",
|
|
73
72
|
"obug": "^2.1.2",
|
|
@@ -76,7 +75,8 @@
|
|
|
76
75
|
"typescript": "^6.0.3"
|
|
77
76
|
},
|
|
78
77
|
"devDependencies": {
|
|
79
|
-
"@emnapi/
|
|
78
|
+
"@emnapi/core": "^2.0.0-alpha.4",
|
|
79
|
+
"@emnapi/runtime": "^2.0.0-alpha.4",
|
|
80
80
|
"@oxc-node/core": "^0.1.0",
|
|
81
81
|
"@std/toml": "npm:@jsr/std__toml@^1.0.11",
|
|
82
82
|
"@types/inquirer": "^9.0.9",
|
|
@@ -84,19 +84,28 @@
|
|
|
84
84
|
"@types/node": "^25.9.2",
|
|
85
85
|
"@types/semver": "^7.7.1",
|
|
86
86
|
"ava": "^8.0.1",
|
|
87
|
+
"emnapi": "^2.0.0-alpha.4",
|
|
87
88
|
"empathic": "^2.0.1",
|
|
88
89
|
"env-paths": "^4.0.0",
|
|
89
|
-
"oxc-parser": "^0.
|
|
90
|
+
"oxc-parser": "^0.148.0",
|
|
90
91
|
"prettier": "^3.8.3",
|
|
91
92
|
"tsdown": "^0.22.2",
|
|
92
93
|
"tslib": "^2.8.1"
|
|
93
94
|
},
|
|
94
95
|
"peerDependencies": {
|
|
95
|
-
"@emnapi/
|
|
96
|
+
"@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
|
|
97
|
+
"@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4",
|
|
98
|
+
"emnapi": "^1.7.1 || ^2.0.0-alpha.4"
|
|
96
99
|
},
|
|
97
100
|
"peerDependenciesMeta": {
|
|
101
|
+
"@emnapi/core": {
|
|
102
|
+
"optional": true
|
|
103
|
+
},
|
|
98
104
|
"@emnapi/runtime": {
|
|
99
105
|
"optional": true
|
|
106
|
+
},
|
|
107
|
+
"emnapi": {
|
|
108
|
+
"optional": true
|
|
100
109
|
}
|
|
101
110
|
},
|
|
102
111
|
"funding": {
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
buildProject,
|
|
28
28
|
generateTypeDef,
|
|
29
29
|
napiCrossToolchainEnvs,
|
|
30
|
+
resolveBuildFormat,
|
|
30
31
|
validateCrossCompileFlags,
|
|
31
32
|
validateNapiCrossSupport,
|
|
32
33
|
writeJsBinding,
|
|
@@ -197,6 +198,95 @@ napi-build = { path = "${napiBuildPath}" }
|
|
|
197
198
|
t.regex(jsContent, /module\.exports\.sum = nativeBinding\.sum/)
|
|
198
199
|
})
|
|
199
200
|
|
|
201
|
+
test('writeJsBinding uses the explicit format independently of the filename', async (t) => {
|
|
202
|
+
const { projectDir } = t.context
|
|
203
|
+
const commonjsPath = join(projectDir, 'binding.cjs')
|
|
204
|
+
const esmPath = join(projectDir, 'binding.js')
|
|
205
|
+
const legacyEsmPath = join(projectDir, 'legacy.js')
|
|
206
|
+
|
|
207
|
+
await writeJsBinding({
|
|
208
|
+
platform: true,
|
|
209
|
+
idents: ['sum'],
|
|
210
|
+
binaryName: 'build-integration',
|
|
211
|
+
packageName: 'build-integration',
|
|
212
|
+
version: '0.1.0',
|
|
213
|
+
outputDir: projectDir,
|
|
214
|
+
jsBinding: 'binding.cjs',
|
|
215
|
+
format: 'commonjs',
|
|
216
|
+
})
|
|
217
|
+
await writeJsBinding({
|
|
218
|
+
platform: true,
|
|
219
|
+
idents: ['sum'],
|
|
220
|
+
binaryName: 'build-integration',
|
|
221
|
+
packageName: 'build-integration',
|
|
222
|
+
version: '0.1.0',
|
|
223
|
+
outputDir: projectDir,
|
|
224
|
+
jsBinding: 'binding.js',
|
|
225
|
+
format: 'esm',
|
|
226
|
+
})
|
|
227
|
+
await writeJsBinding({
|
|
228
|
+
platform: true,
|
|
229
|
+
idents: ['sum'],
|
|
230
|
+
binaryName: 'build-integration',
|
|
231
|
+
packageName: 'build-integration',
|
|
232
|
+
version: '0.1.0',
|
|
233
|
+
outputDir: projectDir,
|
|
234
|
+
jsBinding: 'legacy.js',
|
|
235
|
+
esm: true,
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
const [commonjs, esm, legacyEsm] = await Promise.all([
|
|
239
|
+
readFile(commonjsPath, 'utf8'),
|
|
240
|
+
readFile(esmPath, 'utf8'),
|
|
241
|
+
readFile(legacyEsmPath, 'utf8'),
|
|
242
|
+
])
|
|
243
|
+
|
|
244
|
+
t.regex(commonjs, /module\.exports\.sum = nativeBinding\.sum/)
|
|
245
|
+
t.regex(esm, /export \{ sum \}/)
|
|
246
|
+
t.regex(legacyEsm, /export \{ sum \}/)
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
test('resolveBuildFormat handles defaults, aliases, and conflicts', (t) => {
|
|
250
|
+
const validCases = [
|
|
251
|
+
{ options: {}, expected: 'commonjs' },
|
|
252
|
+
{ options: { format: 'esm' }, expected: 'esm' },
|
|
253
|
+
{ options: { format: 'commonjs' }, expected: 'commonjs' },
|
|
254
|
+
{ options: { esm: true }, expected: 'esm' },
|
|
255
|
+
{ options: { commonjs: true }, expected: 'commonjs' },
|
|
256
|
+
] as const
|
|
257
|
+
|
|
258
|
+
for (const { options, expected } of validCases) {
|
|
259
|
+
t.is(resolveBuildFormat(options), expected)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const invalidCases = [
|
|
263
|
+
{
|
|
264
|
+
options: { esm: true, commonjs: true },
|
|
265
|
+
message: /`--esm` and `--commonjs` cannot be used together/,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
options: { format: 'esm', commonjs: true },
|
|
269
|
+
message: /`--format esm` cannot be used with `--commonjs`/,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
options: { format: 'commonjs', esm: true },
|
|
273
|
+
message: /`--format commonjs` cannot be used with `--esm`/,
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
options: { format: 'invalid' },
|
|
277
|
+
message: /Invalid build format "invalid"/,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
options: { format: '' },
|
|
281
|
+
message: /Invalid build format ""/,
|
|
282
|
+
},
|
|
283
|
+
] as const
|
|
284
|
+
|
|
285
|
+
for (const { options, message } of invalidCases) {
|
|
286
|
+
t.throws(() => resolveBuildFormat(options), { message })
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
|
|
200
290
|
test('generateTypeDef preserves deterministic file order', async (t) => {
|
|
201
291
|
const { projectDir, typeDefDir } = t.context
|
|
202
292
|
|
|
@@ -294,3 +294,25 @@ test('createEsmBinding is Node 12 compatible', (t) => {
|
|
|
294
294
|
t.false(code.includes('?.'), 'ESM loader must not use optional chaining')
|
|
295
295
|
t.false(code.includes('??'), 'ESM loader must not use nullish coalescing')
|
|
296
296
|
})
|
|
297
|
+
|
|
298
|
+
test('createEsmBinding builds native addon loading on portable ESM primitives', (t) => {
|
|
299
|
+
const code = createEsmBinding('test', '@scope/test', ['sum'])
|
|
300
|
+
assertValidJS(t, code, 'esm')
|
|
301
|
+
t.true(
|
|
302
|
+
code.includes(`import { createRequire } from 'module'`),
|
|
303
|
+
'ESM loader must import createRequire so native .node addons can be loaded without the CommonJS `require` global',
|
|
304
|
+
)
|
|
305
|
+
t.true(
|
|
306
|
+
code.includes('const require = createRequire(import.meta.url)'),
|
|
307
|
+
'ESM loader must derive `require` from the current module, not rely on a CommonJS global',
|
|
308
|
+
)
|
|
309
|
+
// `@napi-rs/cli` is a valid Node package but is not running under Deno. Deno
|
|
310
|
+
// rejects `URL.pathname` treated as a filesystem path, which is exactly how a
|
|
311
|
+
// `__dirname` built from `new URL('.', import.meta.url).pathname` behaves on
|
|
312
|
+
// Windows (percent-encoded, forward-slash separated). The ESM native loader
|
|
313
|
+
// never used `__dirname` anyway, so it must not emit that construct at all.
|
|
314
|
+
t.false(
|
|
315
|
+
/new URL\(['"]\.['"], import\.meta\.url\)\.pathname/.test(code),
|
|
316
|
+
'ESM loader must not treat URL.pathname as a filesystem path',
|
|
317
|
+
)
|
|
318
|
+
})
|
package/src/api/build.ts
CHANGED
|
@@ -84,8 +84,13 @@ type WasiBindingMetadata = {
|
|
|
84
84
|
bindingTypeDef?: string
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
export type BuildFormat = 'esm' | 'commonjs'
|
|
88
|
+
|
|
87
89
|
type BuildOptions = RawBuildOptions & { cargoOptions?: string[] }
|
|
88
|
-
type ParsedBuildOptions = Omit<BuildOptions, 'cwd'> & {
|
|
90
|
+
type ParsedBuildOptions = Omit<BuildOptions, 'cwd' | 'format'> & {
|
|
91
|
+
cwd: string
|
|
92
|
+
format: BuildFormat
|
|
93
|
+
}
|
|
89
94
|
|
|
90
95
|
export const WASI_ARTIFACT_METADATA_PREFIX = '// napi-rs-artifact-metadata:'
|
|
91
96
|
|
|
@@ -569,12 +574,57 @@ function readWasmU32(binary: Uint8Array, start: number) {
|
|
|
569
574
|
throw new Error('Invalid WebAssembly unsigned LEB128 value')
|
|
570
575
|
}
|
|
571
576
|
|
|
577
|
+
type BuildFormatOptions = {
|
|
578
|
+
format?: string
|
|
579
|
+
esm?: boolean
|
|
580
|
+
commonjs?: boolean
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Resolve the explicit build format and its legacy CLI/API aliases.
|
|
585
|
+
*
|
|
586
|
+
* CommonJS is the historical default. The aliases are intentionally kept
|
|
587
|
+
* separate from `format` because `--esm` and `--commonjs` are boolean flags,
|
|
588
|
+
* while `--format` takes a value.
|
|
589
|
+
*/
|
|
590
|
+
export function resolveBuildFormat(options: BuildFormatOptions): BuildFormat {
|
|
591
|
+
let format: BuildFormat | undefined
|
|
592
|
+
if (options.format !== undefined) {
|
|
593
|
+
if (options.format === 'esm' || options.format === 'commonjs') {
|
|
594
|
+
format = options.format
|
|
595
|
+
} else {
|
|
596
|
+
throw new Error(
|
|
597
|
+
`Invalid build format ${JSON.stringify(options.format)}. Expected \`esm\` or \`commonjs\`.`,
|
|
598
|
+
)
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (options.esm && options.commonjs) {
|
|
603
|
+
throw new Error('`--esm` and `--commonjs` cannot be used together.')
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const aliasFormat = options.esm
|
|
607
|
+
? 'esm'
|
|
608
|
+
: options.commonjs
|
|
609
|
+
? 'commonjs'
|
|
610
|
+
: undefined
|
|
611
|
+
if (format && aliasFormat && format !== aliasFormat) {
|
|
612
|
+
throw new Error(
|
|
613
|
+
`\`--format ${format}\` cannot be used with \`--${aliasFormat}\`.`,
|
|
614
|
+
)
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
return format ?? aliasFormat ?? 'commonjs'
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** Build the configured NAPI-RS crate and generate its output artifacts. */
|
|
572
621
|
export async function buildProject(rawOptions: BuildOptions) {
|
|
573
622
|
debug('napi build command receive options: %O', rawOptions)
|
|
574
623
|
|
|
575
624
|
const options: ParsedBuildOptions = {
|
|
576
625
|
dtsCache: true,
|
|
577
626
|
...rawOptions,
|
|
627
|
+
format: resolveBuildFormat(rawOptions),
|
|
578
628
|
cwd: rawOptions.cwd ?? process.cwd(),
|
|
579
629
|
}
|
|
580
630
|
|
|
@@ -2003,7 +2053,7 @@ class Builder {
|
|
|
2003
2053
|
noJsBinding: this.options.noJsBinding,
|
|
2004
2054
|
idents,
|
|
2005
2055
|
jsBinding: this.options.jsBinding,
|
|
2006
|
-
|
|
2056
|
+
format: this.options.format,
|
|
2007
2057
|
binaryName: this.config.binaryName,
|
|
2008
2058
|
packageName: this.options.jsPackageName ?? this.config.packageName,
|
|
2009
2059
|
version: process.env.npm_new_version ?? this.config.packageJson.version,
|
|
@@ -2352,7 +2402,9 @@ export interface WriteJsBindingOptions {
|
|
|
2352
2402
|
noJsBinding?: boolean
|
|
2353
2403
|
idents: string[]
|
|
2354
2404
|
jsBinding?: string
|
|
2405
|
+
format?: BuildFormat
|
|
2355
2406
|
esm?: boolean
|
|
2407
|
+
commonjs?: boolean
|
|
2356
2408
|
binaryName: string
|
|
2357
2409
|
packageName: string
|
|
2358
2410
|
version: string
|
|
@@ -2366,6 +2418,7 @@ export interface WriteJsBindingOptions {
|
|
|
2366
2418
|
wasiFlavors?: string[]
|
|
2367
2419
|
}
|
|
2368
2420
|
|
|
2421
|
+
/** Write a platform binding loader in the requested module format. */
|
|
2369
2422
|
export async function writeJsBinding(
|
|
2370
2423
|
options: WriteJsBindingOptions,
|
|
2371
2424
|
): Promise<Output | undefined> {
|
|
@@ -2389,7 +2442,8 @@ export async function writeJsBinding(
|
|
|
2389
2442
|
? localWasiName
|
|
2390
2443
|
: `./${localWasiName}`
|
|
2391
2444
|
|
|
2392
|
-
const createBinding =
|
|
2445
|
+
const createBinding =
|
|
2446
|
+
resolveBuildFormat(options) === 'esm' ? createEsmBinding : createCjsBinding
|
|
2393
2447
|
const binding = createBinding(
|
|
2394
2448
|
options.binaryName,
|
|
2395
2449
|
options.packageName,
|
|
@@ -157,7 +157,6 @@ ${idents.map((ident) => `export { ${ident} }`).join('\n')}`
|
|
|
157
157
|
return `${bindingHeader}
|
|
158
158
|
import { createRequire } from 'module'
|
|
159
159
|
const require = createRequire(import.meta.url)
|
|
160
|
-
const __dirname = new URL('.', import.meta.url).pathname
|
|
161
160
|
|
|
162
161
|
${createCommonBinding(
|
|
163
162
|
localName,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import test from 'ava'
|
|
2
|
+
|
|
3
|
+
import { createBuildCommand } from '../../index.js'
|
|
4
|
+
|
|
5
|
+
test('build supports explicit format and compatibility aliases', (t) => {
|
|
6
|
+
const explicit = createBuildCommand([
|
|
7
|
+
'--format',
|
|
8
|
+
'esm',
|
|
9
|
+
'--js-binding',
|
|
10
|
+
'index.mjs',
|
|
11
|
+
])
|
|
12
|
+
|
|
13
|
+
t.is(explicit.format, 'esm')
|
|
14
|
+
t.is(explicit.jsBinding, 'index.mjs')
|
|
15
|
+
|
|
16
|
+
t.true(createBuildCommand(['--esm']).esm)
|
|
17
|
+
t.true(createBuildCommand(['--commonjs']).commonjs)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('build rejects unsupported formats', (t) => {
|
|
21
|
+
t.throws(() => createBuildCommand(['--format', 'umd']), {
|
|
22
|
+
message: /Invalid value for --format/,
|
|
23
|
+
})
|
|
24
|
+
})
|
package/src/def/build.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// This file is generated by codegen/index.ts
|
|
2
2
|
// Do not edit this file manually
|
|
3
3
|
import { Command, Option } from 'clipanion'
|
|
4
|
+
import * as typanion from 'typanion'
|
|
4
5
|
|
|
5
6
|
export abstract class BaseBuildCommand extends Command {
|
|
6
7
|
static paths = [['build']]
|
|
@@ -60,7 +61,7 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
60
61
|
'Emit `#[napi(string_enum)]` enums as runtime enums (`export declare enum`) under `--no-const-enum`. Default: type-only union.',
|
|
61
62
|
})
|
|
62
63
|
|
|
63
|
-
jsBinding?: string = Option.String('--js', {
|
|
64
|
+
jsBinding?: string = Option.String('--js,--js-binding', {
|
|
64
65
|
description:
|
|
65
66
|
'Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output-dir`.',
|
|
66
67
|
})
|
|
@@ -89,9 +90,21 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
89
90
|
description: 'Whether to enable the dts cache, default to true',
|
|
90
91
|
})
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
format?: 'esm' | 'commonjs' = Option.String('--format', {
|
|
94
|
+
validator: typanion.isOneOf([
|
|
95
|
+
typanion.isLiteral('esm'),
|
|
96
|
+
typanion.isLiteral('commonjs'),
|
|
97
|
+
]),
|
|
93
98
|
description:
|
|
94
|
-
'
|
|
99
|
+
'The module format of the generated JS binding file. Only works with `--platform` flag. Defaults to `commonjs`.',
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
esm?: boolean = Option.Boolean('--esm', {
|
|
103
|
+
description: 'Alias for `--format esm`.',
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
commonjs?: boolean = Option.Boolean('--commonjs', {
|
|
107
|
+
description: 'Alias for `--format commonjs`.',
|
|
95
108
|
})
|
|
96
109
|
|
|
97
110
|
strip?: boolean = Option.Boolean('--strip,-s', {
|
|
@@ -150,6 +163,9 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
150
163
|
description: 'Do not activate the `default` feature',
|
|
151
164
|
})
|
|
152
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Return the parsed build options.
|
|
168
|
+
*/
|
|
153
169
|
getOptions() {
|
|
154
170
|
return {
|
|
155
171
|
target: this.target,
|
|
@@ -169,7 +185,9 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
169
185
|
dtsHeader: this.dtsHeader,
|
|
170
186
|
noDtsHeader: this.noDtsHeader,
|
|
171
187
|
dtsCache: this.dtsCache,
|
|
188
|
+
format: this.format,
|
|
172
189
|
esm: this.esm,
|
|
190
|
+
commonjs: this.commonjs,
|
|
173
191
|
strip: this.strip,
|
|
174
192
|
release: this.release,
|
|
175
193
|
verbose: this.verbose,
|
|
@@ -262,9 +280,17 @@ export interface BuildOptions {
|
|
|
262
280
|
*/
|
|
263
281
|
dtsCache?: boolean
|
|
264
282
|
/**
|
|
265
|
-
*
|
|
283
|
+
* The module format of the generated JS binding file. Only works with `--platform` flag. Defaults to `commonjs`.
|
|
284
|
+
*/
|
|
285
|
+
format?: 'esm' | 'commonjs'
|
|
286
|
+
/**
|
|
287
|
+
* Alias for `--format esm`.
|
|
266
288
|
*/
|
|
267
289
|
esm?: boolean
|
|
290
|
+
/**
|
|
291
|
+
* Alias for `--format commonjs`.
|
|
292
|
+
*/
|
|
293
|
+
commonjs?: boolean
|
|
268
294
|
/**
|
|
269
295
|
* Whether strip the library to achieve the minimum file size
|
|
270
296
|
*/
|