@gjsify/cli 0.1.15 → 0.2.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/lib/actions/build.js +2 -1
- package/lib/commands/build.js +20 -0
- package/lib/config.js +28 -1
- package/lib/types/cli-build-options.d.ts +29 -0
- package/lib/types/config-data.d.ts +5 -0
- package/package.json +12 -13
- package/src/actions/build.ts +2 -1
- package/src/commands/build.ts +20 -0
- package/src/config.ts +30 -1
- package/src/types/cli-build-options.ts +29 -0
- package/src/types/config-data.ts +5 -0
package/lib/actions/build.js
CHANGED
|
@@ -131,7 +131,7 @@ export class BuildAction {
|
|
|
131
131
|
}
|
|
132
132
|
/** Application mode */
|
|
133
133
|
async buildApp(app = 'gjs') {
|
|
134
|
-
const { verbose, esbuild, typescript, exclude, library: pgk } = this.configData;
|
|
134
|
+
const { verbose, esbuild, typescript, exclude, library: pgk, aliases } = this.configData;
|
|
135
135
|
const format = esbuild?.format ?? (esbuild?.outfile?.endsWith('.cjs') ? 'cjs' : 'esm');
|
|
136
136
|
// Set default outfile if no outdir is set
|
|
137
137
|
if (esbuild && !esbuild?.outfile && !esbuild?.outdir && (pgk?.main || pgk?.module)) {
|
|
@@ -145,6 +145,7 @@ export class BuildAction {
|
|
|
145
145
|
exclude,
|
|
146
146
|
reflection: typescript?.reflection,
|
|
147
147
|
consoleShim,
|
|
148
|
+
...(aliases ? { aliases } : {}),
|
|
148
149
|
};
|
|
149
150
|
const { autoMode, extras } = this.parseGlobalsValue(globals);
|
|
150
151
|
// --- Auto mode (with optional extras): iterative multi-pass build ---
|
package/lib/commands/build.js
CHANGED
|
@@ -97,6 +97,26 @@ export const buildCommand = {
|
|
|
97
97
|
type: 'boolean',
|
|
98
98
|
normalize: true,
|
|
99
99
|
default: false
|
|
100
|
+
})
|
|
101
|
+
.option('external', {
|
|
102
|
+
description: "Module names that should NOT be bundled. Repeat the flag or pass a comma-separated list (e.g. --external typedoc,prettier). Globs are forwarded to esbuild as-is. See https://esbuild.github.io/api/#external",
|
|
103
|
+
array: true,
|
|
104
|
+
type: 'string',
|
|
105
|
+
default: [],
|
|
106
|
+
coerce: (arg) => arg.flatMap((v) => v.split(',').map((s) => s.trim()).filter(Boolean)),
|
|
107
|
+
})
|
|
108
|
+
.option('define', {
|
|
109
|
+
description: "Substitute compile-time constants. Each entry is KEY=VALUE where VALUE is a JS expression (string literals must be quoted: --define VERSION='\"1.2.3\"'). Repeat the flag or pass comma-separated. See https://esbuild.github.io/api/#define",
|
|
110
|
+
array: true,
|
|
111
|
+
type: 'string',
|
|
112
|
+
default: [],
|
|
113
|
+
})
|
|
114
|
+
.option('alias', {
|
|
115
|
+
description: "Map module specifiers at bundle time. Each entry is FROM=TO (e.g. --alias typedoc=@gjsify/empty). Layered on top of the built-in alias map. Useful for stubbing heavy deps the test scenario never executes.",
|
|
116
|
+
array: true,
|
|
117
|
+
type: 'string',
|
|
118
|
+
default: [],
|
|
119
|
+
coerce: (arg) => arg.flatMap((v) => v.split(',').map((s) => s.trim()).filter(Boolean)),
|
|
100
120
|
});
|
|
101
121
|
},
|
|
102
122
|
handler: async (args) => {
|
package/lib/config.js
CHANGED
|
@@ -75,13 +75,40 @@ export class Config {
|
|
|
75
75
|
configData.shebang = cliArgs.shebang;
|
|
76
76
|
merge(configData.library ??= {}, pkg, configData.library);
|
|
77
77
|
merge(configData.typescript ??= {}, tsConfig, configData.typescript);
|
|
78
|
+
// Parse `KEY=VALUE` style flags into Record<string, string>.
|
|
79
|
+
// - `--define`: VALUE is a JS expression (string literals must be
|
|
80
|
+
// pre-quoted by the caller, e.g. `'"1.2.3"'`).
|
|
81
|
+
// - `--alias`: VALUE is the substitute module specifier.
|
|
82
|
+
const parseKvPairs = (entries, flag) => {
|
|
83
|
+
const out = {};
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
const idx = entry.indexOf('=');
|
|
86
|
+
if (idx === -1) {
|
|
87
|
+
throw new Error(`Invalid --${flag} value '${entry}'. Expected KEY=VALUE.`);
|
|
88
|
+
}
|
|
89
|
+
const key = entry.slice(0, idx).trim();
|
|
90
|
+
const value = entry.slice(idx + 1);
|
|
91
|
+
if (!key) {
|
|
92
|
+
throw new Error(`Invalid --${flag} value '${entry}'. Empty key.`);
|
|
93
|
+
}
|
|
94
|
+
out[key] = value;
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
};
|
|
98
|
+
const defineMap = parseKvPairs(cliArgs.define ?? [], 'define');
|
|
99
|
+
const aliasMap = parseKvPairs(cliArgs.alias ?? [], 'alias');
|
|
100
|
+
if (Object.keys(aliasMap).length) {
|
|
101
|
+
configData.aliases = { ...(configData.aliases ?? {}), ...aliasMap };
|
|
102
|
+
}
|
|
78
103
|
merge(configData.esbuild ??= {}, {
|
|
79
104
|
format: cliArgs.format,
|
|
80
105
|
minify: cliArgs.minify,
|
|
81
106
|
entryPoints: cliArgs.entryPoints,
|
|
82
107
|
outfile: cliArgs.outfile,
|
|
83
108
|
outdir: cliArgs.outdir,
|
|
84
|
-
logLevel: cliArgs.logLevel || 'warning'
|
|
109
|
+
logLevel: cliArgs.logLevel || 'warning',
|
|
110
|
+
...(cliArgs.external?.length ? { external: cliArgs.external } : {}),
|
|
111
|
+
...(Object.keys(defineMap).length ? { define: defineMap } : {}),
|
|
85
112
|
});
|
|
86
113
|
if (configData.verbose)
|
|
87
114
|
console.debug("configData", configData);
|
|
@@ -60,4 +60,33 @@ export interface CliBuildOptions {
|
|
|
60
60
|
* `--outfile`. Default: false.
|
|
61
61
|
*/
|
|
62
62
|
shebang?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Module names that should NOT be bundled. Each name remains as a literal
|
|
65
|
+
* `import`/`require` in the output and is resolved by the runtime against
|
|
66
|
+
* its own `node_modules` (or equivalent) at execution time.
|
|
67
|
+
*
|
|
68
|
+
* Repeat the flag or pass a comma-separated value:
|
|
69
|
+
* `--external typedoc,prettier --external typescript`. Glob-style wildcards
|
|
70
|
+
* (`@inquirer/*`, `lodash-*`) are forwarded as-is to esbuild.
|
|
71
|
+
*
|
|
72
|
+
* @see https://esbuild.github.io/api/#external
|
|
73
|
+
*/
|
|
74
|
+
external?: string[];
|
|
75
|
+
/**
|
|
76
|
+
* Substitute compile-time constants in the bundle. Each entry is a
|
|
77
|
+
* `KEY=VALUE` pair where `VALUE` is an arbitrary JS expression — string
|
|
78
|
+
* literals must be quoted (`--define VERSION='"1.2.3"'`). Useful for
|
|
79
|
+
* upstream packages that read a build-time constant via
|
|
80
|
+
* `typeof __FOO__ !== 'undefined'`.
|
|
81
|
+
*
|
|
82
|
+
* @see https://esbuild.github.io/api/#define
|
|
83
|
+
*/
|
|
84
|
+
define?: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Map module specifiers to alternative targets at bundle time. Each entry
|
|
87
|
+
* is `FROM=TO` where `FROM` is the imported package name and `TO` is the
|
|
88
|
+
* substitute (typically `@gjsify/empty` to drop a heavy dep that the test
|
|
89
|
+
* scenario never executes). Layered on top of the built-in alias map.
|
|
90
|
+
*/
|
|
91
|
+
alias?: string[];
|
|
63
92
|
}
|
|
@@ -22,4 +22,9 @@ export interface ConfigData {
|
|
|
22
22
|
* Prepend GJS shebang to output and mark executable. See CliBuildOptions.
|
|
23
23
|
*/
|
|
24
24
|
shebang?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Extra module aliases layered on top of the built-in alias map.
|
|
27
|
+
* Comes from `gjsify build --alias FROM=TO`.
|
|
28
|
+
*/
|
|
29
|
+
aliases?: Record<string, string>;
|
|
25
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -23,24 +23,23 @@
|
|
|
23
23
|
"cli"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@gjsify/create-app": "^0.
|
|
27
|
-
"@gjsify/esbuild-plugin-gjsify": "^0.
|
|
28
|
-
"@gjsify/example-dom-
|
|
29
|
-
"@gjsify/example-dom-
|
|
30
|
-
"@gjsify/example-dom-
|
|
31
|
-
"@gjsify/example-dom-three-
|
|
32
|
-
"@gjsify/example-
|
|
33
|
-
"@gjsify/
|
|
34
|
-
"@gjsify/
|
|
35
|
-
"@gjsify/web-polyfills": "^0.1.15",
|
|
26
|
+
"@gjsify/create-app": "^0.2.0",
|
|
27
|
+
"@gjsify/esbuild-plugin-gjsify": "^0.2.0",
|
|
28
|
+
"@gjsify/example-dom-canvas2d-fireworks": "^0.2.0",
|
|
29
|
+
"@gjsify/example-dom-excalibur-jelly-jumper": "^0.2.0",
|
|
30
|
+
"@gjsify/example-dom-three-geometry-teapot": "^0.2.0",
|
|
31
|
+
"@gjsify/example-dom-three-postprocessing-pixel": "^0.2.0",
|
|
32
|
+
"@gjsify/example-node-express-webserver": "^0.2.0",
|
|
33
|
+
"@gjsify/node-polyfills": "^0.2.0",
|
|
34
|
+
"@gjsify/web-polyfills": "^0.2.0",
|
|
36
35
|
"cosmiconfig": "^9.0.1",
|
|
37
36
|
"esbuild": "^0.28.0",
|
|
38
37
|
"get-tsconfig": "^4.14.0",
|
|
39
|
-
"pkg-types": "^2.3.
|
|
38
|
+
"pkg-types": "^2.3.1",
|
|
40
39
|
"yargs": "^18.0.0"
|
|
41
40
|
},
|
|
42
41
|
"devDependencies": {
|
|
43
42
|
"@types/yargs": "^17.0.35",
|
|
44
|
-
"typescript": "^6.0.
|
|
43
|
+
"typescript": "^6.0.3"
|
|
45
44
|
}
|
|
46
45
|
}
|
package/src/actions/build.ts
CHANGED
|
@@ -149,7 +149,7 @@ export class BuildAction {
|
|
|
149
149
|
/** Application mode */
|
|
150
150
|
async buildApp(app: App = 'gjs') {
|
|
151
151
|
|
|
152
|
-
const { verbose, esbuild, typescript, exclude, library: pgk } = this.configData;
|
|
152
|
+
const { verbose, esbuild, typescript, exclude, library: pgk, aliases } = this.configData;
|
|
153
153
|
|
|
154
154
|
const format: 'esm' | 'cjs' = (esbuild?.format as 'esm' | 'cjs') ?? (esbuild?.outfile?.endsWith('.cjs') ? 'cjs' : 'esm');
|
|
155
155
|
|
|
@@ -167,6 +167,7 @@ export class BuildAction {
|
|
|
167
167
|
exclude,
|
|
168
168
|
reflection: typescript?.reflection,
|
|
169
169
|
consoleShim,
|
|
170
|
+
...(aliases ? { aliases } : {}),
|
|
170
171
|
};
|
|
171
172
|
|
|
172
173
|
const { autoMode, extras } = this.parseGlobalsValue(globals);
|
package/src/commands/build.ts
CHANGED
|
@@ -100,6 +100,26 @@ export const buildCommand: Command<any, CliBuildOptions> = {
|
|
|
100
100
|
normalize: true,
|
|
101
101
|
default: false
|
|
102
102
|
})
|
|
103
|
+
.option('external', {
|
|
104
|
+
description: "Module names that should NOT be bundled. Repeat the flag or pass a comma-separated list (e.g. --external typedoc,prettier). Globs are forwarded to esbuild as-is. See https://esbuild.github.io/api/#external",
|
|
105
|
+
array: true,
|
|
106
|
+
type: 'string',
|
|
107
|
+
default: [] as string[],
|
|
108
|
+
coerce: (arg: string[]) => arg.flatMap((v) => v.split(',').map((s) => s.trim()).filter(Boolean)),
|
|
109
|
+
})
|
|
110
|
+
.option('define', {
|
|
111
|
+
description: "Substitute compile-time constants. Each entry is KEY=VALUE where VALUE is a JS expression (string literals must be quoted: --define VERSION='\"1.2.3\"'). Repeat the flag or pass comma-separated. See https://esbuild.github.io/api/#define",
|
|
112
|
+
array: true,
|
|
113
|
+
type: 'string',
|
|
114
|
+
default: [] as string[],
|
|
115
|
+
})
|
|
116
|
+
.option('alias', {
|
|
117
|
+
description: "Map module specifiers at bundle time. Each entry is FROM=TO (e.g. --alias typedoc=@gjsify/empty). Layered on top of the built-in alias map. Useful for stubbing heavy deps the test scenario never executes.",
|
|
118
|
+
array: true,
|
|
119
|
+
type: 'string',
|
|
120
|
+
default: [] as string[],
|
|
121
|
+
coerce: (arg: string[]) => arg.flatMap((v) => v.split(',').map((s) => s.trim()).filter(Boolean)),
|
|
122
|
+
})
|
|
103
123
|
},
|
|
104
124
|
handler: async (args) => {
|
|
105
125
|
const config = new Config();
|
package/src/config.ts
CHANGED
|
@@ -87,13 +87,42 @@ export class Config {
|
|
|
87
87
|
|
|
88
88
|
merge(configData.library ??= {}, pkg, configData.library);
|
|
89
89
|
merge(configData.typescript ??= {}, tsConfig, configData.typescript);
|
|
90
|
+
|
|
91
|
+
// Parse `KEY=VALUE` style flags into Record<string, string>.
|
|
92
|
+
// - `--define`: VALUE is a JS expression (string literals must be
|
|
93
|
+
// pre-quoted by the caller, e.g. `'"1.2.3"'`).
|
|
94
|
+
// - `--alias`: VALUE is the substitute module specifier.
|
|
95
|
+
const parseKvPairs = (entries: readonly string[], flag: string): Record<string, string> => {
|
|
96
|
+
const out: Record<string, string> = {};
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
const idx = entry.indexOf('=');
|
|
99
|
+
if (idx === -1) {
|
|
100
|
+
throw new Error(`Invalid --${flag} value '${entry}'. Expected KEY=VALUE.`);
|
|
101
|
+
}
|
|
102
|
+
const key = entry.slice(0, idx).trim();
|
|
103
|
+
const value = entry.slice(idx + 1);
|
|
104
|
+
if (!key) {
|
|
105
|
+
throw new Error(`Invalid --${flag} value '${entry}'. Empty key.`);
|
|
106
|
+
}
|
|
107
|
+
out[key] = value;
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
};
|
|
111
|
+
const defineMap = parseKvPairs(cliArgs.define ?? [], 'define');
|
|
112
|
+
const aliasMap = parseKvPairs(cliArgs.alias ?? [], 'alias');
|
|
113
|
+
if (Object.keys(aliasMap).length) {
|
|
114
|
+
configData.aliases = { ...(configData.aliases ?? {}), ...aliasMap };
|
|
115
|
+
}
|
|
116
|
+
|
|
90
117
|
merge(configData.esbuild ??= {}, {
|
|
91
118
|
format: cliArgs.format,
|
|
92
119
|
minify: cliArgs.minify,
|
|
93
120
|
entryPoints: cliArgs.entryPoints,
|
|
94
121
|
outfile: cliArgs.outfile,
|
|
95
122
|
outdir: cliArgs.outdir,
|
|
96
|
-
logLevel: cliArgs.logLevel || 'warning'
|
|
123
|
+
logLevel: cliArgs.logLevel || 'warning',
|
|
124
|
+
...(cliArgs.external?.length ? { external: cliArgs.external } : {}),
|
|
125
|
+
...(Object.keys(defineMap).length ? { define: defineMap } : {}),
|
|
97
126
|
});
|
|
98
127
|
|
|
99
128
|
if(configData.verbose) console.debug("configData", configData);
|
|
@@ -61,4 +61,33 @@ export interface CliBuildOptions {
|
|
|
61
61
|
* `--outfile`. Default: false.
|
|
62
62
|
*/
|
|
63
63
|
shebang?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Module names that should NOT be bundled. Each name remains as a literal
|
|
66
|
+
* `import`/`require` in the output and is resolved by the runtime against
|
|
67
|
+
* its own `node_modules` (or equivalent) at execution time.
|
|
68
|
+
*
|
|
69
|
+
* Repeat the flag or pass a comma-separated value:
|
|
70
|
+
* `--external typedoc,prettier --external typescript`. Glob-style wildcards
|
|
71
|
+
* (`@inquirer/*`, `lodash-*`) are forwarded as-is to esbuild.
|
|
72
|
+
*
|
|
73
|
+
* @see https://esbuild.github.io/api/#external
|
|
74
|
+
*/
|
|
75
|
+
external?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Substitute compile-time constants in the bundle. Each entry is a
|
|
78
|
+
* `KEY=VALUE` pair where `VALUE` is an arbitrary JS expression — string
|
|
79
|
+
* literals must be quoted (`--define VERSION='"1.2.3"'`). Useful for
|
|
80
|
+
* upstream packages that read a build-time constant via
|
|
81
|
+
* `typeof __FOO__ !== 'undefined'`.
|
|
82
|
+
*
|
|
83
|
+
* @see https://esbuild.github.io/api/#define
|
|
84
|
+
*/
|
|
85
|
+
define?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Map module specifiers to alternative targets at bundle time. Each entry
|
|
88
|
+
* is `FROM=TO` where `FROM` is the imported package name and `TO` is the
|
|
89
|
+
* substitute (typically `@gjsify/empty` to drop a heavy dep that the test
|
|
90
|
+
* scenario never executes). Layered on top of the built-in alias map.
|
|
91
|
+
*/
|
|
92
|
+
alias?: string[];
|
|
64
93
|
}
|
package/src/types/config-data.ts
CHANGED
|
@@ -23,4 +23,9 @@ export interface ConfigData {
|
|
|
23
23
|
* Prepend GJS shebang to output and mark executable. See CliBuildOptions.
|
|
24
24
|
*/
|
|
25
25
|
shebang?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Extra module aliases layered on top of the built-in alias map.
|
|
28
|
+
* Comes from `gjsify build --alias FROM=TO`.
|
|
29
|
+
*/
|
|
30
|
+
aliases?: Record<string, string>;
|
|
26
31
|
}
|