@ubean/build 0.1.12 → 0.2.0

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
@@ -1,92 +1,11 @@
1
- import { CompiledLayout, CompiledMiddleware, CompiledPage, CompiledRoute, ScannedApiRoute, ScannedLocale, ScannedMiddleware, ScannedPageRoute } from "@ubean/routing";
2
- //#region src/virtual-registry.d.ts
3
- interface VirtualModuleContext {
4
- resolveId(id: string): string | undefined;
5
- load(id: string): string | undefined;
6
- invalidate(id: string): void;
7
- }
8
- type VirtualModuleTransform = (id: string, code: string) => string | Promise<string>;
9
- interface VirtualModule {
10
- id: string;
11
- resolve(id: string, importer?: string): string | undefined;
12
- load(): string | Promise<string>;
13
- }
14
- declare class VirtualModuleRegistry {
15
- private modules;
16
- private invalidated;
17
- register(mod: VirtualModule): void;
18
- resolveId(id: string, importer?: string): string | undefined;
19
- load(id: string): Promise<string | undefined>;
20
- invalidate(id: string): void;
21
- isInvalidated(id: string): boolean;
22
- clearInvalidated(): void;
23
- getModules(): VirtualModule[];
24
- clear(): void;
25
- }
26
- declare function useVirtualRegistry(): VirtualModuleRegistry;
27
- declare function resetVirtualRegistry(): void;
28
- declare function defineVirtualModule(id: string, loader: () => string | Promise<string>): VirtualModule;
29
- declare function defineVirtualModulePrefix(prefix: string, loader: (id: string) => string | Promise<string>): VirtualModule;
30
- //#endregion
31
- //#region src/macros.d.ts
32
- declare function stripMacros(code: string, macros?: readonly string[]): string;
33
- declare function transformMacros(code: string, id: string): string | null;
34
- //#endregion
1
+ import { VirtualModule, VirtualModuleContext, VirtualModuleRegistry, VirtualModuleTransform, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, stripMacros, transformMacros, useVirtualRegistry } from "@ubean/build-core";
2
+ import { CompiledLayout, CompiledMiddleware, CompiledPage, CompiledRoute } from "@ubean/routes";
3
+ import { ScannedApiRoute, ScannedLocale, ScannedMiddleware, ScannedPageRoute } from "@ubean/scan";
35
4
  //#region src/virtual-modules.d.ts
36
- declare function createRoutingVirtualModule(routes: CompiledRoute[], middlewares: CompiledMiddleware[], cwd: string): VirtualModule;
37
- declare function createPagesVirtualModule(pages: CompiledPage[], layouts: CompiledLayout[], cwd: string): VirtualModule;
38
- declare function createMetaVirtualModule(): VirtualModule;
39
- declare function createAppVirtualModule(apiRoutes: ScannedApiRoute[], middlewares: ScannedMiddleware[], pages: ScannedPageRoute[], srcDir: string): VirtualModule;
40
- declare function createLocalesVirtualModule(_locales: ScannedLocale[], defaultLocale: string | undefined, srcDir?: string): VirtualModule;
41
- //#endregion
42
- //#region src/registry.d.ts
43
- /**
44
- * Module extension registry.
45
- *
46
- * Allows built-in extension modules (@ubean/ui, @ubean/icon, etc.) to inject
47
- * component resolvers and CSS imports into the core Vite plugin pipeline
48
- * without modifying ubeanVuePlugin directly.
49
- *
50
- * Registration happens at module load time (when ubeanUiPlugin() etc. are
51
- * called by the module system, before ubeanVuePlugin reads the registry).
52
- *
53
- * Uses globalThis for storage to ensure state is shared across multiple
54
- * copies of @ubean/build that may exist due to package manager duplication
55
- * (e.g. pnpm creating separate instances for different version ranges).
56
- */
57
- /**
58
- * Generic component resolver type compatible with unplugin-vue-components.
59
- * Accepts both function resolvers and object resolvers (ComponentResolverObject).
60
- */
61
- type ComponentResolver = ((name: string) => any) | {
62
- type: 'component' | 'directive';
63
- resolve: (name: string) => any;
64
- };
65
- /**
66
- * Register a component resolver (e.g. `UiResolver()` from `@soybeanjs/ui/resolver`).
67
- * The resolver will be merged into `unplugin-vue-components`'s `resolvers` array.
68
- */
69
- declare function registerComponentResolver(resolver: ComponentResolver): void;
70
- /**
71
- * Get all registered component resolvers.
72
- * Called by `ubeanVuePlugin` when constructing the `Components()` plugin.
73
- */
74
- declare function getComponentResolvers(): ComponentResolver[];
75
- /**
76
- * Register a CSS import path to be injected into the client entry.
77
- * e.g. `registerCssImport('@soybeanjs/ui/styles.css')` makes the client
78
- * entry module prepend `import '@soybeanjs/ui/styles.css'`.
79
- */
80
- declare function registerCssImport(cssPath: string): void;
81
- /**
82
- * Get all registered CSS import paths.
83
- * Called by `createClientEntryVirtualModule` to prepend CSS imports.
84
- */
85
- declare function getCssImports(): string[];
86
- /**
87
- * Reset the registry (for testing).
88
- * @internal
89
- */
90
- declare function resetModuleRegistry(): void;
5
+ declare function createRoutingVirtualModule(routes: CompiledRoute[], middlewares: CompiledMiddleware[], cwd: string): any;
6
+ declare function createPagesVirtualModule(pages: CompiledPage[], layouts: CompiledLayout[], cwd: string): any;
7
+ declare function createMetaVirtualModule(): any;
8
+ declare function createAppVirtualModule(apiRoutes: ScannedApiRoute[], middlewares: ScannedMiddleware[], pages: ScannedPageRoute[], srcDir: string): any;
9
+ declare function createLocalesVirtualModule(_locales: ScannedLocale[], defaultLocale: string | undefined, srcDir?: string): any;
91
10
  //#endregion
92
11
  export { type VirtualModule, type VirtualModuleContext, VirtualModuleRegistry, type VirtualModuleTransform, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, stripMacros, transformMacros, useVirtualRegistry };
package/dist/index.js CHANGED
@@ -1,52 +1,3 @@
1
- import { a as createRoutingVirtualModule, c as VirtualModuleRegistry, d as resetVirtualRegistry, f as useVirtualRegistry, i as createPagesVirtualModule, l as defineVirtualModule, n as createLocalesVirtualModule, o as stripMacros, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule, u as defineVirtualModulePrefix } from "./virtual-modules-DR_ynMd0.js";
2
- //#region src/registry.ts
3
- const REGISTRY_KEY = "__ubean_module_registry__";
4
- function getRegistry() {
5
- const g = globalThis;
6
- if (!g[REGISTRY_KEY]) g[REGISTRY_KEY] = {
7
- componentResolvers: [],
8
- cssImports: []
9
- };
10
- return g[REGISTRY_KEY];
11
- }
12
- /**
13
- * Register a component resolver (e.g. `UiResolver()` from `@soybeanjs/ui/resolver`).
14
- * The resolver will be merged into `unplugin-vue-components`'s `resolvers` array.
15
- */
16
- function registerComponentResolver(resolver) {
17
- getRegistry().componentResolvers.push(resolver);
18
- }
19
- /**
20
- * Get all registered component resolvers.
21
- * Called by `ubeanVuePlugin` when constructing the `Components()` plugin.
22
- */
23
- function getComponentResolvers() {
24
- return [...getRegistry().componentResolvers];
25
- }
26
- /**
27
- * Register a CSS import path to be injected into the client entry.
28
- * e.g. `registerCssImport('@soybeanjs/ui/styles.css')` makes the client
29
- * entry module prepend `import '@soybeanjs/ui/styles.css'`.
30
- */
31
- function registerCssImport(cssPath) {
32
- const reg = getRegistry();
33
- if (!reg.cssImports.includes(cssPath)) reg.cssImports.push(cssPath);
34
- }
35
- /**
36
- * Get all registered CSS import paths.
37
- * Called by `createClientEntryVirtualModule` to prepend CSS imports.
38
- */
39
- function getCssImports() {
40
- return [...getRegistry().cssImports];
41
- }
42
- /**
43
- * Reset the registry (for testing).
44
- * @internal
45
- */
46
- function resetModuleRegistry() {
47
- const reg = getRegistry();
48
- reg.componentResolvers.length = 0;
49
- reg.cssImports.length = 0;
50
- }
51
- //#endregion
1
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-BDgTqx3t.js";
2
+ import { VirtualModuleRegistry, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, stripMacros, transformMacros, useVirtualRegistry } from "@ubean/build-core";
52
3
  export { VirtualModuleRegistry, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, stripMacros, transformMacros, useVirtualRegistry };
@@ -1,5 +1,5 @@
1
1
  import { ResolvedConfig } from "@ubean/config";
2
- import { ScanResult } from "@ubean/routing";
2
+ import { ScanResult } from "@ubean/scan";
3
3
  import { Preset } from "@ubean/preset";
4
4
  //#region src/production.d.ts
5
5
  interface BuildOptions {
@@ -1,17 +1,19 @@
1
- import { a as createRoutingVirtualModule, f as useVirtualRegistry, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-DR_ynMd0.js";
1
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-BDgTqx3t.js";
2
2
  import { ubeanPlugin } from "./vite.js";
3
+ import { useVirtualRegistry } from "@ubean/build-core";
3
4
  import { join, relative, resolve } from "pathe";
4
5
  import { existsSync } from "node:fs";
5
6
  import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
6
7
  import { build } from "vite";
7
8
  import vue from "@vitejs/plugin-vue";
8
- import { ubeanIslandsPlugin } from "@ubean/islands";
9
+ import { getColorModeScript, resolveColorModeConfig } from "@ubean/client";
10
+ import { ubeanIslandsPlugin } from "@ubean/islands/vite";
11
+ import { getLogger } from "@ubean/logger";
9
12
  import { resolveModules } from "@ubean/modules";
10
- import { findUserViteConfig } from "@ubean/utils";
11
- import { VUE_PLUGIN_INCLUDE, createClientEntryVirtualModule, createServerEntryVirtualModule, createVueAppEntryVirtualModule, createVuePagesVirtualModule, ubeanVuePlugin } from "@ubean/vite";
12
- import { consola } from "consola";
13
+ import { findUserViteConfig } from "@ubean/shared/node";
14
+ import { VUE_PLUGIN_INCLUDE, createClientEntryVirtualModule, createServerEntryVirtualModule, createVueAppEntryVirtualModule, createVuePagesVirtualModule, ubeanVite } from "@ubean/vite";
13
15
  //#region src/production.ts
14
- const logger = consola.withTag("ubean-build");
16
+ const logger = getLogger("build");
15
17
  function getOutDirs(cwd, outputDir) {
16
18
  const outputRoot = resolve(cwd, outputDir);
17
19
  return {
@@ -33,7 +35,8 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir)
33
35
  await mkdir(virtualDir, { recursive: true });
34
36
  const registry = useVirtualRegistry();
35
37
  registry.clear();
36
- const viteSrcDir = toVitePath(relative(cwd, resolve(cwd, config.srcDir)));
38
+ const srcDirAbs = resolve(cwd, config.srcDir);
39
+ const viteSrcDir = toVitePath(relative(cwd, srcDirAbs));
37
40
  const viteSrcPrefix = viteSrcDir ? `/${viteSrcDir}` : "";
38
41
  registry.register(createRoutingVirtualModule(scanResult.apiRoutes.map((r) => ({
39
42
  method: r.method?.toUpperCase() || "ALL",
@@ -59,7 +62,7 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir)
59
62
  isDefault: l.isDefault
60
63
  })), cwd));
61
64
  registry.register(createMetaVirtualModule());
62
- registry.register(createVuePagesVirtualModule(scanResult.pages, scanResult.layouts));
65
+ registry.register(createVuePagesVirtualModule(scanResult.pages, scanResult.layouts, scanResult.notFoundPage, scanResult.loadingPage, scanResult.errorPage));
63
66
  registry.register(createVueAppEntryVirtualModule(scanResult.appEntry));
64
67
  registry.register(createClientEntryVirtualModule());
65
68
  }
@@ -82,11 +85,13 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir)
82
85
  await writeModule("virtual:ubean-client-entry", "client-entry.mjs", "");
83
86
  }
84
87
  if (hasServer) await writeModule("virtual:ubean-server", "server-entry.ts", "");
88
+ await writeFile(join(virtualDir, "islands-registry.ts"), "export const islands = {};\n", "utf-8");
85
89
  const pagesGlob = JSON.stringify(`${viteSrcPrefix}/pages/**/*.{vue,ts,tsx,js,jsx,md,mdx}`);
86
90
  const routesGlob = JSON.stringify(`${viteSrcPrefix}/routes/**/*.{ts,js,mjs}`);
87
91
  const middlewareGlob = JSON.stringify(`${viteSrcPrefix}/middleware/**/*.{ts,js,mjs}`);
88
92
  const layoutsGlob = JSON.stringify(`${viteSrcPrefix}/layouts/**/*.{vue,ts}`);
89
- const publicDir = toVitePath(resolve(cwd, config.build.outputDir || "dist", "public"));
93
+ const outputDir = config.build.outputDir || "dist";
94
+ const publicDir = toVitePath(resolve(cwd, outputDir, "public"));
90
95
  const routesJson = JSON.stringify(scanResult.apiRoutes.map((r) => ({
91
96
  relativePath: r.relativePath,
92
97
  route: r.route,
@@ -112,6 +117,14 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir)
112
117
  relativePath: l.relativePath,
113
118
  isDefault: l.isDefault
114
119
  })));
120
+ const notFoundPageJson = JSON.stringify(scanResult.notFoundPage ? {
121
+ relativePath: scanResult.notFoundPage.relativePath,
122
+ name: scanResult.notFoundPage.name,
123
+ route: scanResult.notFoundPage.route,
124
+ layout: scanResult.notFoundPage.layout,
125
+ pageMeta: scanResult.notFoundPage.pageMeta
126
+ } : null);
127
+ const colorModeScript = config.colorMode !== false ? getColorModeScript(resolveColorModeConfig(config.colorMode)) : "";
115
128
  const rendererImport = ssrEnabled ? `import { createVueRenderer } from 'ubean/vue-ssr';` : "";
116
129
  const rendererSetup = ssrEnabled ? `
117
130
  // --- SSR renderer setup ---
@@ -217,10 +230,11 @@ const _routes = ${routesJson};
217
230
  const _middleware = ${middlewareJson};
218
231
  const _pages = ${pagesJson};
219
232
  const _layouts = ${layoutsJson};
233
+ const _notFoundPage = ${notFoundPageJson};
220
234
  ${rendererSetup}
221
235
  // --- Client asset tags from Vite manifest ---
222
236
  const __dirname = dirname(fileURLToPath(import.meta.url));
223
- let _assetTags = { css: '', preloads: '', body: '' };
237
+ let _assetTags = { css: '', preloads: '', body: '', favicon: ${JSON.stringify(config.favicon)} };
224
238
  try {
225
239
  const manifestPath = join(__dirname, '..', 'public', '.vite', 'manifest.json');
226
240
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
@@ -250,6 +264,9 @@ export async function createApp(options = {}) {
250
264
  publicDir: ${JSON.stringify(publicDir)},
251
265
  i18nConfig: ${JSON.stringify(config.i18n)},
252
266
  ssrExclude: ${JSON.stringify(config.ssr?.exclude ?? [])},
267
+ streaming: ${JSON.stringify(config.ssr?.streaming ?? false)},
268
+ notFoundPage: _notFoundPage || undefined,
269
+ colorModeScript: ${JSON.stringify(colorModeScript)},
253
270
  ...options
254
271
  });
255
272
 
@@ -441,7 +458,7 @@ async function buildProduction(options) {
441
458
  }));
442
459
  if (!userViteConfig) {
443
460
  builtinPlugins.push(ubeanPlugin({ config }));
444
- if (hasPages) builtinPlugins.push(...ubeanVuePlugin({ config }), ubeanIslandsPlugin());
461
+ if (hasPages) builtinPlugins.push(...ubeanVite({ config }), ubeanIslandsPlugin());
445
462
  }
446
463
  const { plugins } = await resolveModules({
447
464
  cwd,
@@ -547,7 +564,7 @@ async function buildProduction(options) {
547
564
  sourcemap,
548
565
  rollupOptions: {
549
566
  input: serverEntryPath,
550
- external: presetBuildConfig.external,
567
+ external: presetBuildConfig.external.filter((e) => !(e instanceof RegExp && e.source.startsWith("^ubean"))),
551
568
  output: {
552
569
  format: presetBuildConfig.format,
553
570
  entryFileNames: "entry.mjs",
@@ -557,7 +574,16 @@ async function buildProduction(options) {
557
574
  },
558
575
  emptyOutDir: false
559
576
  },
560
- plugins: [...plugins],
577
+ plugins: [...plugins, {
578
+ name: "ubean:islands-ssr-stub",
579
+ enforce: "pre",
580
+ resolveId(id) {
581
+ if (id === "virtual:ubean-islands-registry") return "\0virtual:ubean-islands-registry";
582
+ },
583
+ load(id) {
584
+ if (id === "\0virtual:ubean-islands-registry") return "export const islands = {};";
585
+ }
586
+ }],
561
587
  resolve: commonResolve
562
588
  });
563
589
  serverEntry = "entry.mjs";
@@ -600,7 +626,7 @@ assets = { directory = "./public" }
600
626
  preset: preset.name || "standard"
601
627
  };
602
628
  await writeFile(join(outDirs.root, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
603
- logger.success(`Build complete! Output: ${outDirs.root}`);
629
+ logger.info(`Build complete! Output: ${outDirs.root}`);
604
630
  if (hasPages) logger.info(` Client assets: ${outDirs.public}`);
605
631
  if (hasServer) {
606
632
  logger.info(` Server bundle: ${outDirs.server}`);
@@ -1,175 +1,5 @@
1
+ import { defineVirtualModule } from "@ubean/build-core";
1
2
  import { isAbsolute, relative } from "pathe";
2
- //#region src/virtual-registry.ts
3
- var VirtualModuleRegistry = class {
4
- modules = /* @__PURE__ */ new Map();
5
- invalidated = /* @__PURE__ */ new Set();
6
- register(mod) {
7
- this.modules.set(mod.id, mod);
8
- }
9
- resolveId(id, importer) {
10
- if (this.modules.has(id)) return id;
11
- for (const mod of this.modules.values()) {
12
- const resolved = mod.resolve(id, importer);
13
- if (resolved) return resolved;
14
- }
15
- }
16
- async load(id) {
17
- const mod = this.modules.get(id);
18
- if (!mod) return void 0;
19
- return mod.load();
20
- }
21
- invalidate(id) {
22
- this.invalidated.add(id);
23
- }
24
- isInvalidated(id) {
25
- return this.invalidated.has(id);
26
- }
27
- clearInvalidated() {
28
- this.invalidated.clear();
29
- }
30
- getModules() {
31
- return [...this.modules.values()];
32
- }
33
- clear() {
34
- this.modules.clear();
35
- this.invalidated.clear();
36
- }
37
- };
38
- let _registry = null;
39
- function useVirtualRegistry() {
40
- if (!_registry) _registry = new VirtualModuleRegistry();
41
- return _registry;
42
- }
43
- function resetVirtualRegistry() {
44
- _registry = null;
45
- }
46
- function defineVirtualModule(id, loader) {
47
- return {
48
- id,
49
- resolve(resolvedId) {
50
- return resolvedId === id ? id : void 0;
51
- },
52
- load: loader
53
- };
54
- }
55
- function defineVirtualModulePrefix(prefix, loader) {
56
- return {
57
- id: prefix,
58
- resolve(id) {
59
- if (id.startsWith(prefix)) return id;
60
- },
61
- load(id) {
62
- return loader(id || prefix);
63
- }
64
- };
65
- }
66
- //#endregion
67
- //#region src/macros.ts
68
- const MACRO_NAMES = ["definePage"];
69
- function findBalancedCall(code, funcName, startSearch = 0) {
70
- const pattern = new RegExp(`\\b${funcName}\\s*\\(`, "g");
71
- pattern.lastIndex = startSearch;
72
- const match = pattern.exec(code);
73
- if (!match) return null;
74
- const startIdx = match.index;
75
- const parenStart = match.index + match[0].length;
76
- let depth = 1;
77
- let i = parenStart;
78
- let inString = null;
79
- let escaped = false;
80
- let inTemplateExpr = 0;
81
- while (i < code.length && depth > 0) {
82
- const ch = code[i];
83
- if (escaped) {
84
- escaped = false;
85
- i++;
86
- continue;
87
- }
88
- if (ch === "\\") {
89
- escaped = true;
90
- i++;
91
- continue;
92
- }
93
- if (inString) {
94
- if (inString === "`" && ch === "$" && code[i + 1] === "{") {
95
- inTemplateExpr++;
96
- i += 2;
97
- continue;
98
- }
99
- if (inString === "`" && ch === "}" && inTemplateExpr > 0) {
100
- inTemplateExpr--;
101
- i++;
102
- continue;
103
- }
104
- if (ch === inString) inString = null;
105
- i++;
106
- continue;
107
- }
108
- if (ch === "\"" || ch === "'" || ch === "`") {
109
- inString = ch;
110
- i++;
111
- continue;
112
- }
113
- if (ch === "/" && code[i + 1] === "/") {
114
- while (i < code.length && code[i] !== "\n") i++;
115
- continue;
116
- }
117
- if (ch === "/" && code[i + 1] === "*") {
118
- i += 2;
119
- while (i < code.length && !(code[i] === "*" && code[i + 1] === "/")) i++;
120
- i += 2;
121
- continue;
122
- }
123
- if (ch === "(" || ch === "{" || ch === "[") depth++;
124
- else if (ch === ")" || ch === "}" || ch === "]") {
125
- depth--;
126
- if (depth === 0 && ch === ")") return {
127
- start: startIdx,
128
- end: i + 1
129
- };
130
- }
131
- i++;
132
- }
133
- return null;
134
- }
135
- function stripStatement(code, callStart, callEnd) {
136
- let start = callStart;
137
- let end = callEnd;
138
- while (start > 0 && /[ \t]/.test(code[start - 1])) start--;
139
- const exportDefaultMatch = code.slice(0, start).match(/export\s+default\s*$/);
140
- if (exportDefaultMatch) {
141
- start -= exportDefaultMatch[0].length;
142
- while (start > 0 && /[ \t\n\r]/.test(code[start - 1])) start--;
143
- }
144
- if (code[end] === ";") end++;
145
- while (end < code.length && /[ \t]/.test(code[end])) end++;
146
- return code.slice(0, start) + code.slice(end);
147
- }
148
- function stripMacros(code, macros = MACRO_NAMES) {
149
- let result = code;
150
- for (const macro of macros) {
151
- let offset = 0;
152
- while (true) {
153
- const found = findBalancedCall(result, macro, offset);
154
- if (!found) break;
155
- result = stripStatement(result, found.start, found.end);
156
- offset = found.start;
157
- }
158
- }
159
- return result;
160
- }
161
- function transformMacros(code, id) {
162
- if (!(id.includes("/src/pages/") || id.includes("/src/routes/") || id.includes("/src/middleware/"))) return null;
163
- if (id.endsWith(".vue")) return transformVueMacros(code);
164
- if (/\.(ts|js|mjs|mts|tsx|jsx)$/.test(id)) return stripMacros(code);
165
- return null;
166
- }
167
- function transformVueMacros(code) {
168
- return code.replace(/<script([^>]*)>([\s\S]*?)<\/script>/g, (_match, attrs, content) => {
169
- return `<script${attrs}>${stripMacros(content)}<\/script>`;
170
- });
171
- }
172
- //#endregion
173
3
  //#region src/virtual-modules.ts
174
4
  function toVitePath(p) {
175
5
  return p.replace(/\\/g, "/");
@@ -266,7 +96,7 @@ export default { routeLoaders, middlewareLoaders, pageLoaders, apiRoutes, middle
266
96
  }
267
97
  function createLocalesVirtualModule(_locales, defaultLocale, srcDir = "src") {
268
98
  return defineVirtualModule("ubean:locales", () => {
269
- const defaultCode = JSON.stringify(defaultLocale);
99
+ const defaultCode = defaultLocale == null ? "null" : JSON.stringify(defaultLocale);
270
100
  const viteSrcDir = toVitePath(srcDir);
271
101
  const prefix = viteSrcDir === "/" || viteSrcDir === "" ? "" : viteSrcDir;
272
102
  return `
@@ -414,4 +244,4 @@ if (import.meta.hot) {
414
244
  });
415
245
  }
416
246
  //#endregion
417
- export { createRoutingVirtualModule as a, VirtualModuleRegistry as c, resetVirtualRegistry as d, useVirtualRegistry as f, createPagesVirtualModule as i, defineVirtualModule as l, createLocalesVirtualModule as n, stripMacros as o, createMetaVirtualModule as r, transformMacros as s, createAppVirtualModule as t, defineVirtualModulePrefix as u };
247
+ export { createRoutingVirtualModule as a, createPagesVirtualModule as i, createLocalesVirtualModule as n, createMetaVirtualModule as r, createAppVirtualModule as t };
package/dist/vite.d.ts CHANGED
@@ -16,10 +16,10 @@ interface UbeanPluginOptions {
16
16
  * - 虚拟模块(`ubean:routes`、`ubean:pages`、`ubean:meta`、`ubean:app-config`、`ubean:locales`)
17
17
  * - 宏转换(`definePage` / `defineMeta` 在 `.ts` / `.vue` 中被剥离)
18
18
  * - 文件监听(dev 模式下扫描 `routes` / `middleware` / `pages` / `layouts` / `plugins` / `locales`)
19
- * - 实体路由文件生成(当 `routing.mode` 为 `'file'` 或 `'both'` 时触发 `@ubean/routing/generator`)
19
+ * - 实体路由文件生成(当 `routing.mode` 为 `'file'` 或 `'both'` 时触发 `@ubean/vue/generator`)
20
20
  *
21
21
  * Vue 专属的虚拟模块(`virtual:ubean-pages`、`virtual:ubean-app` 等)由 `@ubean/vite` 的
22
- * `ubeanVuePlugin` 提供,二者共用 `useVirtualRegistry()` 注册表。
22
+ * `ubeanVite` 提供,二者共用 `useVirtualRegistry()` 注册表。
23
23
  *
24
24
  * @example 在 vite.config.ts 中使用(自动加载 ubean.config)
25
25
  * ```typescript
package/dist/vite.js CHANGED
@@ -1,7 +1,9 @@
1
- import { a as createRoutingVirtualModule, f as useVirtualRegistry, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-DR_ynMd0.js";
1
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-BDgTqx3t.js";
2
+ import { transformMacros, useVirtualRegistry } from "@ubean/build-core";
2
3
  import { join, relative, resolve } from "pathe";
3
4
  import { loadUbeanConfig, tryGetConfig } from "@ubean/config";
4
- import { createUbeanRouter, scanProject } from "@ubean/routing";
5
+ import { createServerRouter } from "@ubean/routes";
6
+ import { scanProject } from "@ubean/scan";
5
7
  //#region src/vite.ts
6
8
  const VIRTUAL_MODULES = [
7
9
  "ubean:routes",
@@ -18,10 +20,10 @@ const VIRTUAL_PREFIX = "\0ubean:";
18
20
  * - 虚拟模块(`ubean:routes`、`ubean:pages`、`ubean:meta`、`ubean:app-config`、`ubean:locales`)
19
21
  * - 宏转换(`definePage` / `defineMeta` 在 `.ts` / `.vue` 中被剥离)
20
22
  * - 文件监听(dev 模式下扫描 `routes` / `middleware` / `pages` / `layouts` / `plugins` / `locales`)
21
- * - 实体路由文件生成(当 `routing.mode` 为 `'file'` 或 `'both'` 时触发 `@ubean/routing/generator`)
23
+ * - 实体路由文件生成(当 `routing.mode` 为 `'file'` 或 `'both'` 时触发 `@ubean/vue/generator`)
22
24
  *
23
25
  * Vue 专属的虚拟模块(`virtual:ubean-pages`、`virtual:ubean-app` 等)由 `@ubean/vite` 的
24
- * `ubeanVuePlugin` 提供,二者共用 `useVirtualRegistry()` 注册表。
26
+ * `ubeanVite` 提供,二者共用 `useVirtualRegistry()` 注册表。
25
27
  *
26
28
  * @example 在 vite.config.ts 中使用(自动加载 ubean.config)
27
29
  * ```typescript
@@ -107,7 +109,6 @@ function ubeanPlugin(options) {
107
109
  event: "ubean:locale-update",
108
110
  data: { file }
109
111
  });
110
- else server.ws.send({ type: "full-reload" });
111
112
  }
112
113
  }
113
114
  }
@@ -120,7 +121,7 @@ function ubeanPlugin(options) {
120
121
  dirs: ubeanConfig.dir,
121
122
  ignore: ubeanConfig.scanOptions?.ignore
122
123
  });
123
- const router = createUbeanRouter();
124
+ const router = createServerRouter();
124
125
  for (const mw of result.middlewares) router.addMiddleware(mw);
125
126
  for (const route of result.apiRoutes) router.addApiRoute(route);
126
127
  for (const page of result.pages) router.addPage(page);
@@ -162,15 +163,15 @@ function ubeanPlugin(options) {
162
163
  * - `'file'`:额外生成 `routes.ts`/`imports.ts` 到 `outputDir`(实体文件,可编辑 `meta`)
163
164
  * - `'both'`:同 `'file'`,且虚拟模块也加载实体文件
164
165
  *
165
- * `typed-router.d.ts` 包含 `@ubean/routing` 和 `vue-router`/`vue-router/auto-routes`
166
+ * `typed-router.d.ts` 包含 `@ubean/scan` 和 `vue-router`/`vue-router/auto-routes`
166
167
  * 的模块增强(让 `useRoute<Name>(name)` 能推断 `route.params` 类型),所有模式
167
168
  * 都会生成到 `.ubean/typed-router.d.ts`,与 `auto-imports.d.ts`/`components.d.ts`
168
169
  * 等其他纯类型声明产物同目录,由 `.gitignore` 忽略。
169
170
  *
170
- * 由于 `@ubean/routing/generator` 通过动态 import 加载,前端-only 项目
171
+ * 由于 `@ubean/vue/generator` 通过动态 import 加载,前端-only 项目
171
172
  * (不依赖实体路由文件)即使没有安装 generator 相关依赖也能运行。
172
173
  *
173
- * 注意:`@ubean/config` 与 `@ubean/routing/generator` 的 `getRouteMeta` /
174
+ * 注意:`@ubean/config` 与 `@ubean/vue/generator` 的 `getRouteMeta` /
174
175
  * `onGenerated` 签名略有差异(配置层面向用户,生成器层面向内部)。本函数
175
176
  * 负责适配:把 `(filePath, frontmatter) => meta` 包装为 `(page) => meta`,
176
177
  * 把 `GeneratorResult` 转换为 `string[]` 文件路径列表。
@@ -183,7 +184,7 @@ async function maybeGenerateRouteFiles(config, scanResult) {
183
184
  const dtsPath = resolve(config.rootDir, ".ubean", "typed-router.d.ts");
184
185
  const configGetRouteMeta = routing.getRouteMeta;
185
186
  const generatorGetRouteMeta = configGetRouteMeta ? (page) => configGetRouteMeta(page.relativePath, page.frontmatter ?? {}) : void 0;
186
- const { generateRouteFiles } = await import("@ubean/routing/generator");
187
+ const { generateRouteFiles } = await import("@ubean/vue/generator");
187
188
  const result = await generateRouteFiles(scanResult, {
188
189
  cwd: config.rootDir,
189
190
  srcDir: config.srcDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/build",
3
- "version": "0.1.12",
3
+ "version": "0.2.0",
4
4
  "description": "Core Vite plugin (framework-agnostic) for ubean (ubeanPlugin, virtual modules: routes/pages/meta/app-config/locales, macros)",
5
5
  "files": [
6
6
  "dist"
@@ -25,26 +25,30 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@vitejs/plugin-vue": "^6.0.8",
28
- "consola": "^3.4.2",
29
- "oxc-transform": "^0.142.0",
28
+ "oxc-transform": "^0.144.0",
30
29
  "pathe": "^2.0.3",
31
- "@ubean/config": "0.1.12",
32
- "@ubean/islands": "0.1.12",
33
- "@ubean/modules": "0.1.12",
34
- "@ubean/preset": "0.1.12",
35
- "@ubean/ssr": "0.1.12",
36
- "@ubean/vite": "0.1.12",
37
- "@ubean/routing": "0.1.12",
38
- "@ubean/utils": "0.1.12"
30
+ "@ubean/build-core": "0.2.0",
31
+ "@ubean/logger": "0.2.0",
32
+ "@ubean/client": "0.2.0",
33
+ "@ubean/islands": "0.2.0",
34
+ "@ubean/config": "0.2.0",
35
+ "@ubean/preset": "0.2.0",
36
+ "@ubean/modules": "0.2.0",
37
+ "@ubean/routes": "0.2.0",
38
+ "@ubean/scan": "0.2.0",
39
+ "@ubean/ssr": "0.2.0",
40
+ "@ubean/shared": "0.2.0",
41
+ "@ubean/vue": "0.2.0",
42
+ "@ubean/vite": "0.2.0"
39
43
  },
40
44
  "devDependencies": {
41
- "@types/node": "^26.1.2",
45
+ "@types/node": "^26.2.0",
42
46
  "typescript": "7.0.2",
43
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6",
44
- "vite-plus": "0.2.6"
47
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.2.9",
48
+ "vite-plus": "0.2.9"
45
49
  },
46
50
  "peerDependencies": {
47
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6"
51
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.2.9"
48
52
  },
49
53
  "peerDependenciesMeta": {
50
54
  "vite": {
@@ -54,6 +58,7 @@
54
58
  "scripts": {
55
59
  "build": "vp pack",
56
60
  "dev": "vp pack --watch",
61
+ "test": "vp test",
57
62
  "typecheck": "tsc --noEmit --skipLibCheck"
58
63
  }
59
64
  }