@gjsify/vite-plugin-gjsify 0.4.36 → 0.4.38
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/index.js +175 -7
- package/package.json +7 -6
package/lib/index.js
CHANGED
|
@@ -28,7 +28,10 @@
|
|
|
28
28
|
// `aliasPlugin` from rolldown-plugin-gjsify is intentionally NOT used here
|
|
29
29
|
// (it is not part of that package's public API). Vite has a native
|
|
30
30
|
// `resolve.alias`, which is what the inline config hook below sets.
|
|
31
|
-
import {
|
|
31
|
+
import { createRequire } from 'node:module';
|
|
32
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
33
|
+
import * as nodePath from 'node:path';
|
|
34
|
+
import { gjsImportsEmptyPlugin, platformResolvePlugin, detectNativescriptPlatform, nativescriptPlatformDefines, } from '@gjsify/rolldown-plugin-gjsify';
|
|
32
35
|
import blueprintPlugin from '@gjsify/vite-plugin-blueprint';
|
|
33
36
|
import { deepkitPlugin } from '@gjsify/rolldown-plugin-deepkit';
|
|
34
37
|
import { ALIASES_NODE_FOR_NATIVESCRIPT } from '@gjsify/resolve-npm';
|
|
@@ -99,6 +102,153 @@ export function gjsifyBrowser(options = {}) {
|
|
|
99
102
|
];
|
|
100
103
|
}
|
|
101
104
|
export default gjsifyBrowser;
|
|
105
|
+
/**
|
|
106
|
+
* `@nativescript/core`'s CSS parser pulls in `css-tree`, whose data modules
|
|
107
|
+
* (`data.js` / `data-patch.js` / `version.js`) load JSON via
|
|
108
|
+
* `createRequire(import.meta.url)('mdn-data/*.json' | '../package.json')` at
|
|
109
|
+
* module-evaluation time. Rolldown can't statically resolve those dynamic
|
|
110
|
+
* requires, so they survive into the bundle and throw on the NativeScript V8
|
|
111
|
+
* runtime ("Module evaluation promise rejected") — crashing every NS app that
|
|
112
|
+
* uses `@nativescript/core`'s styling. css-tree ships a self-contained
|
|
113
|
+
* `dist/csstree.esm.js` with the data inlined (no `createRequire`); aliasing the
|
|
114
|
+
* bare `css-tree` specifier to it keeps those requires out of the bundle.
|
|
115
|
+
*
|
|
116
|
+
* Resolved from the consuming project (`css-tree` is `@nativescript/core`'s
|
|
117
|
+
* transitive dep, not a direct one here). Returns no alias when css-tree isn't
|
|
118
|
+
* installed — a non-NS-core consumer keeps resolving `css-tree` normally.
|
|
119
|
+
*/
|
|
120
|
+
function nativescriptCssTreeAlias(fromDir) {
|
|
121
|
+
try {
|
|
122
|
+
const require = createRequire(import.meta.url);
|
|
123
|
+
return { 'css-tree': require.resolve('css-tree/dist/csstree.esm', { paths: [fromDir] }) };
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Collect the barrel modules referenced from the app's XML via `xmlns="~/MOD"`
|
|
131
|
+
* that `@nativescript/vite`'s `ns-bundler-context` does NOT register — i.e. those
|
|
132
|
+
* with no paired `.xml` sibling. Returns the NS nickname + a root-relative import
|
|
133
|
+
* specifier for each.
|
|
134
|
+
*/
|
|
135
|
+
function collectXmlnsBarrels(appDir, root) {
|
|
136
|
+
const xmlFiles = [];
|
|
137
|
+
const walk = (dir) => {
|
|
138
|
+
let entries;
|
|
139
|
+
try {
|
|
140
|
+
entries = readdirSync(dir);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
for (const entry of entries) {
|
|
146
|
+
const full = nodePath.join(dir, entry);
|
|
147
|
+
let isDir;
|
|
148
|
+
try {
|
|
149
|
+
isDir = statSync(full).isDirectory();
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (isDir)
|
|
155
|
+
walk(full);
|
|
156
|
+
else if (full.endsWith('.xml'))
|
|
157
|
+
xmlFiles.push(full);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
walk(appDir);
|
|
161
|
+
const names = new Set();
|
|
162
|
+
const xmlnsRe = /xmlns:[\w-]+\s*=\s*["']~\/([^"']+)["']/g;
|
|
163
|
+
for (const file of xmlFiles) {
|
|
164
|
+
let src;
|
|
165
|
+
try {
|
|
166
|
+
src = readFileSync(file, 'utf8');
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
for (const match of src.matchAll(xmlnsRe)) {
|
|
172
|
+
names.add(match[1].replace(/\/+$/, ''));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const barrels = [];
|
|
176
|
+
for (const name of names) {
|
|
177
|
+
// ns-bundler-context already registers any module that has an `.xml` sibling.
|
|
178
|
+
if (existsSync(nodePath.join(appDir, `${name}.xml`)))
|
|
179
|
+
continue;
|
|
180
|
+
const file = ['.ts', '.js', '/index.ts', '/index.js']
|
|
181
|
+
.map((suffix) => nodePath.join(appDir, `${name}${suffix}`))
|
|
182
|
+
.find((candidate) => existsSync(candidate));
|
|
183
|
+
if (!file)
|
|
184
|
+
continue;
|
|
185
|
+
const spec = '/' + nodePath.relative(root, file).split(nodePath.sep).join('/');
|
|
186
|
+
barrels.push({ name, spec });
|
|
187
|
+
}
|
|
188
|
+
return barrels;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Register barrel modules referenced from XML via `xmlns` namespaces, which
|
|
192
|
+
* `@nativescript/vite`'s `ns-bundler-context` leaves unregistered.
|
|
193
|
+
*
|
|
194
|
+
* NativeScript resolves a custom element — e.g. `<w:SourceView>` declared with
|
|
195
|
+
* `xmlns:w="~/widgets/index"` — at runtime via `global.loadModule("widgets/index")`,
|
|
196
|
+
* a lookup in the registry populated by `registerModule` / `registerBundlerModules`.
|
|
197
|
+
* `ns-bundler-context` registers every XML file, its paired code-behind and CSS,
|
|
198
|
+
* but deliberately NOT standalone barrels (`index.ts` with no `.xml` sibling). So a
|
|
199
|
+
* barrel reachable only via `xmlns` (`~/widgets/index`, `~/mdx/index`) is never
|
|
200
|
+
* registered; an ESM bundle has no `global.require` fallback, so `loadModule(...)`
|
|
201
|
+
* returns `null` → "Module 'SourceView' not found". `@nativescript/webpack`'s
|
|
202
|
+
* `xml-namespace-loader` registered every `.ts`, so these resolved for free there —
|
|
203
|
+
* this plugin reproduces that behaviour for the Vite build.
|
|
204
|
+
*
|
|
205
|
+
* It augments `@nativescript/vite`'s generated `virtual:ns-bundler-context` module
|
|
206
|
+
* (guaranteed imported early, before `Application.run`) by prepending a namespace
|
|
207
|
+
* import of each missing barrel and appending matching `registerModule` calls. The
|
|
208
|
+
* barrels enter the bundle via the added imports; registration runs right after the
|
|
209
|
+
* upstream `registerBundlerModules`.
|
|
210
|
+
*/
|
|
211
|
+
function nativescriptXmlnsBarrelsPlugin() {
|
|
212
|
+
const BUNDLER_CONTEXT_ID = '\0virtual:ns-bundler-context';
|
|
213
|
+
let root = process.cwd();
|
|
214
|
+
let appDir;
|
|
215
|
+
return {
|
|
216
|
+
name: 'gjsify-nativescript-xmlns-barrels',
|
|
217
|
+
configResolved(config) {
|
|
218
|
+
root = config.root || process.cwd();
|
|
219
|
+
// `~/` maps to the NativeScript app directory (`appPath`, default `app`;
|
|
220
|
+
// `src` is the other common layout). Probe both; XML lives under it.
|
|
221
|
+
appDir = ['app', 'src'].map((dir) => nodePath.join(root, dir)).find((dir) => existsSync(dir));
|
|
222
|
+
},
|
|
223
|
+
transform(code, id) {
|
|
224
|
+
if (id !== BUNDLER_CONTEXT_ID || !appDir)
|
|
225
|
+
return null;
|
|
226
|
+
const barrels = collectXmlnsBarrels(appDir, root);
|
|
227
|
+
if (barrels.length === 0)
|
|
228
|
+
return null;
|
|
229
|
+
const imports = barrels
|
|
230
|
+
.map((barrel, i) => `import * as __gjsifyXmlnsBarrel${i} from ${JSON.stringify(barrel.spec)};`)
|
|
231
|
+
.join('\n');
|
|
232
|
+
const registrations = barrels
|
|
233
|
+
.map((barrel, i) => ` global.registerModule(${JSON.stringify(barrel.name)}, () => __gjsifyXmlnsBarrel${i});`)
|
|
234
|
+
.join('\n');
|
|
235
|
+
const footer = [
|
|
236
|
+
'',
|
|
237
|
+
';(function () {',
|
|
238
|
+
' try {',
|
|
239
|
+
" if (typeof global !== 'undefined' && typeof global.registerModule === 'function') {",
|
|
240
|
+
registrations,
|
|
241
|
+
' }',
|
|
242
|
+
' } catch (e) {',
|
|
243
|
+
" try { console.warn('[gjsify-nativescript] xmlns barrel registration failed', e); } catch (_) {}",
|
|
244
|
+
' }',
|
|
245
|
+
'})();',
|
|
246
|
+
'',
|
|
247
|
+
].join('\n');
|
|
248
|
+
return { code: `${imports}\n${code}${footer}`, map: null };
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
102
252
|
/**
|
|
103
253
|
* Returns the Vite plugin array that brings `gjsify build --app nativescript`'s
|
|
104
254
|
* NS-target transforms to a Vite project (dev + build). Spread it into a
|
|
@@ -124,23 +274,32 @@ export function gjsifyNativescript(options = {}) {
|
|
|
124
274
|
nodePrefixAliases[bare] = target;
|
|
125
275
|
nodePrefixAliases[`node:${bare}`] = target;
|
|
126
276
|
}
|
|
127
|
-
const alias = {
|
|
128
|
-
...nodePrefixAliases,
|
|
129
|
-
...options.aliases,
|
|
130
|
-
};
|
|
131
277
|
const optimizeDepsExclude = ['@gjsify/unit', ...(options.optimizeDepsExclude ?? [])];
|
|
278
|
+
// Target platform from the env NS' CLI sets when it spawns the bundler
|
|
279
|
+
// (else `undefined` → `.native`-only resolution + neutral defines).
|
|
280
|
+
const platform = detectNativescriptPlatform();
|
|
132
281
|
const configPlugin = {
|
|
133
282
|
name: 'gjsify-nativescript-config',
|
|
134
|
-
config() {
|
|
283
|
+
config(userConfig, env) {
|
|
284
|
+
// `__DEV__` tracks Vite's mode (dev server vs `vite build`).
|
|
285
|
+
const dev = env?.mode !== 'production';
|
|
286
|
+
// Resolve css-tree from the project root (its dist is the consumer's
|
|
287
|
+
// transitive dep). User `aliases` are merged last so they win.
|
|
288
|
+
const root = userConfig?.root ?? process.cwd();
|
|
135
289
|
return {
|
|
136
290
|
resolve: {
|
|
137
|
-
alias,
|
|
291
|
+
alias: { ...nodePrefixAliases, ...nativescriptCssTreeAlias(root), ...options.aliases },
|
|
138
292
|
conditions: ['import', 'nativescript'],
|
|
139
293
|
mainFields: ['nativescript', 'module', 'main'],
|
|
140
294
|
},
|
|
141
295
|
define: {
|
|
142
296
|
global: 'globalThis',
|
|
143
297
|
// NO `window` define — NS apps have no DOM
|
|
298
|
+
//
|
|
299
|
+
// Standard NS compile-time platform flags, matching the
|
|
300
|
+
// Rolldown `--app nativescript` factory + the globals
|
|
301
|
+
// `@nativescript/vite` seeds in its main entry.
|
|
302
|
+
...nativescriptPlatformDefines(platform, { dev }),
|
|
144
303
|
},
|
|
145
304
|
build: {
|
|
146
305
|
target: 'esnext',
|
|
@@ -153,6 +312,15 @@ export function gjsifyNativescript(options = {}) {
|
|
|
153
312
|
};
|
|
154
313
|
return [
|
|
155
314
|
gjsImportsEmptyPlugin(),
|
|
315
|
+
// Platform-specific source variants (`*.android` / `*.ios` /
|
|
316
|
+
// `*.native`). A `resolveId` HOOK, NOT a `resolve.alias` — so it works
|
|
317
|
+
// under Vite 8 / Rolldown, where @nativescript/vite's function-based
|
|
318
|
+
// alias for the same feature is rejected.
|
|
319
|
+
platformResolvePlugin({ platform }),
|
|
320
|
+
// Register `xmlns`-referenced barrel modules that @nativescript/vite's
|
|
321
|
+
// ns-bundler-context leaves unregistered (its tree-shaking gap for
|
|
322
|
+
// barrels with no `.xml` sibling). Reproduces webpack's xml-namespace-loader.
|
|
323
|
+
nativescriptXmlnsBarrelsPlugin(),
|
|
156
324
|
// NO blueprintPlugin — Blueprint is GTK-specific
|
|
157
325
|
// NO cssAsStringPlugin — NS handles CSS via @nativescript/core
|
|
158
326
|
deepkitPlugin({ reflection: options.reflection }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/vite-plugin-gjsify",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.38",
|
|
4
4
|
"description": "Vite plugin presets mirroring `gjsify build --app browser` / `--app nativescript` — dev (Vite/HMR) parity with the gjsify CLI targets.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -39,10 +39,11 @@
|
|
|
39
39
|
],
|
|
40
40
|
"license": "MIT",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@gjsify/
|
|
43
|
-
"@gjsify/
|
|
44
|
-
"@gjsify/rolldown-plugin-
|
|
45
|
-
"@gjsify/
|
|
42
|
+
"@gjsify/empty": "^0.4.38",
|
|
43
|
+
"@gjsify/resolve-npm": "^0.4.38",
|
|
44
|
+
"@gjsify/rolldown-plugin-deepkit": "^0.4.38",
|
|
45
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.4.38",
|
|
46
|
+
"@gjsify/vite-plugin-blueprint": "^0.4.38"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"vite": "^8.0.14"
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
57
|
"@types/node": "^25.9.1",
|
|
57
|
-
"typescript": "^
|
|
58
|
+
"typescript": "^6.0.3",
|
|
58
59
|
"vite": "^8.0.14"
|
|
59
60
|
}
|
|
60
61
|
}
|