@ubean/cli 0.4.2 → 0.4.4
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 +52 -4
- package/package.json +13 -13
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,6 @@ import { createServer as createServer$1 } from "vite";
|
|
|
19
19
|
import vue from "@vitejs/plugin-vue";
|
|
20
20
|
import { ubeanPlugin } from "@ubean/build/vite";
|
|
21
21
|
import { VUE_PLUGIN_INCLUDE, ubeanVite } from "@ubean/build/vue";
|
|
22
|
-
import { createVueRenderer } from "@ubean/client/ssr";
|
|
23
22
|
import { getVueLocaleParam, toVueRouterLocalePath } from "@ubean/i18n";
|
|
24
23
|
import { ubeanIslandsPlugin } from "@ubean/islands/vite";
|
|
25
24
|
import { findAvailablePort, findUserViteConfig, waitForPort } from "@ubean/shared/node";
|
|
@@ -501,6 +500,52 @@ function loadScaffoldOps() {
|
|
|
501
500
|
recoverScaffold
|
|
502
501
|
};
|
|
503
502
|
}
|
|
503
|
+
/** Vite's browser-facing prefix for virtual module ids (see `wrapId`). */
|
|
504
|
+
const VALID_ID_PREFIX = "/@id/";
|
|
505
|
+
/** Vite's URL-safe encoding of the `\0` virtual-module marker. */
|
|
506
|
+
const NULL_BYTE_PLACEHOLDER = "__x00__";
|
|
507
|
+
/**
|
|
508
|
+
* Encode a module-graph URL into a browser-servable path.
|
|
509
|
+
*
|
|
510
|
+
* Virtual module ids carry a raw `\0` marker in the module graph (e.g.
|
|
511
|
+
* UnoCSS's `\0/__uno.css`). A literal NUL is invalid inside HTML — parse5
|
|
512
|
+
* rejects it with `unexpected-null-character`, which surfaces as a warning
|
|
513
|
+
* in `transformIndexHtml`. Mirror Vite's own import-analysis rewriting
|
|
514
|
+
* (`wrapId`: `/@id/` prefix + `\0` → `__x00__`) so the href stays valid
|
|
515
|
+
* and resolvable by the dev server.
|
|
516
|
+
*/
|
|
517
|
+
function toDevCssHref(url) {
|
|
518
|
+
return url.includes("\0") ? `${VALID_ID_PREFIX}${url.replace(/\0/g, NULL_BYTE_PLACEHOLDER)}` : url;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Collect render-blocking CSS URLs from the Vite dev module graph.
|
|
522
|
+
*
|
|
523
|
+
* In dev, CSS imported from JS (virtual uno.css entry, global.css, font css)
|
|
524
|
+
* is only applied once the client entry module graph has fully loaded and
|
|
525
|
+
* executed — SSR HTML paints unstyled for that gap (FOUC). Injecting the same
|
|
526
|
+
* CSS modules as blocking `<link>` tags lets the browser fetch them in
|
|
527
|
+
* parallel with the JS graph, so the first paint is styled.
|
|
528
|
+
*
|
|
529
|
+
* `?direct` tells Vite's transform middleware to return raw CSS
|
|
530
|
+
* (`Content-Type: text/css`) instead of the JS style-injection wrapper.
|
|
531
|
+
* Modules whose URL already carries a query (SFC `<style>` blocks such as
|
|
532
|
+
* `*.vue?vue&type=style&...`) cannot be served this way and are skipped.
|
|
533
|
+
*/
|
|
534
|
+
function collectDevCssLinks(moduleGraph) {
|
|
535
|
+
const links = /* @__PURE__ */ new Set();
|
|
536
|
+
for (const mod of moduleGraph.idToModuleMap.values()) {
|
|
537
|
+
const { url, id } = mod;
|
|
538
|
+
if (!url || url.includes("?")) continue;
|
|
539
|
+
if (id?.endsWith(".css") || url.endsWith(".css")) links.add(`${toDevCssHref(url)}?direct`);
|
|
540
|
+
}
|
|
541
|
+
return [...links];
|
|
542
|
+
}
|
|
543
|
+
/** Inject blocking stylesheet links right before `</head>`. */
|
|
544
|
+
function injectStylesheetLinks(html, hrefs) {
|
|
545
|
+
if (!hrefs.length || !html.includes("</head>")) return html;
|
|
546
|
+
const tags = hrefs.map((href) => `<link rel="stylesheet" href="${href}">`).join("");
|
|
547
|
+
return html.replace("</head>", `${tags}</head>`);
|
|
548
|
+
}
|
|
504
549
|
async function createViteDevServer(options) {
|
|
505
550
|
const { cwd, config, app: initialApp, layouts: initialLayouts = [] } = options;
|
|
506
551
|
const host = options.host || "localhost";
|
|
@@ -573,8 +618,8 @@ async function createViteDevServer(options) {
|
|
|
573
618
|
const contentType = webRes.headers.get("content-type") || "";
|
|
574
619
|
const skipTransform = (req.url || "").startsWith("/_devtools");
|
|
575
620
|
if (contentType.includes("text/html") && webRes.body && !skipTransform) {
|
|
576
|
-
const
|
|
577
|
-
const transformedHtml = await viteServer.transformIndexHtml(req.url || "/",
|
|
621
|
+
const htmlWithCss = injectStylesheetLinks(await webRes.text(), collectDevCssLinks(viteServer.moduleGraph));
|
|
622
|
+
const transformedHtml = await viteServer.transformIndexHtml(req.url || "/", htmlWithCss);
|
|
578
623
|
res.statusCode = webRes.status;
|
|
579
624
|
res.statusMessage = webRes.statusText;
|
|
580
625
|
webRes.headers.forEach((value, key) => {
|
|
@@ -629,6 +674,7 @@ async function createViteDevServer(options) {
|
|
|
629
674
|
let viteDevtoolsPlugins = [];
|
|
630
675
|
if (devtoolsEnabled) try {
|
|
631
676
|
const { DevTools } = await import("@vitejs/devtools");
|
|
677
|
+
// @vitejs/devtools 也解析到含 @vitejs+devtools peer 上下文的 vite-plus-core
|
|
632
678
|
viteDevtoolsPlugins = await DevTools({ builtinDevTools: false });
|
|
633
679
|
} catch {}
|
|
634
680
|
const userViteConfig = findUserViteConfig(cwd);
|
|
@@ -663,6 +709,7 @@ async function createViteDevServer(options) {
|
|
|
663
709
|
viteServer = await createServer$1({
|
|
664
710
|
root: cwd,
|
|
665
711
|
configFile: userViteConfig ?? false,
|
|
712
|
+
resolve: { dedupe: ["vue", "vue-router"] },
|
|
666
713
|
server: {
|
|
667
714
|
middlewareMode: { server: httpServer },
|
|
668
715
|
hmr: { port: actualPort + 1e3 }
|
|
@@ -686,10 +733,11 @@ async function createViteDevServer(options) {
|
|
|
686
733
|
"#ubean-client-entry"
|
|
687
734
|
] },
|
|
688
735
|
ssr: {
|
|
689
|
-
noExternal: ["ubean"],
|
|
736
|
+
noExternal: ["ubean", /^@ubean\//],
|
|
690
737
|
external: ["@ubean/i18n"]
|
|
691
738
|
}
|
|
692
739
|
});
|
|
740
|
+
const { createVueRenderer } = await viteServer.ssrLoadModule("@ubean/client/ssr");
|
|
693
741
|
function enhanceAppWithVite(app, layouts = []) {
|
|
694
742
|
app.options.layouts = layouts;
|
|
695
743
|
const routeLoaders = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubean/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "CLI for ubean (ubean-next binary: dev, build, prepare, init, preview, page, env, config, devtools, api/layout/middleware/cron/plugin scaffolds) plus the Vite dev server runner",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ubean-next": "./bin/ubean-next.mjs"
|
|
@@ -24,29 +24,29 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@ubean/app": "0.4.
|
|
28
|
-
"@ubean/build": "0.4.
|
|
29
|
-
"@ubean/client": "0.4.
|
|
30
|
-
"@ubean/config": "0.4.
|
|
31
|
-
"@ubean/i18n": "0.4.
|
|
32
|
-
"@ubean/islands": "0.4.
|
|
33
|
-
"@ubean/preset": "0.4.
|
|
34
|
-
"@ubean/scan": "0.4.
|
|
35
|
-
"@ubean/shared": "0.4.
|
|
27
|
+
"@ubean/app": "0.4.4",
|
|
28
|
+
"@ubean/build": "0.4.4",
|
|
29
|
+
"@ubean/client": "0.4.4",
|
|
30
|
+
"@ubean/config": "0.4.4",
|
|
31
|
+
"@ubean/i18n": "0.4.4",
|
|
32
|
+
"@ubean/islands": "0.4.4",
|
|
33
|
+
"@ubean/preset": "0.4.4",
|
|
34
|
+
"@ubean/scan": "0.4.4",
|
|
35
|
+
"@ubean/shared": "0.4.4",
|
|
36
36
|
"citty": "^0.2.2",
|
|
37
37
|
"kolorist": "^1.8.0",
|
|
38
38
|
"pathe": "^2.0.3"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@types/node": "^26.
|
|
41
|
+
"@types/node": "^26.5.0",
|
|
42
42
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
43
43
|
"typescript": "7.0.2",
|
|
44
44
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
|
|
45
45
|
"vite-plus": "0.3.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@ubean/content": "0.4.
|
|
49
|
-
"@ubean/devtools": "0.4.
|
|
48
|
+
"@ubean/content": "0.4.4",
|
|
49
|
+
"@ubean/devtools": "0.4.4",
|
|
50
50
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
51
51
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.0"
|
|
52
52
|
},
|