@gjsify/rolldown-plugin-gjsify 0.4.27 → 0.4.29
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/app/browser.js +2 -2
- package/lib/app/gjs.js +6 -10
- package/lib/app/node.js +4 -8
- package/lib/index.d.ts +2 -2
- package/lib/library/lib.js +2 -2
- package/lib/plugins/alias.js +0 -1
- package/lib/plugins/css-as-string.d.ts +2 -1
- package/lib/plugins/css-as-string.js +2 -1
- package/lib/plugins/gjs-imports-empty.js +15 -1
- package/lib/plugins/text-loader.d.ts +7 -4
- package/lib/plugins/text-loader.js +58 -12
- package/lib/shims/console-gjs.js +29 -5
- package/lib/utils/alias.js +8 -8
- package/lib/utils/auto-globals.js +7 -6
- package/lib/utils/detect-free-globals.js +1 -5
- package/lib/utils/extension.js +8 -1
- package/lib/utils/inline-static-reads.js +11 -9
- package/lib/utils/merge.js +4 -1
- package/package.json +7 -7
package/lib/app/browser.js
CHANGED
|
@@ -29,8 +29,8 @@ export const setupForBrowser = async (input) => {
|
|
|
29
29
|
};
|
|
30
30
|
const aliasMap = {
|
|
31
31
|
...browserPolyfillAliases,
|
|
32
|
-
...
|
|
33
|
-
...
|
|
32
|
+
...input.pluginOptions.aliases,
|
|
33
|
+
...input.userAliases,
|
|
34
34
|
};
|
|
35
35
|
const options = {
|
|
36
36
|
input: entryPoints,
|
package/lib/app/gjs.js
CHANGED
|
@@ -15,7 +15,7 @@ import { deepkitPlugin } from '@gjsify/rolldown-plugin-deepkit';
|
|
|
15
15
|
import blueprintPlugin from '@gjsify/vite-plugin-blueprint';
|
|
16
16
|
import { getAliasesForGjs } from '../utils/alias.js';
|
|
17
17
|
import { globToEntryPoints } from '../utils/entry-points.js';
|
|
18
|
-
import { nodeModulesPathRewritePlugin, getBundleDirFromOutput
|
|
18
|
+
import { nodeModulesPathRewritePlugin, getBundleDirFromOutput } from '../plugins/rewrite-node-modules-paths.js';
|
|
19
19
|
import { processStubPlugin } from '../plugins/process-stub.js';
|
|
20
20
|
import { cssAsStringPlugin } from '../plugins/css-as-string.js';
|
|
21
21
|
import { shebangPlugin, resolveShebangLine, inputShebangStripPlugin } from '../plugins/shebang.js';
|
|
@@ -77,8 +77,8 @@ export const setupForGjs = async (input) => {
|
|
|
77
77
|
const aliasMap = {
|
|
78
78
|
...getAliasesForGjs({ external }),
|
|
79
79
|
'unicorn-magic': unicornMagicShim,
|
|
80
|
-
...
|
|
81
|
-
...
|
|
80
|
+
...input.pluginOptions.aliases,
|
|
81
|
+
...input.userAliases,
|
|
82
82
|
};
|
|
83
83
|
// The console shim replaces all `console` references with print()/printerr()-
|
|
84
84
|
// based implementations that bypass GLib.log_structured() — no prefix,
|
|
@@ -91,9 +91,7 @@ export const setupForGjs = async (input) => {
|
|
|
91
91
|
// resolution lands at a non-existent location. Walk up via
|
|
92
92
|
// createRequire's node_modules-aware resolver as a fallback.
|
|
93
93
|
const consoleShimEnabled = input.pluginOptions.consoleShim !== false;
|
|
94
|
-
const consoleShimPath = consoleShimEnabled
|
|
95
|
-
? resolveConsoleShim()
|
|
96
|
-
: null;
|
|
94
|
+
const consoleShimPath = consoleShimEnabled ? resolveConsoleShim() : null;
|
|
97
95
|
// The auto-globals inject stub (when present) is side-effect-imported
|
|
98
96
|
// via a virtual entry — its register modules write to globalThis, so
|
|
99
97
|
// the import chain matters but no name binding does. We can't use
|
|
@@ -239,9 +237,7 @@ function wrapInputWithSideEffects(input, sideEffects) {
|
|
|
239
237
|
}
|
|
240
238
|
wrappedInput = out;
|
|
241
239
|
}
|
|
242
|
-
const sideEffectImports = sideEffects
|
|
243
|
-
.map((p) => `import ${JSON.stringify(p)};`)
|
|
244
|
-
.join('\n');
|
|
240
|
+
const sideEffectImports = sideEffects.map((p) => `import ${JSON.stringify(p)};`).join('\n');
|
|
245
241
|
// Resolved real-path targets from `userEntries` get their
|
|
246
242
|
// moduleSideEffects forced to 'no-treeshake' so the user-entry's
|
|
247
243
|
// top-level body (`run({...})`, side-effect calls) survives tree-shake
|
|
@@ -249,7 +245,7 @@ function wrapInputWithSideEffects(input, sideEffects) {
|
|
|
249
245
|
const resolvedTargets = new Set();
|
|
250
246
|
const plugin = {
|
|
251
247
|
name: 'gjsify-virtual-entry',
|
|
252
|
-
async resolveId(source,
|
|
248
|
+
async resolveId(source, _importer) {
|
|
253
249
|
if (source.startsWith(PREFIX))
|
|
254
250
|
return source;
|
|
255
251
|
// Force-mark the resolved user-entry target as having
|
package/lib/app/node.js
CHANGED
|
@@ -9,7 +9,7 @@ import { deepkitPlugin } from '@gjsify/rolldown-plugin-deepkit';
|
|
|
9
9
|
import { EXTERNALS_NODE } from '@gjsify/resolve-npm';
|
|
10
10
|
import { getAliasesForNode } from '../utils/alias.js';
|
|
11
11
|
import { globToEntryPoints } from '../utils/entry-points.js';
|
|
12
|
-
import { nodeModulesPathRewritePlugin, getBundleDirFromOutput
|
|
12
|
+
import { nodeModulesPathRewritePlugin, getBundleDirFromOutput } from '../plugins/rewrite-node-modules-paths.js';
|
|
13
13
|
import { cssAsStringPlugin } from '../plugins/css-as-string.js';
|
|
14
14
|
export const setupForNode = async (input) => {
|
|
15
15
|
const userExternal = input.userExternal ?? [];
|
|
@@ -21,11 +21,7 @@ export const setupForNode = async (input) => {
|
|
|
21
21
|
// way esbuild's did (`gi://*`, `@girs/*`). We use a function predicate
|
|
22
22
|
// instead so the gi:// URI scheme and the @girs/ namespace are matched
|
|
23
23
|
// by prefix.
|
|
24
|
-
const exactExternal = [
|
|
25
|
-
...EXTERNALS_NODE,
|
|
26
|
-
'node-datachannel',
|
|
27
|
-
...userExternal,
|
|
28
|
-
];
|
|
24
|
+
const exactExternal = [...EXTERNALS_NODE, 'node-datachannel', ...userExternal];
|
|
29
25
|
const external = (id) => {
|
|
30
26
|
if (id.startsWith('gi://'))
|
|
31
27
|
return true;
|
|
@@ -40,8 +36,8 @@ export const setupForNode = async (input) => {
|
|
|
40
36
|
const entryPoints = await globToEntryPoints(input.input, exclude);
|
|
41
37
|
const aliasMap = {
|
|
42
38
|
...getAliasesForNode({ external }),
|
|
43
|
-
...
|
|
44
|
-
...
|
|
39
|
+
...input.pluginOptions.aliases,
|
|
40
|
+
...input.userAliases,
|
|
45
41
|
};
|
|
46
42
|
const bundleDir = getBundleDirFromOutput(input.output);
|
|
47
43
|
// Rolldown's CJS interop wraps bundled CJS via `__commonJSMin` and
|
package/lib/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ export * from './utils/index.js';
|
|
|
3
3
|
export * from './app/index.js';
|
|
4
4
|
export * from './library/index.js';
|
|
5
5
|
export { REWRITE_FILTER, getBundleDirFromOutput, rewriteContents, shouldRewrite, nodeModulesPathRewritePlugin, } from './plugins/rewrite-node-modules-paths.js';
|
|
6
|
-
export type { NodeModulesPathRewriteOptions, RewriteResult
|
|
6
|
+
export type { NodeModulesPathRewriteOptions, RewriteResult } from './plugins/rewrite-node-modules-paths.js';
|
|
7
7
|
export { processStubPlugin, GJS_PROCESS_STUB, composeBanner } from './plugins/process-stub.js';
|
|
8
8
|
export type { ProcessStubPluginOptions } from './plugins/process-stub.js';
|
|
9
9
|
export { cssAsStringPlugin } from './plugins/css-as-string.js';
|
|
10
10
|
export { textLoaderPlugin } from './plugins/text-loader.js';
|
|
11
|
-
export type { TextLoaderPluginOptions } from './plugins/text-loader.js';
|
|
11
|
+
export type { TextLoaderPluginOptions, LoaderKind } from './plugins/text-loader.js';
|
|
12
12
|
export { shebangPlugin, GJS_SHEBANG, NODE_SHEBANG, expandEnvTemplate, resolveShebangLine } from './plugins/shebang.js';
|
|
13
13
|
export type { ShebangPluginOptions } from './plugins/shebang.js';
|
|
14
14
|
export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
|
package/lib/library/lib.js
CHANGED
|
@@ -27,8 +27,8 @@ export const setupLib = async (input) => {
|
|
|
27
27
|
// which doesn't match the package.json `exports` map.
|
|
28
28
|
const preserveModulesRoot = computeCommonRoot(entryPoints);
|
|
29
29
|
const aliasMap = {
|
|
30
|
-
...
|
|
31
|
-
...
|
|
30
|
+
...input.pluginOptions.aliases,
|
|
31
|
+
...input.userAliases,
|
|
32
32
|
};
|
|
33
33
|
// Library mode keeps all third-party / workspace imports as-is so the
|
|
34
34
|
// emitted package re-exports its dep tree by reference. Rolldown's
|
package/lib/plugins/alias.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from 'rolldown';
|
|
2
|
+
import type { Targets } from 'lightningcss';
|
|
2
3
|
export interface CssAsStringOptions {
|
|
3
4
|
/**
|
|
4
5
|
* lightningcss browser targets passed to `bundleAsync`. When set,
|
|
@@ -7,7 +8,7 @@ export interface CssAsStringOptions {
|
|
|
7
8
|
* match the GTK4 CSS parser. Omit or leave undefined to skip
|
|
8
9
|
* lowering (output stays as-authored except for `@import` inlining).
|
|
9
10
|
*/
|
|
10
|
-
targets?:
|
|
11
|
+
targets?: Targets;
|
|
11
12
|
/**
|
|
12
13
|
* When true (default), `@import` statements are resolved by
|
|
13
14
|
* lightningcss `bundleAsync`. Set false to fall back to a plain
|
|
@@ -41,7 +41,8 @@ import { dirname, isAbsolute, resolve as resolvePath } from 'node:path';
|
|
|
41
41
|
import { pathToFileURL } from 'node:url';
|
|
42
42
|
let _bundlerPromise = null;
|
|
43
43
|
async function pickBundler() {
|
|
44
|
-
const forced = globalThis.process?.env
|
|
44
|
+
const forced = globalThis.process?.env
|
|
45
|
+
?.GJSIFY_CSS_BACKEND;
|
|
45
46
|
if (forced === 'npm')
|
|
46
47
|
return loadNpmBundler();
|
|
47
48
|
if (forced === 'native') {
|
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
// Marking them external would leave bare specifiers in the bundle that the
|
|
7
7
|
// browser cannot resolve at runtime; instead we resolve them to a virtual
|
|
8
8
|
// empty ESM module so the bundle is self-contained.
|
|
9
|
+
//
|
|
10
|
+
// Portability note: the `filter: { id: ... }` below is a Rolldown fast-path
|
|
11
|
+
// — Rolldown pre-filters which specifiers reach `handler`. Under Vite (which
|
|
12
|
+
// also runs Rolldown for `build` but does NOT honor the Rolldown-specific
|
|
13
|
+
// hook-level `filter` in every code path, e.g. esbuild dep prebundle or the
|
|
14
|
+
// dev server) the handler may receive ALL ids. The internal guard below makes
|
|
15
|
+
// the plugin correct regardless of whether the filter pre-filtered — it is
|
|
16
|
+
// the load-bearing check; the `filter` is a defense-in-depth optimization.
|
|
9
17
|
const GJSIMPORTS_VIRTUAL_ID = '\0gjsify-empty-gjs-import';
|
|
10
18
|
export function gjsImportsEmptyPlugin() {
|
|
11
19
|
return {
|
|
@@ -13,7 +21,13 @@ export function gjsImportsEmptyPlugin() {
|
|
|
13
21
|
resolveId: {
|
|
14
22
|
order: 'pre',
|
|
15
23
|
filter: { id: /^(@girs\/|gi:\/\/)/ },
|
|
16
|
-
handler(
|
|
24
|
+
handler(source) {
|
|
25
|
+
// Internal guard: do not rely solely on the Rolldown `filter`
|
|
26
|
+
// above (it may not pre-filter under Vite). Only intercept
|
|
27
|
+
// `@girs/*` and `gi://*` specifiers; let everything else fall
|
|
28
|
+
// through to the default resolver chain.
|
|
29
|
+
if (!/^(@girs\/|gi:\/\/)/.test(source))
|
|
30
|
+
return null;
|
|
17
31
|
return { id: GJSIMPORTS_VIRTUAL_ID };
|
|
18
32
|
},
|
|
19
33
|
},
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { Plugin } from 'rolldown';
|
|
2
|
+
/** Loader kind values accepted under `gjsify.loaders`. */
|
|
3
|
+
export type LoaderKind = 'text' | 'dataurl';
|
|
2
4
|
export interface TextLoaderPluginOptions {
|
|
3
5
|
/**
|
|
4
|
-
* Map of file extension (with leading `.`) → loader kind.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Map of file extension (with leading `.`) → loader kind.
|
|
7
|
+
* `'text'` — file contents as JS string default export.
|
|
8
|
+
* `'dataurl'` — `data:<mime>;base64,<b64>` string default export.
|
|
9
|
+
* MIME inferred from extension (.png → image/png etc.).
|
|
7
10
|
*/
|
|
8
|
-
loaders?: Record<string,
|
|
11
|
+
loaders?: Record<string, LoaderKind>;
|
|
9
12
|
}
|
|
10
13
|
export declare function textLoaderPlugin(options?: TextLoaderPluginOptions): Plugin | null;
|
|
@@ -1,24 +1,56 @@
|
|
|
1
|
-
// Generic "load file as JS string default export" plugin.
|
|
1
|
+
// Generic "load file as JS string / data-URL default export" plugin.
|
|
2
2
|
//
|
|
3
3
|
// Mirrors `css-as-string` but lets the user opt-in arbitrary extensions
|
|
4
|
-
// through `
|
|
4
|
+
// through `gjsify.loaders` config, e.g.:
|
|
5
5
|
//
|
|
6
|
-
// "
|
|
6
|
+
// "loaders": { ".ui": "text", ".asm": "text", ".glsl": "text", ".png": "dataurl" }
|
|
7
7
|
//
|
|
8
|
-
// — replaces the esbuild `loader: { '.ui': 'text' }` shorthand
|
|
9
|
-
// pre-Rolldown era. Rolldown does not classify unknown extensions as text
|
|
8
|
+
// — replaces the esbuild `loader: { '.ui': 'text', '.png': 'dataurl' }` shorthand
|
|
9
|
+
// from the pre-Rolldown era. Rolldown does not classify unknown extensions as text
|
|
10
10
|
// by default; without a hook it tries to parse them as JS and fails.
|
|
11
|
+
//
|
|
12
|
+
// Loader kinds:
|
|
13
|
+
// 'text' — file contents as a JS string default export
|
|
14
|
+
// (`export default "…source…"`)
|
|
15
|
+
// 'dataurl' — file encoded as a data: URL string default export
|
|
16
|
+
// (`export default "data:<mime>;base64,<b64>"`)
|
|
17
|
+
// MIME is inferred from the file extension; falls back to
|
|
18
|
+
// `application/octet-stream` for unknown extensions.
|
|
19
|
+
// Useful for Excalibur's `ImageSource` constructor and similar
|
|
20
|
+
// libraries that want a data: URL rather than a separate asset.
|
|
11
21
|
import { readFile } from 'node:fs/promises';
|
|
22
|
+
/** MIME type lookup for common binary / shader formats. */
|
|
23
|
+
const MIME_BY_EXT = {
|
|
24
|
+
'.png': 'image/png',
|
|
25
|
+
'.jpg': 'image/jpeg',
|
|
26
|
+
'.jpeg': 'image/jpeg',
|
|
27
|
+
'.gif': 'image/gif',
|
|
28
|
+
'.webp': 'image/webp',
|
|
29
|
+
'.svg': 'image/svg+xml',
|
|
30
|
+
'.ico': 'image/x-icon',
|
|
31
|
+
'.avif': 'image/avif',
|
|
32
|
+
'.bmp': 'image/bmp',
|
|
33
|
+
'.tiff': 'image/tiff',
|
|
34
|
+
'.tif': 'image/tiff',
|
|
35
|
+
'.wasm': 'application/wasm',
|
|
36
|
+
};
|
|
37
|
+
function mimeForExtension(ext) {
|
|
38
|
+
return MIME_BY_EXT[ext.toLowerCase()] ?? 'application/octet-stream';
|
|
39
|
+
}
|
|
12
40
|
export function textLoaderPlugin(options = {}) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
41
|
+
const loaders = options.loaders ?? {};
|
|
42
|
+
const entries = Object.entries(loaders);
|
|
43
|
+
const textExts = entries.filter(([, kind]) => kind === 'text').map(([ext]) => ext);
|
|
44
|
+
const dataurlExts = entries.filter(([, kind]) => kind === 'dataurl').map(([ext]) => ext);
|
|
45
|
+
const allExts = [...textExts, ...dataurlExts];
|
|
46
|
+
if (allExts.length === 0)
|
|
17
47
|
return null;
|
|
18
48
|
// Build a single regex matching any of the configured extensions:
|
|
19
|
-
// ['.ui', '.asm'] → /\.(ui|asm)$/
|
|
20
|
-
const escaped =
|
|
49
|
+
// ['.ui', '.asm', '.png'] → /\.(ui|asm|png)$/
|
|
50
|
+
const escaped = allExts.map((e) => e.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
21
51
|
const filter = new RegExp(`\\.(?:${escaped.join('|')})$`);
|
|
52
|
+
// Index extensions → kind for fast lookup in the load hook.
|
|
53
|
+
const kindMap = new Map(entries.map(([ext, kind]) => [ext.toLowerCase(), kind]));
|
|
22
54
|
// Use the function-form `load(id)` (Rollup-compatible) rather than the
|
|
23
55
|
// newer `load: { filter, handler }` shape. The newer shape was observed
|
|
24
56
|
// not to claim unknown-extension files reliably under Rolldown rc.18 —
|
|
@@ -27,10 +59,24 @@ export function textLoaderPlugin(options = {}) {
|
|
|
27
59
|
// as `@gjsify/vite-plugin-blueprint`'s `.blp` hook) intercepts during
|
|
28
60
|
// module-load lookup and works under both Vite and Rolldown.
|
|
29
61
|
return {
|
|
30
|
-
name: 'gjsify-
|
|
62
|
+
name: 'gjsify-asset-loader',
|
|
31
63
|
async load(id) {
|
|
32
64
|
if (!filter.test(id))
|
|
33
65
|
return null;
|
|
66
|
+
// Determine the extension (lowercase, with leading dot).
|
|
67
|
+
const dotIdx = id.lastIndexOf('.');
|
|
68
|
+
const ext = dotIdx >= 0 ? id.slice(dotIdx).toLowerCase() : '';
|
|
69
|
+
const kind = kindMap.get(ext) ?? 'text';
|
|
70
|
+
if (kind === 'dataurl') {
|
|
71
|
+
const bytes = await readFile(id);
|
|
72
|
+
const mime = mimeForExtension(ext);
|
|
73
|
+
const b64 = bytes.toString('base64');
|
|
74
|
+
return {
|
|
75
|
+
code: `export default ${JSON.stringify(`data:${mime};base64,${b64}`)};`,
|
|
76
|
+
moduleType: 'js',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// kind === 'text'
|
|
34
80
|
const code = await readFile(id, 'utf8');
|
|
35
81
|
return {
|
|
36
82
|
code: `export default ${JSON.stringify(code)};`,
|
package/lib/shims/console-gjs.js
CHANGED
|
@@ -15,10 +15,34 @@
|
|
|
15
15
|
// `globalThis.console` untouched and routing user `console.log(…)` calls
|
|
16
16
|
// through our object.
|
|
17
17
|
// @ts-ignore — resolved by Rolldown at user-build time, not by tsc here.
|
|
18
|
-
import
|
|
18
|
+
import * as gjsConsole from '@gjsify/console';
|
|
19
|
+
// NOTE: a namespace import is used deliberately. It is a single statement that
|
|
20
|
+
// no formatter (oxfmt) can wrap across lines, so the `@ts-ignore` above always
|
|
21
|
+
// sits on the line immediately preceding the import and reliably suppresses the
|
|
22
|
+
// TS2307 (`@gjsify/console` is resolved by Rolldown at user-build time, not by
|
|
23
|
+
// tsc here). A multi-line named import would let the reformatter detach the
|
|
24
|
+
// suppression from the offending `from '@gjsify/console'` line.
|
|
19
25
|
export const console = {
|
|
20
|
-
log
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
log: gjsConsole.log,
|
|
27
|
+
info: gjsConsole.info,
|
|
28
|
+
debug: gjsConsole.debug,
|
|
29
|
+
warn: gjsConsole.warn,
|
|
30
|
+
error: gjsConsole.error,
|
|
31
|
+
dir: gjsConsole.dir,
|
|
32
|
+
dirxml: gjsConsole.dirxml,
|
|
33
|
+
table: gjsConsole.table,
|
|
34
|
+
time: gjsConsole.time,
|
|
35
|
+
timeEnd: gjsConsole.timeEnd,
|
|
36
|
+
timeLog: gjsConsole.timeLog,
|
|
37
|
+
trace: gjsConsole.trace,
|
|
38
|
+
assert: gjsConsole.assert,
|
|
39
|
+
clear: gjsConsole.clear,
|
|
40
|
+
count: gjsConsole.count,
|
|
41
|
+
countReset: gjsConsole.countReset,
|
|
42
|
+
group: gjsConsole.group,
|
|
43
|
+
groupCollapsed: gjsConsole.groupCollapsed,
|
|
44
|
+
groupEnd: gjsConsole.groupEnd,
|
|
45
|
+
profile: gjsConsole.profile,
|
|
46
|
+
profileEnd: gjsConsole.profileEnd,
|
|
47
|
+
timeStamp: gjsConsole.timeStamp,
|
|
24
48
|
};
|
package/lib/utils/alias.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EXTERNALS_NODE, EXTERNALS_NPM, ALIASES_GENERAL_FOR_GJS, ALIASES_NODE_FOR_GJS, ALIASES_WEB_FOR_GJS, ALIASES_GENERAL_FOR_NODE, ALIASES_GJS_FOR_NODE, ALIASES_WEB_FOR_NODE } from
|
|
1
|
+
import { EXTERNALS_NODE, EXTERNALS_NPM, ALIASES_GENERAL_FOR_GJS, ALIASES_NODE_FOR_GJS, ALIASES_WEB_FOR_GJS, ALIASES_GENERAL_FOR_NODE, ALIASES_GJS_FOR_NODE, ALIASES_WEB_FOR_NODE, } from '@gjsify/resolve-npm';
|
|
2
2
|
export const setNodeAliasPrefix = (ALIASES) => {
|
|
3
3
|
// Also resolve alias names with `node:${ALIAS}`
|
|
4
4
|
for (const ALIAS in ALIASES) {
|
|
@@ -11,12 +11,12 @@ export const setNodeAliasPrefix = (ALIASES) => {
|
|
|
11
11
|
}
|
|
12
12
|
return ALIASES;
|
|
13
13
|
};
|
|
14
|
-
const getAliasesGeneralForGjs = (
|
|
15
|
-
const getAliasesNodeForGjs = (
|
|
16
|
-
const getAliasesWebForGjs = (
|
|
17
|
-
const getAliasesGeneralForNode = (
|
|
18
|
-
const getAliasesGjsForNode = (
|
|
19
|
-
const getAliasesWebForNode = (
|
|
14
|
+
const getAliasesGeneralForGjs = (_options) => ALIASES_GENERAL_FOR_GJS;
|
|
15
|
+
const getAliasesNodeForGjs = (_options) => setNodeAliasPrefix(ALIASES_NODE_FOR_GJS);
|
|
16
|
+
const getAliasesWebForGjs = (_options) => ALIASES_WEB_FOR_GJS;
|
|
17
|
+
const getAliasesGeneralForNode = (_options) => ALIASES_GENERAL_FOR_NODE;
|
|
18
|
+
const getAliasesGjsForNode = (_options) => ALIASES_GJS_FOR_NODE;
|
|
19
|
+
const getAliasesWebForNode = (_options) => ALIASES_WEB_FOR_NODE;
|
|
20
20
|
export const getAliasesForGjs = (options) => {
|
|
21
21
|
return { ...getAliasesGeneralForGjs(options), ...getAliasesNodeForGjs(options), ...getAliasesWebForGjs(options) };
|
|
22
22
|
};
|
|
@@ -24,6 +24,6 @@ export const getAliasesForNode = (options) => {
|
|
|
24
24
|
return { ...getAliasesGeneralForNode(options), ...getAliasesGjsForNode(options), ...getAliasesWebForNode(options) };
|
|
25
25
|
};
|
|
26
26
|
/** Array of Node.js build in module names (also with node: prefix) */
|
|
27
|
-
export const externalNode = [...EXTERNALS_NODE, ...EXTERNALS_NODE.map(E => `node:${E}`)];
|
|
27
|
+
export const externalNode = [...EXTERNALS_NODE, ...EXTERNALS_NODE.map((E) => `node:${E}`)];
|
|
28
28
|
/** Array of NPM module names for which we have our own implementation */
|
|
29
29
|
export const externalNPM = [...EXTERNALS_NPM];
|
|
@@ -58,7 +58,7 @@ async function applyExcludeGlobals(detected, currentInject, extraRegisterPaths,
|
|
|
58
58
|
const filtered = detectedToRegisterPaths(detected);
|
|
59
59
|
for (const p of extraRegisterPaths)
|
|
60
60
|
filtered.add(p);
|
|
61
|
-
const injectPath = filtered.size > 0 ? (await writeRegisterInjectFile(filtered)) ?? undefined : undefined;
|
|
61
|
+
const injectPath = filtered.size > 0 ? ((await writeRegisterInjectFile(filtered)) ?? undefined) : undefined;
|
|
62
62
|
return { detected, injectPath };
|
|
63
63
|
}
|
|
64
64
|
function detectedToRegisterPaths(detected) {
|
|
@@ -150,9 +150,7 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
|
|
|
150
150
|
// shape: caller plugins first (PnP, user text-loaders), then the
|
|
151
151
|
// gjsify chain (which may be either a single RolldownPluginOption
|
|
152
152
|
// or an array of them depending on the factory shape).
|
|
153
|
-
const gjsifyPluginsArray = Array.isArray(gjsifyInstance)
|
|
154
|
-
? gjsifyInstance
|
|
155
|
-
: [gjsifyInstance];
|
|
153
|
+
const gjsifyPluginsArray = Array.isArray(gjsifyInstance) ? gjsifyInstance : [gjsifyInstance];
|
|
156
154
|
const chunkCodes = await bundler({
|
|
157
155
|
rolldownInput: {
|
|
158
156
|
input: inputWithInject,
|
|
@@ -181,7 +179,8 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
|
|
|
181
179
|
newDetected.add(id);
|
|
182
180
|
}
|
|
183
181
|
catch (e) {
|
|
184
|
-
if (globalThis.process?.env
|
|
182
|
+
if (globalThis.process?.env
|
|
183
|
+
?.GJSIFY_DEBUG_AUTO_GLOBALS) {
|
|
185
184
|
const path = `/tmp/gjsify-auto-globals-failed-chunk-${i}.mjs`;
|
|
186
185
|
try {
|
|
187
186
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -189,7 +188,9 @@ export async function detectAutoGlobals(analysisOptions, pluginOptions, gjsifyPl
|
|
|
189
188
|
fs.writeFileSync(path, code);
|
|
190
189
|
console.error(`[gjsify-auto-globals] parse failed on chunk #${i} — wrote ${path} for inspection`);
|
|
191
190
|
}
|
|
192
|
-
catch {
|
|
191
|
+
catch {
|
|
192
|
+
/* ignore */
|
|
193
|
+
}
|
|
193
194
|
}
|
|
194
195
|
throw e;
|
|
195
196
|
}
|
|
@@ -113,11 +113,7 @@ function extractBindingNames(node) {
|
|
|
113
113
|
? extractBindingNames(p.argument)
|
|
114
114
|
: extractBindingNames(p.value));
|
|
115
115
|
case 'ArrayPattern':
|
|
116
|
-
return node.elements.flatMap((e) => e
|
|
117
|
-
? e.type === 'RestElement'
|
|
118
|
-
? extractBindingNames(e.argument)
|
|
119
|
-
: extractBindingNames(e)
|
|
120
|
-
: []);
|
|
116
|
+
return node.elements.flatMap((e) => e ? (e.type === 'RestElement' ? extractBindingNames(e.argument) : extractBindingNames(e)) : []);
|
|
121
117
|
case 'AssignmentPattern':
|
|
122
118
|
return extractBindingNames(node.left);
|
|
123
119
|
case 'RestElement':
|
package/lib/utils/extension.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
export const getJsExtensions = (allowExt) => {
|
|
2
|
-
const extensions = {
|
|
2
|
+
const extensions = {
|
|
3
|
+
'.js': '.js',
|
|
4
|
+
'.ts': '.js',
|
|
5
|
+
'.mts': '.js',
|
|
6
|
+
'.cts': '.js',
|
|
7
|
+
'.cjs': '.js',
|
|
8
|
+
'.mjs': '.js',
|
|
9
|
+
};
|
|
3
10
|
if (allowExt && extensions[allowExt]) {
|
|
4
11
|
delete extensions[allowExt];
|
|
5
12
|
}
|
|
@@ -53,9 +53,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
|
53
53
|
* `readdirSync` / `existsSync` skip the AST parse entirely (cheap fast path).
|
|
54
54
|
*/
|
|
55
55
|
export function inlineStaticReads(src, sourceFilePath) {
|
|
56
|
-
if (!src.includes('readFileSync') &&
|
|
57
|
-
!src.includes('readdirSync') &&
|
|
58
|
-
!src.includes('existsSync')) {
|
|
56
|
+
if (!src.includes('readFileSync') && !src.includes('readdirSync') && !src.includes('existsSync')) {
|
|
59
57
|
return { contents: src, inlined: 0 };
|
|
60
58
|
}
|
|
61
59
|
let ast;
|
|
@@ -112,7 +110,7 @@ export function inlineStaticReads(src, sourceFilePath) {
|
|
|
112
110
|
* `undefined` if the call doesn't match an inlinable pattern or the path
|
|
113
111
|
* couldn't be resolved or the file doesn't exist.
|
|
114
112
|
*/
|
|
115
|
-
function tryInlineCall(node, ctx,
|
|
113
|
+
function tryInlineCall(node, ctx, _src) {
|
|
116
114
|
const callee = node.callee;
|
|
117
115
|
// `JSON.parse(readFileSync(<path>, "utf8"))` — collapse the whole
|
|
118
116
|
// composition. Recognising it specifically lets us emit a parsed-JSON
|
|
@@ -120,8 +118,10 @@ function tryInlineCall(node, ctx, src) {
|
|
|
120
118
|
// which esbuild can dead-code-eliminate against.
|
|
121
119
|
if (callee.type === 'MemberExpression' &&
|
|
122
120
|
!callee.computed &&
|
|
123
|
-
callee.object.type === 'Identifier' &&
|
|
124
|
-
callee.
|
|
121
|
+
callee.object.type === 'Identifier' &&
|
|
122
|
+
callee.object.name === 'JSON' &&
|
|
123
|
+
callee.property.type === 'Identifier' &&
|
|
124
|
+
callee.property.name === 'parse' &&
|
|
125
125
|
node.arguments.length >= 1 &&
|
|
126
126
|
node.arguments[0].type === 'CallExpression') {
|
|
127
127
|
const inner = node.arguments[0];
|
|
@@ -377,7 +377,7 @@ function evalExpr(node, ctx) {
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
const base = evalExpr(ne.arguments[1], ctx);
|
|
380
|
-
const baseStr = base instanceof URL ? base.href :
|
|
380
|
+
const baseStr = base instanceof URL ? base.href : typeof base === 'string' ? base : undefined;
|
|
381
381
|
if (!baseStr)
|
|
382
382
|
return undefined;
|
|
383
383
|
try {
|
|
@@ -394,7 +394,7 @@ function evalExpr(node, ctx) {
|
|
|
394
394
|
const name = identifierName(ce.callee);
|
|
395
395
|
if (name === 'fileURLToPath') {
|
|
396
396
|
const arg = evalExpr(ce.arguments[0], ctx);
|
|
397
|
-
const url = arg instanceof URL ? arg.href :
|
|
397
|
+
const url = arg instanceof URL ? arg.href : typeof arg === 'string' ? arg : undefined;
|
|
398
398
|
if (!url)
|
|
399
399
|
return undefined;
|
|
400
400
|
try {
|
|
@@ -471,7 +471,9 @@ function evalEncodingExpr(node) {
|
|
|
471
471
|
continue;
|
|
472
472
|
const key = p.key.type === 'Identifier'
|
|
473
473
|
? p.key.name
|
|
474
|
-
: p.key.type === 'Literal'
|
|
474
|
+
: p.key.type === 'Literal'
|
|
475
|
+
? String(p.key.value)
|
|
476
|
+
: undefined;
|
|
475
477
|
if (key !== 'encoding')
|
|
476
478
|
continue;
|
|
477
479
|
if (p.value.type === 'Literal' && typeof p.value.value === 'string') {
|
package/lib/utils/merge.js
CHANGED
|
@@ -19,5 +19,8 @@ export function merge(target, ...sources) {
|
|
|
19
19
|
return target;
|
|
20
20
|
}
|
|
21
21
|
function isPlainObject(val) {
|
|
22
|
-
return typeof val === 'object' &&
|
|
22
|
+
return (typeof val === 'object' &&
|
|
23
|
+
val !== null &&
|
|
24
|
+
!Array.isArray(val) &&
|
|
25
|
+
Object.getPrototypeOf(val) === Object.prototype);
|
|
23
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/rolldown-plugin-gjsify",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.29",
|
|
4
4
|
"description": "Rolldown / Rollup / Vite plugin orchestrator for GJS, Node, and Browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
],
|
|
49
49
|
"license": "MIT",
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@gjsify/console": "^0.4.
|
|
52
|
-
"@gjsify/resolve-npm": "^0.4.
|
|
53
|
-
"@gjsify/rolldown-plugin-deepkit": "^0.4.
|
|
54
|
-
"@gjsify/rolldown-plugin-pnp": "^0.4.
|
|
55
|
-
"@gjsify/vite-plugin-blueprint": "^0.4.
|
|
51
|
+
"@gjsify/console": "^0.4.29",
|
|
52
|
+
"@gjsify/resolve-npm": "^0.4.29",
|
|
53
|
+
"@gjsify/rolldown-plugin-deepkit": "^0.4.29",
|
|
54
|
+
"@gjsify/rolldown-plugin-pnp": "^0.4.29",
|
|
55
|
+
"@gjsify/vite-plugin-blueprint": "^0.4.29",
|
|
56
56
|
"@rollup/pluginutils": "^5.3.0",
|
|
57
57
|
"acorn": "^8.16.0",
|
|
58
58
|
"acorn-walk": "^8.3.5",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"lightningcss": "^1.32.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@gjsify/lightningcss-native": "^0.4.
|
|
63
|
+
"@gjsify/lightningcss-native": "^0.4.29",
|
|
64
64
|
"rolldown": "^1.0.0-rc.18"
|
|
65
65
|
},
|
|
66
66
|
"peerDependenciesMeta": {
|