@ubean/build 0.6.5 → 0.6.6

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/index.d.ts CHANGED
@@ -49,6 +49,21 @@ export declare function registerCssImport(cssPath: string): void;
49
49
  * Called by `createClientEntryVirtualModule` to prepend CSS imports.
50
50
  */
51
51
  export declare function getCssImports(): string[];
52
+ /**
53
+ * Register an inline `<script>` to be injected as the first element of `<head>`.
54
+ * e.g. `@ubean/integrations/ui` registers `@vean/theme`'s first-paint script so a
55
+ * project using `ui: true` needs no manual `useHead()` injection.
56
+ *
57
+ * The script must be self-contained and must run **before** any blocking
58
+ * stylesheet: the three injection points (`transformIndexHtml`, the fullstack
59
+ * server entry and the ssg static entry) all prepend it right after `<head>`.
60
+ */
61
+ export declare function registerHeadScript(script: string): void;
62
+ /**
63
+ * Get all registered head scripts, joined in registration order.
64
+ * Called by the dev HTML transform and the build-time server/ssg entries.
65
+ */
66
+ export declare function getHeadScripts(): string;
52
67
  /**
53
68
  * Reset the registry (for testing).
54
69
  * @internal
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as resetVirtualRegistry, a as ssrSingletonProdOptimizeExclude, c as getComponentResolvers, d as registerCssImport, f as resetModuleRegistry, g as defineVirtualModulePrefix, h as defineVirtualModule, i as ssrSingletonDevPolicy, l as getCssImports, m as createVirtualRegistry, n as SSR_SINGLETON_OPTIMIZE_EXCLUDE, o as ssrSingletonProdSsr, p as VirtualModuleRegistry, r as SSR_SINGLETON_PACKAGES, t as SSR_SINGLETON_DEDUPE, u as registerComponentResolver, v as useVirtualRegistry } from "./ssr-singleton-Bbds29jS.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, o as stripMacros, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-BK0L1Op-.js";
3
- export { SSR_SINGLETON_DEDUPE, SSR_SINGLETON_OPTIMIZE_EXCLUDE, SSR_SINGLETON_PACKAGES, VirtualModuleRegistry, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, createVirtualRegistry, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, ssrSingletonDevPolicy, ssrSingletonProdOptimizeExclude, ssrSingletonProdSsr, stripMacros, transformMacros, useVirtualRegistry };
1
+ import { _ as defineVirtualModule, a as ssrSingletonProdOptimizeExclude, b as useVirtualRegistry, c as getComponentResolvers, d as registerComponentResolver, f as registerCssImport, g as createVirtualRegistry, h as VirtualModuleRegistry, i as ssrSingletonDevPolicy, l as getCssImports, m as resetModuleRegistry, n as SSR_SINGLETON_OPTIMIZE_EXCLUDE, o as ssrSingletonProdSsr, p as registerHeadScript, r as SSR_SINGLETON_PACKAGES, t as SSR_SINGLETON_DEDUPE, u as getHeadScripts, v as defineVirtualModulePrefix, y as resetVirtualRegistry } from "./ssr-singleton-CUHZLgiO.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, o as stripMacros, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-CsmYnd9W.js";
3
+ export { SSR_SINGLETON_DEDUPE, SSR_SINGLETON_OPTIMIZE_EXCLUDE, SSR_SINGLETON_PACKAGES, VirtualModuleRegistry, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, createVirtualRegistry, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, getHeadScripts, registerComponentResolver, registerCssImport, registerHeadScript, resetModuleRegistry, resetVirtualRegistry, ssrSingletonDevPolicy, ssrSingletonProdOptimizeExclude, ssrSingletonProdSsr, stripMacros, transformMacros, useVirtualRegistry };
@@ -1 +1 @@
1
- export { T as buildWithEnvironments, v as createIslandsSsrStubPlugin, y as generateCloudflareWorkerEntry, b as generateNodeServerEntry, x as generateStandardHandlerEntry, S as generateVirtualModulesToDisk, C as getPresetBuildConfig, w as serializePagesForEntry } from "./vite-CmtXmVIm.js";
1
+ export { T as buildWithEnvironments, v as createIslandsSsrStubPlugin, y as generateCloudflareWorkerEntry, b as generateNodeServerEntry, x as generateStandardHandlerEntry, S as generateVirtualModulesToDisk, C as getPresetBuildConfig, w as serializePagesForEntry } from "./vite-Dva-CNKw.js";
@@ -101,7 +101,8 @@ function getRegistry() {
101
101
  const g = globalThis;
102
102
  if (!g[REGISTRY_KEY]) g[REGISTRY_KEY] = {
103
103
  componentResolvers: [],
104
- cssImports: []
104
+ cssImports: [],
105
+ headScripts: []
105
106
  };
106
107
  return g[REGISTRY_KEY];
107
108
  }
@@ -136,6 +137,27 @@ function getCssImports() {
136
137
  return [...getRegistry().cssImports];
137
138
  }
138
139
  /**
140
+ * Register an inline `<script>` to be injected as the first element of `<head>`.
141
+ * e.g. `@ubean/integrations/ui` registers `@vean/theme`'s first-paint script so a
142
+ * project using `ui: true` needs no manual `useHead()` injection.
143
+ *
144
+ * The script must be self-contained and must run **before** any blocking
145
+ * stylesheet: the three injection points (`transformIndexHtml`, the fullstack
146
+ * server entry and the ssg static entry) all prepend it right after `<head>`.
147
+ */
148
+ function registerHeadScript(script) {
149
+ if (!script) return;
150
+ const reg = getRegistry();
151
+ if (!reg.headScripts.includes(script)) reg.headScripts.push(script);
152
+ }
153
+ /**
154
+ * Get all registered head scripts, joined in registration order.
155
+ * Called by the dev HTML transform and the build-time server/ssg entries.
156
+ */
157
+ function getHeadScripts() {
158
+ return getRegistry().headScripts.join("\n");
159
+ }
160
+ /**
139
161
  * Reset the registry (for testing).
140
162
  * @internal
141
163
  */
@@ -143,6 +165,7 @@ function resetModuleRegistry() {
143
165
  const reg = getRegistry();
144
166
  reg.componentResolvers.length = 0;
145
167
  reg.cssImports.length = 0;
168
+ reg.headScripts.length = 0;
146
169
  }
147
170
  //#endregion
148
171
  //#region src/ssr-singleton.ts
@@ -215,4 +238,4 @@ function ssrSingletonProdOptimizeExclude(extra = []) {
215
238
  return [...SSR_SINGLETON_OPTIMIZE_EXCLUDE, ...extra];
216
239
  }
217
240
  //#endregion
218
- export { resetVirtualRegistry as _, ssrSingletonProdOptimizeExclude as a, getComponentResolvers as c, registerCssImport as d, resetModuleRegistry as f, defineVirtualModulePrefix as g, defineVirtualModule as h, ssrSingletonDevPolicy as i, getCssImports as l, createVirtualRegistry as m, SSR_SINGLETON_OPTIMIZE_EXCLUDE as n, ssrSingletonProdSsr as o, VirtualModuleRegistry as p, SSR_SINGLETON_PACKAGES as r, ssr_singleton_exports as s, SSR_SINGLETON_DEDUPE as t, registerComponentResolver as u, useVirtualRegistry as v, __exportAll as y };
241
+ export { defineVirtualModule as _, ssrSingletonProdOptimizeExclude as a, useVirtualRegistry as b, getComponentResolvers as c, registerComponentResolver as d, registerCssImport as f, createVirtualRegistry as g, VirtualModuleRegistry as h, ssrSingletonDevPolicy as i, getCssImports as l, resetModuleRegistry as m, SSR_SINGLETON_OPTIMIZE_EXCLUDE as n, ssrSingletonProdSsr as o, registerHeadScript as p, SSR_SINGLETON_PACKAGES as r, ssr_singleton_exports as s, SSR_SINGLETON_DEDUPE as t, getHeadScripts as u, defineVirtualModulePrefix as v, __exportAll as x, resetVirtualRegistry as y };
@@ -57,7 +57,10 @@ export interface StaticSsgRendererI18nInit {
57
57
  defaultLocale?: string;
58
58
  locales?: Array<string | {
59
59
  code: string;
60
+ path?: string;
60
61
  }>;
62
+ /** Locale code → URL segment override. See `LocaleRoutingConfig.paths`. */
63
+ paths?: Record<string, string>;
61
64
  }
62
65
  export interface StaticSsgRendererInit {
63
66
  /** 扫描得到的页面(含动态路由模式,供具象 URL 匹配) */
@@ -144,13 +144,14 @@ function expandRoutesForLocales(routes, i18n) {
144
144
  const strategy = i18n.strategy || "prefix_except_default";
145
145
  if (strategy === "no_prefix") return dedupeRoutes(routes);
146
146
  const defaultLocale = i18n.defaultLocale || localeCodes[0] || "";
147
+ const seg = (code) => segmentOf(code, i18n.paths);
147
148
  const expanded = [];
148
149
  for (const route of routes) {
149
150
  if (route === "/__ubean_404__") {
150
151
  expanded.push(route);
151
152
  continue;
152
153
  }
153
- const { locale } = extractLocaleFromPath(route, localeCodes);
154
+ const { locale } = extractLocaleFromPath(route, localeCodes, i18n.paths);
154
155
  if (locale) {
155
156
  expanded.push(route);
156
157
  continue;
@@ -158,22 +159,26 @@ function expandRoutesForLocales(routes, i18n) {
158
159
  const suffix = route === "/" || route === "" ? "" : route;
159
160
  switch (strategy) {
160
161
  case "prefix":
161
- for (const code of localeCodes) expanded.push(`/${code}${suffix}`);
162
+ for (const code of localeCodes) expanded.push(`/${seg(code)}${suffix}`);
162
163
  break;
163
164
  case "prefix_and_default":
164
165
  expanded.push(route || "/");
165
- for (const code of localeCodes) expanded.push(`/${code}${suffix}`);
166
+ for (const code of localeCodes) expanded.push(`/${seg(code)}${suffix}`);
166
167
  break;
167
168
  default:
168
169
  expanded.push(route || "/");
169
170
  for (const code of localeCodes) {
170
171
  if (code === defaultLocale) continue;
171
- expanded.push(`/${code}${suffix}`);
172
+ expanded.push(`/${seg(code)}${suffix}`);
172
173
  }
173
174
  }
174
175
  }
175
176
  return dedupeRoutes(expanded);
176
177
  }
178
+ /** URL segment for a locale code (`paths` override, else the code). */
179
+ function segmentOf(code, paths) {
180
+ return paths?.[code] ?? code;
181
+ }
177
182
  /**
178
183
  * 加载构建产物中的静态 entry(`dist/server/entry.mjs`),返回静态渲染器。
179
184
  *
@@ -210,7 +215,8 @@ async function createStaticSsgRenderer(cwd, manifest, init) {
210
215
  enabled: i18nEnabled,
211
216
  strategy,
212
217
  defaultLocale,
213
- locales: localeCodes
218
+ locales: localeCodes,
219
+ paths: init.i18n?.paths
214
220
  }),
215
221
  fetcher: async (url) => {
216
222
  const u = new URL(url, "http://ubean.local");
@@ -231,7 +237,7 @@ async function createStaticSsgRenderer(cwd, manifest, init) {
231
237
  let pathToMatch = pathname;
232
238
  let locale = defaultLocale;
233
239
  if (usePrefix) {
234
- const { locale: extracted, pathWithoutLocale } = extractLocaleFromPath(pathname, localeCodes);
240
+ const { locale: extracted, pathWithoutLocale } = extractLocaleFromPath(pathname, localeCodes, init.i18n?.paths);
235
241
  if (extracted) {
236
242
  locale = extracted;
237
243
  pathToMatch = pathWithoutLocale;
@@ -1,4 +1,4 @@
1
- import { h as defineVirtualModule } from "./ssr-singleton-Bbds29jS.js";
1
+ import { _ as defineVirtualModule } from "./ssr-singleton-CUHZLgiO.js";
2
2
  import { isAbsolute, relative } from "pathe";
3
3
  //#region src/macros.ts
4
4
  const MACRO_NAMES = ["definePage"];
@@ -287,12 +287,16 @@ if (import.meta.env.SSR) {
287
287
  }
288
288
 
289
289
  async function collectMessages(code) {
290
- const localeData = { messages: {}, options: { isDefault: false, name: undefined, dir: 'ltr', language: undefined } };
290
+ const localeData = {
291
+ messages: {},
292
+ options: { isDefault: false, name: undefined, path: undefined, dir: 'ltr', language: undefined }
293
+ };
291
294
  const configLoc = i18nConfig && i18nConfig.locales
292
295
  ? i18nConfig.locales.find(l => (typeof l === 'string' ? l : l.code) === code)
293
296
  : undefined;
294
297
  if (configLoc && typeof configLoc === 'object') {
295
298
  localeData.options.name = configLoc.name;
299
+ localeData.options.path = configLoc.path;
296
300
  localeData.options.dir = configLoc.dir || 'ltr';
297
301
  localeData.options.language = configLoc.language;
298
302
  localeData.options.isDefault = configLoc.code === (i18nConfig && i18nConfig.defaultLocale);
@@ -1,13 +1,13 @@
1
- import { a as ssrSingletonProdOptimizeExclude, m as createVirtualRegistry, o as ssrSingletonProdSsr, y as __exportAll } from "./ssr-singleton-Bbds29jS.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-BK0L1Op-.js";
1
+ import { a as ssrSingletonProdOptimizeExclude, g as createVirtualRegistry, o as ssrSingletonProdSsr, x as __exportAll } from "./ssr-singleton-CUHZLgiO.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-CsmYnd9W.js";
3
3
  import { a as generateOpenApiTypes, i as generateTypes } from "./codegen-BL0s5Pyq.js";
4
- import { _ as toWebRequest, a as createVueAppEntryVirtualModule, b as getDevScanCoordinator, g as sendWebResponse, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, u as ensureDevApp } from "./vue-15_4jzH7.js";
4
+ import { _ as sendWebResponse, a as createServerEntryVirtualModule, d as ensureDevApp, i as createClientEntryVirtualModule, n as ubeanVite, o as createVueAppEntryVirtualModule, r as composeHeadScripts, s as createVuePagesVirtualModule, v as toWebRequest, x as getDevScanCoordinator } from "./vue-q7rHFo73.js";
5
5
  import { createStaticSsgRenderer } from "./static-render.js";
6
6
  import { prerender, resolvePrerenderStaticDir } from "./prerender.js";
7
7
  import { dirname, isAbsolute, join, relative, resolve } from "pathe";
8
8
  import * as nodeFs from "node:fs";
9
9
  import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
10
- import { checkProjectDependenciesOnce, loadUbeanConfig, resolveModules, resolvePrerenderConfig, tryGetConfig } from "@ubean/config";
10
+ import { checkProjectDependenciesOnce, loadUbeanConfig, localePathsOf, resolveModules, resolvePrerenderConfig, tryGetConfig } from "@ubean/config";
11
11
  import { isEphemeralCachePreset, registerBuiltinPresets, resolvePresetByName, resolveProductionCacheStore } from "@ubean/preset";
12
12
  import { createServerRouter } from "@ubean/routes";
13
13
  import { scanProject } from "@ubean/scan";
@@ -30,7 +30,8 @@ function localeVueParamFromI18n(config) {
30
30
  return getVueLocaleParam({
31
31
  defaultLocale: config.defaultLocale,
32
32
  locales: config.locales.map((l) => l.code),
33
- strategy: config.strategy
33
+ strategy: config.strategy,
34
+ paths: localePathsOf(config)
34
35
  }) || void 0;
35
36
  }
36
37
  //#endregion
@@ -285,7 +286,8 @@ export async function renderStaticPage(input) {
285
286
  renderContext.routing = {
286
287
  defaultLocale: _i18nConfig.defaultLocale || 'en',
287
288
  locales: _localeCodes,
288
- strategy: _i18nConfig.strategy || 'prefix_except_default'
289
+ strategy: _i18nConfig.strategy || 'prefix_except_default',
290
+ ...(_i18nConfig.paths ? { paths: _i18nConfig.paths } : {})
289
291
  };
290
292
  const cookieName =
291
293
  _i18nConfig.detectBrowserLanguage && _i18nConfig.detectBrowserLanguage.cookieName;
@@ -738,14 +740,15 @@ async function writeClientIndexHtml(virtualDir) {
738
740
  * manifest、同一套标签规则,避免出现第二种「入口长什么样」的定义。
739
741
  */
740
742
  async function writeSpaIndexHtml(options) {
741
- const { outDirs, tags } = options;
743
+ const { outDirs, tags, headScript } = options;
742
744
  const target = join(outDirs.public, "index.html");
745
+ const favicon = tags.favicon ?? "/favicon.svg";
743
746
  const html = `<!DOCTYPE html>
744
747
  <html>
745
- <head>
748
+ <head>${headScript ? `\n ${headScript}` : ""}
746
749
  <meta charset="UTF-8" />
747
750
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
748
- <link rel="icon" href="${tags.favicon ?? "/favicon.svg"}" type="image/svg+xml" />
751
+ <link rel="icon" href="${favicon}" type="image/svg+xml" />
749
752
  <title>Ubean App</title>
750
753
  ${tags.css ? ` ${tags.css.split("\n").join("\n ")}\n` : ""}</head>
751
754
  <body>
@@ -1250,10 +1253,7 @@ async function prepareBuild(ctx, manifestRef = { current: null }) {
1250
1253
  mode: ctx.mode,
1251
1254
  ssrEnabled: ctx.ssrEnabled
1252
1255
  });
1253
- logger$2.info("Generating virtual modules...");
1254
1256
  const virtualRegistry = createVirtualRegistry();
1255
- await generateVirtualModulesToDisk(cwd, config, scanResult, outDirs.virtual, preset, virtualRegistry, contentSnapshot);
1256
- if (hasPages) await writeClientIndexHtml(outDirs.virtual);
1257
1257
  const userViteConfig = findUserViteConfig(cwd);
1258
1258
  const builtinPlugins = [];
1259
1259
  if (!userViteConfig) {
@@ -1277,6 +1277,9 @@ async function prepareBuild(ctx, manifestRef = { current: null }) {
1277
1277
  builtinPlugins
1278
1278
  });
1279
1279
  if (hasServer) plugins.push(perEnvironmentPlugin("ubean", () => createIslandsSsrStubPlugin()));
1280
+ logger$2.info("Generating virtual modules...");
1281
+ await generateVirtualModulesToDisk(cwd, config, scanResult, outDirs.virtual, preset, virtualRegistry, contentSnapshot);
1282
+ if (hasPages) await writeClientIndexHtml(outDirs.virtual);
1280
1283
  return {
1281
1284
  ...ctx,
1282
1285
  plugins,
@@ -1316,7 +1319,8 @@ async function runEnvBuilds(builder, prepared) {
1316
1319
  css: tags.css,
1317
1320
  body: tags.body,
1318
1321
  favicon: prepared.config.favicon
1319
- }
1322
+ },
1323
+ headScript: composeHeadScripts(prepared.config.colorMode !== false ? getColorModeScript(resolveColorModeConfig(prepared.config.colorMode)) : "")
1320
1324
  });
1321
1325
  }
1322
1326
  const builtManifest = await writeBuildManifest({
@@ -1528,7 +1532,7 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir,
1528
1532
  layout: scanResult.notFoundPage.layout,
1529
1533
  pageMeta: scanResult.notFoundPage.pageMeta
1530
1534
  } : null);
1531
- const colorModeScript = config.colorMode !== false ? getColorModeScript(resolveColorModeConfig(config.colorMode)) : "";
1535
+ const colorModeScript = composeHeadScripts(config.colorMode !== false ? getColorModeScript(resolveColorModeConfig(config.colorMode)) : "");
1532
1536
  const rendererImport = ssrEnabled ? `import { createVueRenderer } from 'ubean/ssr';` : "";
1533
1537
  const prodLocaleVueParam = localeVueParamFromI18n(config.i18n) || "";
1534
1538
  const rendererSetup = buildRendererSetup({
@@ -2482,7 +2486,7 @@ async function buildEnvironmentsForConfig(config) {
2482
2486
  Promise.resolve().then(() => build_configs_exports),
2483
2487
  import("./production.js"),
2484
2488
  import("@ubean/preset"),
2485
- import("./ssr-singleton-Bbds29jS.js").then((n) => n.s)
2489
+ import("./ssr-singleton-CUHZLgiO.js").then((n) => n.s)
2486
2490
  ]);
2487
2491
  registerBuiltinPresets();
2488
2492
  const outDirs = getBuildOutDirsForConfig(config);
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { m as createVirtualRegistry } from "./ssr-singleton-Bbds29jS.js";
2
- import { A as toVueRouterPagePath, C as bootstrapDevApp, D as resolveLocaleVueParam, E as resolveDevSecurityHeaders, O as enhanceDevApp, S as peekDevScanCoordinator, T as createDevAppReady, _ as toWebRequest, b as getDevScanCoordinator, c as collectDevCssLinks, d as getDevApp, f as injectStylesheetLinks, g as sendWebResponse, h as ubeanDevRequestPlugin, k as buildDevSsrRoutes, l as createUbeanRequestHandlers, m as isViteResourceRequest, p as isFrameworkHtmlPage, s as DEVTOOLS_PASS_THROUGH_PREFIXES, u as ensureDevApp, v as DEV_SCAN_DIRS, w as createDevApp, x as onDevScan, y as createDevScanCoordinator } from "./vue-15_4jzH7.js";
3
- import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-CmtXmVIm.js";
1
+ import { g as createVirtualRegistry } from "./ssr-singleton-CUHZLgiO.js";
2
+ import { A as buildDevSsrRoutes, C as peekDevScanCoordinator, D as resolveDevSecurityHeaders, E as createDevAppReady, O as resolveLocaleVueParam, S as onDevScan, T as createDevApp, _ as sendWebResponse, b as createDevScanCoordinator, c as DEVTOOLS_PASS_THROUGH_PREFIXES, d as ensureDevApp, f as getDevApp, g as ubeanDevRequestPlugin, h as isViteResourceRequest, j as toVueRouterPagePath, k as enhanceDevApp, l as collectDevCssLinks, m as isFrameworkHtmlPage, p as injectStylesheetLinks, u as createUbeanRequestHandlers, v as toWebRequest, w as bootstrapDevApp, x as getDevScanCoordinator, y as DEV_SCAN_DIRS } from "./vue-q7rHFo73.js";
3
+ import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-Dva-CNKw.js";
4
4
  export { DEVTOOLS_PASS_THROUGH_PREFIXES, DEV_SCAN_DIRS, DEV_WORKER_FILE, MINIFLARE_INSTALL_HINT, UBEAN_DEV_ENV_NAME, UbeanDevEnvironment, attachPreviewMiddleware, bootstrapDevApp, bridgeEnvRunnerInvokes, buildDevSsrRoutes, collectDevCssLinks, createCloudflarePreviewRunner, createDevApp, createDevAppReady, createDevScanCoordinator, createEnvRunnerTransport, createPreviewMiddleware, createUbeanDevEnvironmentFactory, createUbeanRequestHandlers, createVirtualRegistry, defaultLoadMiniflare, enhanceDevApp, ensureDevApp, getDevApp, getDevScanCoordinator, getDevWorkerEntrySource, injectStylesheetLinks, invalidateDevWorkerModules, isFrameworkHtmlPage, isViteResourceRequest, onDevScan, peekDevScanCoordinator, previewMimeType, readCompatibilityDate, resolveDevSecurityHeaders, resolveLocaleVueParam, resolvePreviewFile, sendPreviewFile, sendPreviewStatus, sendWebResponse, toVueRouterPagePath, toWebRequest, ubeanDevRequestPlugin, ubeanPlugin, ubeanPreviewPlugin, writeDevWorkerEntry };
@@ -1,13 +1,14 @@
1
- import { c as getComponentResolvers, h as defineVirtualModule, i as ssrSingletonDevPolicy, l as getCssImports, m as createVirtualRegistry } from "./ssr-singleton-Bbds29jS.js";
1
+ import { _ as defineVirtualModule, c as getComponentResolvers, g as createVirtualRegistry, i as ssrSingletonDevPolicy, l as getCssImports, u as getHeadScripts } from "./ssr-singleton-CUHZLgiO.js";
2
2
  import { D as resolveComponentsConfig, E as resolveAutoImportsConfig, O as toArray, S as getAutoImportPresets, f as COMPONENT_HALF_GLOBS } from "./codegen-BL0s5Pyq.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { isAbsolute, join, normalize, relative, resolve } from "pathe";
5
5
  import { existsSync } from "node:fs";
6
- import { loadUbeanConfig } from "@ubean/config";
6
+ import { loadUbeanConfig, localePathsOf } from "@ubean/config";
7
7
  import { scanProject } from "@ubean/scan";
8
8
  import { applyServerConfig, createUbeanApp } from "@ubean/app";
9
9
  import { getVueLocaleParam, toVueRouterLocalePath } from "@ubean/i18n";
10
10
  import { getColorModeScript, getPartyTownScript, resolveColorModeConfig, resolvePartyTownConfig } from "@ubean/client";
11
+ import { generatePagesModuleSource } from "@ubean/vue/vite";
11
12
  import { transformWithOxc } from "vite";
12
13
  import vue from "@vitejs/plugin-vue";
13
14
  import Components from "unplugin-vue-components/vite";
@@ -16,7 +17,6 @@ import AutoImport from "unplugin-auto-import/vite";
16
17
  import { ubeanMdxPlugin } from "@ubean/markdown";
17
18
  import { renderFaviconLink } from "@ubean/pages";
18
19
  import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
19
- import { generatePagesModuleSource } from "@ubean/vue/vite";
20
20
  //#region src/dev/dev-ssr-routes.ts
21
21
  /**
22
22
  * dev/SSR 路由表(RM-V11 的组成部件,从 CLI dev server 抽出)。
@@ -391,7 +391,8 @@ function resolveLocaleVueParam(config) {
391
391
  return getVueLocaleParam({
392
392
  defaultLocale: i18n.defaultLocale,
393
393
  locales: i18n.locales.map((l) => l.code),
394
- strategy: i18n.strategy
394
+ strategy: i18n.strategy,
395
+ paths: localePathsOf(i18n)
395
396
  });
396
397
  }
397
398
  //#endregion
@@ -1213,6 +1214,7 @@ if (_i18nConfig && _i18nConfig.enabled !== false) {
1213
1214
  fallbackLocale: _i18nConfig.fallbackLocale || _i18nConfig.defaultLocale,
1214
1215
  cookieName: (_i18nConfig.detectBrowserLanguage && _i18nConfig.detectBrowserLanguage.cookieName) || 'ubean_locale',
1215
1216
  baseUrl: _i18nConfig.baseUrl || '',
1217
+ paths: _i18nConfig.paths,
1216
1218
  vueI18n: _i18nConfig.vueI18n
1217
1219
  },
1218
1220
  loadLocale: _loadLocale,
@@ -1465,6 +1467,21 @@ export const rootId = 'app';
1465
1467
  `.trim()}\n`;
1466
1468
  });
1467
1469
  }
1470
+ /**
1471
+ * 合并首帧 `<head>` 脚本的两个来源,去重后返回。
1472
+ *
1473
+ * 通常只有一个源生效:`ui` 接管时配置层强制把 `colorMode` 置 false,所以两边不会同时非空。
1474
+ * 两个源合成一个字符串后,三条注入路径(dev `transformIndexHtml`、fullstack 服务端入口、
1475
+ * ssg 静态入口)只需要一个 `colorModeScript` 字段,不必各自改签名。
1476
+ *
1477
+ * @param colorModeScript - 已渲染的 ubean color-mode 脚本(`getColorModeScript()` 产物)
1478
+ */
1479
+ function composeHeadScripts(colorModeScript) {
1480
+ const headScripts = getHeadScripts();
1481
+ if (!headScripts) return colorModeScript;
1482
+ if (!colorModeScript) return headScripts;
1483
+ return `${headScripts}\n${colorModeScript}`;
1484
+ }
1468
1485
  function createClientEntryVirtualModule() {
1469
1486
  return defineVirtualModule("virtual:ubean-client-entry", () => {
1470
1487
  return `${`
@@ -1570,7 +1587,8 @@ function localeVueParamFromConfig(config) {
1570
1587
  return getVueLocaleParam({
1571
1588
  defaultLocale: config.i18n.defaultLocale,
1572
1589
  locales: codes,
1573
- strategy: config.i18n.strategy
1590
+ strategy: config.i18n.strategy,
1591
+ paths: localePathsOf(config.i18n)
1574
1592
  }) || void 0;
1575
1593
  }
1576
1594
  function ubeanVite(options) {
@@ -1695,11 +1713,8 @@ function ubeanVite(options) {
1695
1713
  transformIndexHtml(html, ctx) {
1696
1714
  if (ctx?.path && isFrameworkHtmlPage(ctx.path)) return html;
1697
1715
  let result = html;
1698
- const colorModeConfig = ubeanConfig.colorMode;
1699
- if (colorModeConfig !== false) {
1700
- const script = getColorModeScript(resolveColorModeConfig(colorModeConfig));
1701
- result = result.replace("<head>", `<head>\n ${script}`);
1702
- }
1716
+ const headScript = composeHeadScripts(ubeanConfig.colorMode !== false ? getColorModeScript(resolveColorModeConfig(ubeanConfig.colorMode)) : "");
1717
+ if (headScript) result = result.replace("<head>", `<head>\n ${headScript}`);
1703
1718
  const partyTownConfig = ubeanConfig.partyTown;
1704
1719
  if (partyTownConfig !== false && partyTownConfig !== void 0) {
1705
1720
  const resolved = resolvePartyTownConfig(partyTownConfig === true ? { enabled: true } : partyTownConfig);
@@ -1872,4 +1887,4 @@ async function runPagefindIndexing(ubeanConfig, searchConfig) {
1872
1887
  });
1873
1888
  }
1874
1889
  //#endregion
1875
- export { toVueRouterPagePath as A, bootstrapDevApp as C, resolveLocaleVueParam as D, resolveDevSecurityHeaders as E, enhanceDevApp as O, peekDevScanCoordinator as S, createDevAppReady as T, toWebRequest as _, createVueAppEntryVirtualModule as a, getDevScanCoordinator as b, collectDevCssLinks as c, getDevApp as d, injectStylesheetLinks as f, sendWebResponse as g, ubeanDevRequestPlugin as h, createServerEntryVirtualModule as i, buildDevSsrRoutes as k, createUbeanRequestHandlers as l, isViteResourceRequest as m, ubeanVite as n, createVuePagesVirtualModule as o, isFrameworkHtmlPage as p, createClientEntryVirtualModule as r, DEVTOOLS_PASS_THROUGH_PREFIXES as s, VUE_PLUGIN_INCLUDE as t, ensureDevApp as u, DEV_SCAN_DIRS as v, createDevApp as w, onDevScan as x, createDevScanCoordinator as y };
1890
+ export { buildDevSsrRoutes as A, peekDevScanCoordinator as C, resolveDevSecurityHeaders as D, createDevAppReady as E, resolveLocaleVueParam as O, onDevScan as S, createDevApp as T, sendWebResponse as _, createServerEntryVirtualModule as a, createDevScanCoordinator as b, DEVTOOLS_PASS_THROUGH_PREFIXES as c, ensureDevApp as d, getDevApp as f, ubeanDevRequestPlugin as g, isViteResourceRequest as h, createClientEntryVirtualModule as i, toVueRouterPagePath as j, enhanceDevApp as k, collectDevCssLinks as l, isFrameworkHtmlPage as m, ubeanVite as n, createVueAppEntryVirtualModule as o, injectStylesheetLinks as p, composeHeadScripts as r, createVuePagesVirtualModule as s, VUE_PLUGIN_INCLUDE as t, createUbeanRequestHandlers as u, toWebRequest as v, bootstrapDevApp as w, getDevScanCoordinator as x, DEV_SCAN_DIRS as y };
package/dist/vue.d.ts CHANGED
@@ -36,6 +36,16 @@ export declare function ubeanVite(options: UbeanViteOptions): Plugin[];
36
36
  */
37
37
  export declare function createVuePagesVirtualModule(pages: ScannedPageRoute[], layouts: ScannedLayout[], notFoundPage?: ScannedPageRoute, loadingPage?: ScannedPageRoute, errorPage?: ScannedPageRoute, localeVueParam?: string): VirtualModule;
38
38
  export declare function createVueAppEntryVirtualModule(appEntry?: ScannedAppEntry): VirtualModule;
39
+ /**
40
+ * 合并首帧 `<head>` 脚本的两个来源,去重后返回。
41
+ *
42
+ * 通常只有一个源生效:`ui` 接管时配置层强制把 `colorMode` 置 false,所以两边不会同时非空。
43
+ * 两个源合成一个字符串后,三条注入路径(dev `transformIndexHtml`、fullstack 服务端入口、
44
+ * ssg 静态入口)只需要一个 `colorModeScript` 字段,不必各自改签名。
45
+ *
46
+ * @param colorModeScript - 已渲染的 ubean color-mode 脚本(`getColorModeScript()` 产物)
47
+ */
48
+ export declare function composeHeadScripts(colorModeScript: string): string;
39
49
  export declare function createClientEntryVirtualModule(): VirtualModule;
40
50
  export declare function createServerEntryVirtualModule(serverEntry?: ScannedServerEntry): VirtualModule;
41
51
  //#endregion
package/dist/vue.js CHANGED
@@ -1 +1 @@
1
- export { t as VUE_PLUGIN_INCLUDE, r as createClientEntryVirtualModule, i as createServerEntryVirtualModule, a as createVueAppEntryVirtualModule, o as createVuePagesVirtualModule, n as default, n as ubeanVite } from "./vue-15_4jzH7.js";
1
+ export { t as VUE_PLUGIN_INCLUDE, r as composeHeadScripts, i as createClientEntryVirtualModule, a as createServerEntryVirtualModule, o as createVueAppEntryVirtualModule, s as createVuePagesVirtualModule, n as default, n as ubeanVite } from "./vue-q7rHFo73.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/build",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Vite plugins, production build, SSG prerender, type codegen, and Server Actions plugin for ubean",
5
5
  "files": [
6
6
  "dist"
@@ -48,20 +48,20 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "@intlify/unplugin-vue-i18n": "11.2.6",
52
- "@ubean/app": "0.6.5",
53
- "@ubean/client": "0.6.5",
54
- "@ubean/config": "0.6.5",
55
- "@ubean/i18n": "0.6.5",
56
- "@ubean/islands": "0.6.5",
57
- "@ubean/markdown": "0.6.5",
58
- "@ubean/pages": "0.6.5",
59
- "@ubean/preset": "0.6.5",
60
- "@ubean/routes": "0.6.5",
61
- "@ubean/scan": "0.6.5",
62
- "@ubean/server": "0.6.5",
63
- "@ubean/shared": "0.6.5",
64
- "@ubean/vue": "0.6.5",
51
+ "@intlify/unplugin-vue-i18n": "11.2.7",
52
+ "@ubean/app": "0.6.6",
53
+ "@ubean/client": "0.6.6",
54
+ "@ubean/config": "0.6.6",
55
+ "@ubean/i18n": "0.6.6",
56
+ "@ubean/islands": "0.6.6",
57
+ "@ubean/markdown": "0.6.6",
58
+ "@ubean/pages": "0.6.6",
59
+ "@ubean/preset": "0.6.6",
60
+ "@ubean/routes": "0.6.6",
61
+ "@ubean/scan": "0.6.6",
62
+ "@ubean/server": "0.6.6",
63
+ "@ubean/shared": "0.6.6",
64
+ "@ubean/vue": "0.6.6",
65
65
  "@vitejs/plugin-vue": "^6.0.10",
66
66
  "openapi-typescript": "^7.13.0",
67
67
  "pathe": "^2.0.3",
@@ -70,7 +70,7 @@
70
70
  "unplugin-auto-import": "21.1.0",
71
71
  "unplugin-vue-components": "^32.1.0",
72
72
  "unplugin-vue-markdown": "^32.1.1",
73
- "vue-i18n": "11.4.15"
73
+ "vue-i18n": "11.4.16"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/node": "^26.6.5",