@moostjs/vite 0.6.25 → 0.6.26
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 +5 -3
- package/dist/index.cjs +60 -25
- package/dist/index.mjs +60 -25
- package/dist/prod-server.cjs +1 -1
- package/dist/prod-server.mjs +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -101,6 +101,8 @@ moostVite({
|
|
|
101
101
|
})
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
Note that the production server generated by `vite build` defaults the prefix to `'/api'` when the option is omitted — set `prefix` explicitly so dev (where all requests pass through Moost without it) and prod route the same way.
|
|
105
|
+
|
|
104
106
|
## SSR Mode
|
|
105
107
|
|
|
106
108
|
Add `ssrEntry` to enable server-side rendering. The plugin handles everything automatically — SSR rendering in dev, multi-environment builds for production:
|
|
@@ -180,7 +182,7 @@ export default defineConfig({
|
|
|
180
182
|
|
|
181
183
|
**Don't externalize:** workspace packages (`workspace:*`), anything that uses `Symbol()` as a public slot key (Moost, wooks, atscript), anything not reliably hoisted by pnpm.
|
|
182
184
|
|
|
183
|
-
You can also opt out of bundle-everything by setting `ssr.noExternal` to an explicit list — the plugin honors it
|
|
185
|
+
You can also opt out of bundle-everything by setting `ssr.noExternal` to an explicit list — the plugin honors it, appending `/^@moostjs\/vite($|\/)/` (so its own `define:` substitutions still land) plus, unless you externalize the runtime yourself, the moost/wooks runtime patterns described below:
|
|
184
186
|
|
|
185
187
|
```ts
|
|
186
188
|
ssr: {
|
|
@@ -225,12 +227,12 @@ The plugin injects a `__VITE_ID` decorator on `@Injectable` and `@Controller` cl
|
|
|
225
227
|
| `host` | `string` | `'localhost'` | Dev server host (backend mode only) |
|
|
226
228
|
| `outDir` | `string` | `'dist'` | Build output directory (backend mode only) |
|
|
227
229
|
| `format` | `'cjs' \| 'esm'` | `'esm'` | Output module format (backend mode only) |
|
|
228
|
-
| `sourcemap` | `boolean` | `true` | Generate source maps (
|
|
230
|
+
| `sourcemap` | `boolean` | `true` | Generate source maps (both modes; in middleware mode applies to the `dist/server` SSR build) |
|
|
229
231
|
| `externals` | `boolean \| object` | `true` | Configure external dependencies (backend mode only) |
|
|
230
232
|
| `onEject` | `function` | — | Hook to control DI instance ejection during HMR |
|
|
231
233
|
| `ssrFetch` | `boolean` | `true` | Enable local fetch interception for SSR |
|
|
232
234
|
| `middleware` | `boolean` | `false` | Run Moost as Connect middleware (Vite serves frontend) |
|
|
233
|
-
| `prefix` | `string` |
|
|
235
|
+
| `prefix` | `string` | `'/api'` (prod server) | URL prefix filter for middleware mode (e.g. `'/api'`); the production server defaults to `'/api'` when omitted |
|
|
234
236
|
| `ssrEntry` | `string` | — | Vue/React SSR entry module (e.g. `'/src/entry-server.ts'`) |
|
|
235
237
|
| `ssrOutlet` | `string` | `'<!--ssr-outlet-->'` | HTML placeholder for SSR-rendered content |
|
|
236
238
|
| `ssrState` | `string` | `'<!--ssr-state-->'` | HTML placeholder for SSR state transfer script |
|
package/dist/index.cjs
CHANGED
|
@@ -379,6 +379,31 @@ function moostVite(options) {
|
|
|
379
379
|
* Drains any pending Moost app reload before a request is served. Assigned once
|
|
380
380
|
* the SSR module runner exists (see configureServer); a no-op until then.
|
|
381
381
|
*/ let drainReload = () => Promise.resolve();
|
|
382
|
+
/**
|
|
383
|
+
* Last Moost entry import failure. While set, the dev middleware answers matching
|
|
384
|
+
* requests with 502 instead of letting them fall through to the SPA/SSR fallback
|
|
385
|
+
* (which would serve index.html for API routes). Cleared on a successful reload;
|
|
386
|
+
* the next hot update schedules the retry.
|
|
387
|
+
*/ let bootError = null;
|
|
388
|
+
/**
|
|
389
|
+
* Looks up the Moost entry node with the verbatim `options.entry` string — the
|
|
390
|
+
* module graph keys (and memoizes) unresolved urls as-is, so the same spelling
|
|
391
|
+
* that was passed to `runner.import()` is guaranteed to return the very node
|
|
392
|
+
* that import created.
|
|
393
|
+
*/ const getEntryModule = (moduleGraph) => moduleGraph.getModuleByUrl(options.entry);
|
|
394
|
+
/**
|
|
395
|
+
* Drops the captured Moost app so the next request triggers a full reload:
|
|
396
|
+
* releases the middleware + local fetch and ejects DI instances affected by
|
|
397
|
+
* the changed modules.
|
|
398
|
+
*/ const ejectApp = (cleanupInstances) => {
|
|
399
|
+
moostMiddleware = null;
|
|
400
|
+
if (localFetchTeardown) {
|
|
401
|
+
localFetchTeardown();
|
|
402
|
+
localFetchTeardown = null;
|
|
403
|
+
}
|
|
404
|
+
moostRestartCleanup(adapters, options.onEject, cleanupInstances);
|
|
405
|
+
reloadRequired = true;
|
|
406
|
+
};
|
|
382
407
|
patchMoostHandlerLogging();
|
|
383
408
|
const pluginConfig = {
|
|
384
409
|
name: PLUGIN_NAME,
|
|
@@ -523,16 +548,27 @@ function moostVite(options) {
|
|
|
523
548
|
};
|
|
524
549
|
},
|
|
525
550
|
async configureServer(server) {
|
|
526
|
-
const runner = (0, vite.createServerModuleRunner)(server.environments.ssr);
|
|
551
|
+
const runner = (0, vite.createServerModuleRunner)(server.environments.ssr, { hmr: false });
|
|
527
552
|
const ssrImport = (id) => runner.import(id);
|
|
553
|
+
bootError = null;
|
|
554
|
+
reloadRequired = false;
|
|
555
|
+
reloadPromise = null;
|
|
528
556
|
const runReload = () => {
|
|
529
557
|
reloadRequired = false;
|
|
530
558
|
console.log();
|
|
531
559
|
logger.debug("🚀 Reloading Moost App...");
|
|
532
560
|
console.log();
|
|
533
561
|
return (async () => {
|
|
534
|
-
|
|
535
|
-
|
|
562
|
+
try {
|
|
563
|
+
for (const adapter of adapters) if (adapter.detected) await adapter.init();
|
|
564
|
+
const entryModule = await getEntryModule(server.environments.ssr.moduleGraph);
|
|
565
|
+
if (entryModule?.transformResult) server.environments.ssr.moduleGraph.invalidateModule(entryModule);
|
|
566
|
+
await ssrImport(options.entry);
|
|
567
|
+
bootError = null;
|
|
568
|
+
} catch (error) {
|
|
569
|
+
bootError = error;
|
|
570
|
+
logger.error(`✖️ Failed to reload Moost App: ${error.message}`);
|
|
571
|
+
}
|
|
536
572
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
537
573
|
})().finally(() => {
|
|
538
574
|
reloadPromise = null;
|
|
@@ -561,30 +597,29 @@ function moostVite(options) {
|
|
|
561
597
|
}
|
|
562
598
|
return moostMiddleware(req, res);
|
|
563
599
|
}
|
|
600
|
+
if (bootError) {
|
|
601
|
+
res.statusCode = 502;
|
|
602
|
+
res.setHeader("Content-Type", "text/plain");
|
|
603
|
+
res.end(`Moost app failed to load: ${bootError.message}`);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
564
606
|
next();
|
|
565
607
|
});
|
|
566
608
|
},
|
|
567
|
-
hotUpdate({ file }) {
|
|
568
|
-
if (
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
localFetchTeardown = null;
|
|
582
|
-
}
|
|
583
|
-
moostRestartCleanup(adapters, options.onEject, cleanupInstances);
|
|
584
|
-
reloadRequired = true;
|
|
585
|
-
}
|
|
586
|
-
return [];
|
|
587
|
-
}
|
|
609
|
+
async hotUpdate({ file, modules }) {
|
|
610
|
+
if (this.environment.name !== "ssr" || modules.length === 0) return;
|
|
611
|
+
const { moduleGraph } = this.environment;
|
|
612
|
+
const entryModule = await getEntryModule(moduleGraph);
|
|
613
|
+
const importerSets = modules.map((mod) => gatherAllImporters(mod));
|
|
614
|
+
if (entryModule && !importerSets.some((importers) => importers.has(entryModule))) return;
|
|
615
|
+
logger.debug(`🔃 Hot update: ${file}`);
|
|
616
|
+
const cleanupInstances = /* @__PURE__ */ new Set();
|
|
617
|
+
for (const importers of importerSets) for (const impModule of importers) if (impModule.id) cleanupInstances.add(impModule.id);
|
|
618
|
+
for (const mod of modules) moduleGraph.invalidateModule(mod);
|
|
619
|
+
if (entryModule) moduleGraph.invalidateModule(entryModule);
|
|
620
|
+
else moduleGraph.invalidateAll();
|
|
621
|
+
ejectApp(cleanupInstances);
|
|
622
|
+
return [];
|
|
588
623
|
}
|
|
589
624
|
};
|
|
590
625
|
if (isProd || isTest) {
|
|
@@ -606,7 +641,7 @@ function moostVite(options) {
|
|
|
606
641
|
const url = req.originalUrl || req.url || "/";
|
|
607
642
|
try {
|
|
608
643
|
await drainReload();
|
|
609
|
-
let template = await fs.readFile((0, node_path.resolve)(
|
|
644
|
+
let template = await fs.readFile((0, node_path.resolve)(server.config.root, "index.html"), "utf8");
|
|
610
645
|
template = await server.transformIndexHtml(url, template);
|
|
611
646
|
const { render } = await server.ssrLoadModule(options.ssrEntry);
|
|
612
647
|
const { html: appHtml, state } = await render(url);
|
package/dist/index.mjs
CHANGED
|
@@ -348,6 +348,31 @@ function moostVite(options) {
|
|
|
348
348
|
* Drains any pending Moost app reload before a request is served. Assigned once
|
|
349
349
|
* the SSR module runner exists (see configureServer); a no-op until then.
|
|
350
350
|
*/ let drainReload = () => Promise.resolve();
|
|
351
|
+
/**
|
|
352
|
+
* Last Moost entry import failure. While set, the dev middleware answers matching
|
|
353
|
+
* requests with 502 instead of letting them fall through to the SPA/SSR fallback
|
|
354
|
+
* (which would serve index.html for API routes). Cleared on a successful reload;
|
|
355
|
+
* the next hot update schedules the retry.
|
|
356
|
+
*/ let bootError = null;
|
|
357
|
+
/**
|
|
358
|
+
* Looks up the Moost entry node with the verbatim `options.entry` string — the
|
|
359
|
+
* module graph keys (and memoizes) unresolved urls as-is, so the same spelling
|
|
360
|
+
* that was passed to `runner.import()` is guaranteed to return the very node
|
|
361
|
+
* that import created.
|
|
362
|
+
*/ const getEntryModule = (moduleGraph) => moduleGraph.getModuleByUrl(options.entry);
|
|
363
|
+
/**
|
|
364
|
+
* Drops the captured Moost app so the next request triggers a full reload:
|
|
365
|
+
* releases the middleware + local fetch and ejects DI instances affected by
|
|
366
|
+
* the changed modules.
|
|
367
|
+
*/ const ejectApp = (cleanupInstances) => {
|
|
368
|
+
moostMiddleware = null;
|
|
369
|
+
if (localFetchTeardown) {
|
|
370
|
+
localFetchTeardown();
|
|
371
|
+
localFetchTeardown = null;
|
|
372
|
+
}
|
|
373
|
+
moostRestartCleanup(adapters, options.onEject, cleanupInstances);
|
|
374
|
+
reloadRequired = true;
|
|
375
|
+
};
|
|
351
376
|
patchMoostHandlerLogging();
|
|
352
377
|
return [{
|
|
353
378
|
name: PLUGIN_NAME,
|
|
@@ -492,16 +517,27 @@ function moostVite(options) {
|
|
|
492
517
|
};
|
|
493
518
|
},
|
|
494
519
|
async configureServer(server) {
|
|
495
|
-
const runner = createServerModuleRunner(server.environments.ssr);
|
|
520
|
+
const runner = createServerModuleRunner(server.environments.ssr, { hmr: false });
|
|
496
521
|
const ssrImport = (id) => runner.import(id);
|
|
522
|
+
bootError = null;
|
|
523
|
+
reloadRequired = false;
|
|
524
|
+
reloadPromise = null;
|
|
497
525
|
const runReload = () => {
|
|
498
526
|
reloadRequired = false;
|
|
499
527
|
console.log();
|
|
500
528
|
logger.debug("🚀 Reloading Moost App...");
|
|
501
529
|
console.log();
|
|
502
530
|
return (async () => {
|
|
503
|
-
|
|
504
|
-
|
|
531
|
+
try {
|
|
532
|
+
for (const adapter of adapters) if (adapter.detected) await adapter.init();
|
|
533
|
+
const entryModule = await getEntryModule(server.environments.ssr.moduleGraph);
|
|
534
|
+
if (entryModule?.transformResult) server.environments.ssr.moduleGraph.invalidateModule(entryModule);
|
|
535
|
+
await ssrImport(options.entry);
|
|
536
|
+
bootError = null;
|
|
537
|
+
} catch (error) {
|
|
538
|
+
bootError = error;
|
|
539
|
+
logger.error(`✖️ Failed to reload Moost App: ${error.message}`);
|
|
540
|
+
}
|
|
505
541
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
506
542
|
})().finally(() => {
|
|
507
543
|
reloadPromise = null;
|
|
@@ -530,30 +566,29 @@ function moostVite(options) {
|
|
|
530
566
|
}
|
|
531
567
|
return moostMiddleware(req, res);
|
|
532
568
|
}
|
|
569
|
+
if (bootError) {
|
|
570
|
+
res.statusCode = 502;
|
|
571
|
+
res.setHeader("Content-Type", "text/plain");
|
|
572
|
+
res.end(`Moost app failed to load: ${bootError.message}`);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
533
575
|
next();
|
|
534
576
|
});
|
|
535
577
|
},
|
|
536
|
-
hotUpdate({ file }) {
|
|
537
|
-
if (
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
localFetchTeardown = null;
|
|
551
|
-
}
|
|
552
|
-
moostRestartCleanup(adapters, options.onEject, cleanupInstances);
|
|
553
|
-
reloadRequired = true;
|
|
554
|
-
}
|
|
555
|
-
return [];
|
|
556
|
-
}
|
|
578
|
+
async hotUpdate({ file, modules }) {
|
|
579
|
+
if (this.environment.name !== "ssr" || modules.length === 0) return;
|
|
580
|
+
const { moduleGraph } = this.environment;
|
|
581
|
+
const entryModule = await getEntryModule(moduleGraph);
|
|
582
|
+
const importerSets = modules.map((mod) => gatherAllImporters(mod));
|
|
583
|
+
if (entryModule && !importerSets.some((importers) => importers.has(entryModule))) return;
|
|
584
|
+
logger.debug(`🔃 Hot update: ${file}`);
|
|
585
|
+
const cleanupInstances = /* @__PURE__ */ new Set();
|
|
586
|
+
for (const importers of importerSets) for (const impModule of importers) if (impModule.id) cleanupInstances.add(impModule.id);
|
|
587
|
+
for (const mod of modules) moduleGraph.invalidateModule(mod);
|
|
588
|
+
if (entryModule) moduleGraph.invalidateModule(entryModule);
|
|
589
|
+
else moduleGraph.invalidateAll();
|
|
590
|
+
ejectApp(cleanupInstances);
|
|
591
|
+
return [];
|
|
557
592
|
}
|
|
558
593
|
}, options.middleware && options.ssrEntry ? {
|
|
559
594
|
name: `${PLUGIN_NAME}:ssr-fallback`,
|
|
@@ -567,7 +602,7 @@ function moostVite(options) {
|
|
|
567
602
|
const url = req.originalUrl || req.url || "/";
|
|
568
603
|
try {
|
|
569
604
|
await drainReload();
|
|
570
|
-
let template = await fs.readFile(resolve(
|
|
605
|
+
let template = await fs.readFile(resolve(server.config.root, "index.html"), "utf8");
|
|
571
606
|
template = await server.transformIndexHtml(url, template);
|
|
572
607
|
const { render } = await server.ssrLoadModule(options.ssrEntry);
|
|
573
608
|
const { html: appHtml, state } = await render(url);
|
package/dist/prod-server.cjs
CHANGED
|
@@ -33,7 +33,7 @@ async function createSSRServer(options) {
|
|
|
33
33
|
if (req.method !== "GET") return next();
|
|
34
34
|
const url = req.originalUrl || req.url || "/";
|
|
35
35
|
try {
|
|
36
|
-
let template = await fs.readFile(path.resolve(
|
|
36
|
+
let template = await fs.readFile(path.resolve(vite.config.root, "index.html"), "utf8");
|
|
37
37
|
template = await vite.transformIndexHtml(url, template);
|
|
38
38
|
const { render } = await vite.ssrLoadModule(ssrEntry);
|
|
39
39
|
const { html: appHtml, state } = await render(url);
|
package/dist/prod-server.mjs
CHANGED
|
@@ -34,7 +34,7 @@ async function createSSRServer(options) {
|
|
|
34
34
|
if (req.method !== "GET") return next();
|
|
35
35
|
const url = req.originalUrl || req.url || "/";
|
|
36
36
|
try {
|
|
37
|
-
let template = await fs.readFile(path.resolve(
|
|
37
|
+
let template = await fs.readFile(path.resolve(vite.config.root, "index.html"), "utf8");
|
|
38
38
|
template = await vite.transformIndexHtml(url, template);
|
|
39
39
|
const { render } = await vite.ssrLoadModule(ssrEntry);
|
|
40
40
|
const { html: appHtml, state } = await render(url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moostjs/vite",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.26",
|
|
4
4
|
"description": "Vite Dev plugin for moostjs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"sirv": "^3.0.0",
|
|
60
60
|
"vite": "^8.0.0",
|
|
61
|
-
"@moostjs/event-http": "^0.6.
|
|
62
|
-
"moost": "^0.6.
|
|
61
|
+
"@moostjs/event-http": "^0.6.26",
|
|
62
|
+
"moost": "^0.6.26"
|
|
63
63
|
},
|
|
64
64
|
"peerDependenciesMeta": {
|
|
65
65
|
"sirv": {
|