vike-lite 1.6.2 → 1.7.1
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 +4 -3
- package/dist/__internal/server.d.mts +2 -2
- package/dist/server.mjs +3 -3
- package/dist/vite.d.mts +7 -1
- package/dist/vite.mjs +87 -18
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -18,9 +18,10 @@ import vikeLite from 'vike-lite/vite'
|
|
|
18
18
|
export default {
|
|
19
19
|
plugins: [
|
|
20
20
|
vikeLite({
|
|
21
|
-
pagesDir = 'pages', //
|
|
22
|
-
serverEntry = 'server/index', //
|
|
23
|
-
apiPrefix = '/api' //
|
|
21
|
+
pagesDir = 'pages', // Default
|
|
22
|
+
serverEntry = 'server/index', // Default
|
|
23
|
+
apiPrefix = '/api', // Default
|
|
24
|
+
prerender = false // Default
|
|
24
25
|
})
|
|
25
26
|
]
|
|
26
27
|
} satisfies UserConfig
|
|
@@ -2,8 +2,8 @@ import { t as Config } from "../index-Dt5n1zWh.mjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/server/store.d.ts
|
|
4
4
|
interface VikeState {
|
|
5
|
-
routes:
|
|
6
|
-
errorRoute:
|
|
5
|
+
routes: typeof import('virtual:routes')['routes'];
|
|
6
|
+
errorRoute: typeof import('virtual:routes')['errorRoute'] | null;
|
|
7
7
|
config: Config | null;
|
|
8
8
|
manifest: Manifest | undefined;
|
|
9
9
|
}
|
package/dist/server.mjs
CHANGED
|
@@ -74,8 +74,8 @@ async function buildPageContext(urlPathname, urlOriginal, isJsonRequest) {
|
|
|
74
74
|
urlPathname
|
|
75
75
|
};
|
|
76
76
|
const [dataMod, titleMod, PageModule, HeadModule, LayoutModule] = await Promise.all([
|
|
77
|
-
route.
|
|
78
|
-
route.
|
|
77
|
+
route.Data?.() ?? null,
|
|
78
|
+
route.Title?.() ?? null,
|
|
79
79
|
isJsonRequest ? null : route.Page(),
|
|
80
80
|
isJsonRequest ? null : route.Head?.() ?? null,
|
|
81
81
|
isJsonRequest ? null : route.Layout?.() ?? null
|
|
@@ -137,7 +137,7 @@ async function renderErrorPage(req, status, urlPathname, error) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
async function renderPage(req) {
|
|
140
|
-
let pathname = new URL(req.url)
|
|
140
|
+
let { pathname } = new URL(req.url);
|
|
141
141
|
if (BASE_URL !== "/") {
|
|
142
142
|
const baseSlashed = BASE_URL.endsWith("/") ? BASE_URL : BASE_URL + "/";
|
|
143
143
|
const baseNoSlash = baseSlashed.slice(0, -1);
|
package/dist/vite.d.mts
CHANGED
|
@@ -4,7 +4,8 @@ import { Plugin } from "vite";
|
|
|
4
4
|
declare function routerPlugin({
|
|
5
5
|
pagesDir,
|
|
6
6
|
serverEntry,
|
|
7
|
-
apiPrefix
|
|
7
|
+
apiPrefix,
|
|
8
|
+
prerender
|
|
8
9
|
}?: {
|
|
9
10
|
/**
|
|
10
11
|
* The directory where your page components are located.
|
|
@@ -24,6 +25,11 @@ declare function routerPlugin({
|
|
|
24
25
|
* @default '/api'
|
|
25
26
|
*/
|
|
26
27
|
apiPrefix?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to prerender the pages.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
prerender?: boolean;
|
|
27
33
|
}): Plugin;
|
|
28
34
|
//#endregion
|
|
29
35
|
export { routerPlugin as default };
|
package/dist/vite.mjs
CHANGED
|
@@ -4,6 +4,11 @@ import { Readable } from "node:stream";
|
|
|
4
4
|
import { pipeline } from "node:stream/promises";
|
|
5
5
|
import { loadEnv } from "vite";
|
|
6
6
|
//#region src/utils/generateRoutes.ts
|
|
7
|
+
const pageExtensions = [".ts", ".js"];
|
|
8
|
+
const pageExtensionsX = [".tsx", ".jsx"];
|
|
9
|
+
function findFile(files, basename, extensions) {
|
|
10
|
+
return files.find((file) => extensions.some((ext) => file === `${basename}${ext}`));
|
|
11
|
+
}
|
|
7
12
|
function generateRoutes(viteRoot, pagesDir) {
|
|
8
13
|
const pagesAbsPath = path.resolve(viteRoot, pagesDir);
|
|
9
14
|
if (!fs.existsSync(pagesAbsPath)) return { routes: [] };
|
|
@@ -12,15 +17,22 @@ function generateRoutes(viteRoot, pagesDir) {
|
|
|
12
17
|
function walk(dir, routePath, parentLayout, parentHead) {
|
|
13
18
|
const files = fs.readdirSync(dir);
|
|
14
19
|
const importPath = path.relative(viteRoot, dir).replaceAll("\\", "/");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
20
|
+
const layoutFile = findFile(files, "+Layout", pageExtensionsX);
|
|
21
|
+
const currentLayout = layoutFile ? `${importPath}/${layoutFile}` : parentLayout;
|
|
22
|
+
const headFile = findFile(files, "+Head", pageExtensionsX);
|
|
23
|
+
const currentHead = headFile ? `${importPath}/${headFile}` : parentHead;
|
|
24
|
+
const pageFile = findFile(files, "+Page", pageExtensionsX);
|
|
25
|
+
if (pageFile) {
|
|
18
26
|
const route = {
|
|
19
27
|
path: routePath || "/",
|
|
20
|
-
page: `${importPath}
|
|
21
|
-
hasData: files.includes("+data.ts"),
|
|
22
|
-
hasTitle: files.includes("+title.ts")
|
|
28
|
+
page: `${importPath}/${pageFile}`
|
|
23
29
|
};
|
|
30
|
+
const dataFile = findFile(files, "+data", pageExtensions);
|
|
31
|
+
const titleFile = findFile(files, "+title", pageExtensions);
|
|
32
|
+
const prerenderFile = findFile(files, "+prerender", pageExtensions);
|
|
33
|
+
if (dataFile) route.data = `${importPath}/${dataFile}`;
|
|
34
|
+
if (titleFile) route.title = `${importPath}/${titleFile}`;
|
|
35
|
+
if (prerenderFile) route.prerender = `${importPath}/${prerenderFile}`;
|
|
24
36
|
if (currentLayout) route.layout = currentLayout;
|
|
25
37
|
if (currentHead) route.head = currentHead;
|
|
26
38
|
routes.push(route);
|
|
@@ -29,9 +41,10 @@ function generateRoutes(viteRoot, pagesDir) {
|
|
|
29
41
|
const fullPath = path.join(dir, file);
|
|
30
42
|
if (!fs.statSync(fullPath).isDirectory()) continue;
|
|
31
43
|
if (file === "_error") {
|
|
32
|
-
|
|
44
|
+
const errorPageFile = findFile(fs.readdirSync(fullPath), "+Page", pageExtensionsX);
|
|
45
|
+
if (errorPageFile) errorRoute = {
|
|
33
46
|
path: "_error",
|
|
34
|
-
page: `${importPath}/_error
|
|
47
|
+
page: `${importPath}/_error/${errorPageFile}`,
|
|
35
48
|
layout: currentLayout,
|
|
36
49
|
head: currentHead
|
|
37
50
|
};
|
|
@@ -85,7 +98,7 @@ async function injectFOUCStyles(server, html) {
|
|
|
85
98
|
const SUPPORTED_RENDERERS = ["solid"];
|
|
86
99
|
//#endregion
|
|
87
100
|
//#region src/vite-plugin.ts
|
|
88
|
-
function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPrefix = "/api" } = {}) {
|
|
101
|
+
function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPrefix = "/api", prerender = false } = {}) {
|
|
89
102
|
const isProd = process.env.NODE_ENV === "production";
|
|
90
103
|
let viteConfigRoot;
|
|
91
104
|
let outDir;
|
|
@@ -172,10 +185,13 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
|
|
|
172
185
|
code += `{path:'${r.path}',page:'${r.page}',Page:()=>import('/${r.page}'),`;
|
|
173
186
|
if (r.head) code += `head:'${r.head}',Head:()=>import('/${r.head}'),`;
|
|
174
187
|
if (r.layout) code += `layout:'${r.layout}',Layout:()=>import('/${r.layout}'),`;
|
|
175
|
-
code += `
|
|
188
|
+
if (r.data) code += `data:'${r.data}',`;
|
|
189
|
+
if (r.title) code += `title:'${r.title}',`;
|
|
190
|
+
if (r.prerender) code += `prerender:'${r.prerender}',`;
|
|
176
191
|
if (isSSR) {
|
|
177
|
-
if (r.
|
|
178
|
-
if (r.
|
|
192
|
+
if (r.data) code += `Data:()=>import('/${r.data}'),`;
|
|
193
|
+
if (r.title) code += `Title:()=>import('/${r.title}'),`;
|
|
194
|
+
if (r.prerender) code += `Prerender:()=>import('/${r.prerender}'),`;
|
|
179
195
|
}
|
|
180
196
|
code += "},";
|
|
181
197
|
}
|
|
@@ -220,11 +236,8 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
|
|
|
220
236
|
break;
|
|
221
237
|
}
|
|
222
238
|
}
|
|
223
|
-
if (hasCustomServer) return `import '${virtualSetupId}';
|
|
224
|
-
|
|
225
|
-
export { default } from '${customServerPath}';`;
|
|
226
|
-
return String.raw`import '${virtualSetupId}';
|
|
227
|
-
import { renderPage } from 'vike-lite/server';
|
|
239
|
+
if (hasCustomServer) return `import '${virtualSetupId}';` + (prerender ? `export{routes}from'${virtualModuleId}';` : "") + `export * from'${customServerPath}';export{default}from'${customServerPath}';`;
|
|
240
|
+
return `import '${virtualSetupId}';` + (prerender ? `export{routes}from'${virtualModuleId}';` : "") + `import { renderPage } from 'vike-lite/server';
|
|
228
241
|
export default {
|
|
229
242
|
async fetch(request) {
|
|
230
243
|
return renderPage(request);
|
|
@@ -313,11 +326,67 @@ if (process.env.NODE_ENV === 'production') {
|
|
|
313
326
|
const { PORT } = process.env;
|
|
314
327
|
const port = PORT ? Number.parseInt(PORT) : 3000;
|
|
315
328
|
server.listen(port, () => {
|
|
316
|
-
console.log('\n\
|
|
329
|
+
console.log('\n\u{1B}[32m🚀 Server is running at http://localhost:' + port + '\u{1B}[0m\n');
|
|
317
330
|
});
|
|
318
331
|
}`;
|
|
319
332
|
}
|
|
320
333
|
},
|
|
334
|
+
async closeBundle() {
|
|
335
|
+
if (!prerender || !isProd || !import.meta.env.SSR) return;
|
|
336
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
337
|
+
const { pathToFileURL } = await import("node:url");
|
|
338
|
+
const serverEntryPath = path.resolve(viteConfigRoot, outDir, "server/index.mjs");
|
|
339
|
+
if (!fs.existsSync(serverEntryPath)) return;
|
|
340
|
+
const serverModule = await import(pathToFileURL(serverEntryPath).href);
|
|
341
|
+
const app = serverModule.default;
|
|
342
|
+
const routes = serverModule.routes || [];
|
|
343
|
+
const urlsToPrerender = /* @__PURE__ */ new Set();
|
|
344
|
+
for (const route of routes) {
|
|
345
|
+
let shouldPrerender = true;
|
|
346
|
+
let dynamicUrls = [];
|
|
347
|
+
if (route.Prerender) {
|
|
348
|
+
const mod = await route.Prerender();
|
|
349
|
+
const prerenderFn = mod.default ?? mod.prerender;
|
|
350
|
+
const result = typeof prerenderFn === "function" ? await prerenderFn() : prerenderFn;
|
|
351
|
+
if (result === false) shouldPrerender = false;
|
|
352
|
+
else if (result === true) shouldPrerender = true;
|
|
353
|
+
else if (Array.isArray(result)) {
|
|
354
|
+
shouldPrerender = true;
|
|
355
|
+
dynamicUrls = result;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (shouldPrerender) {
|
|
359
|
+
if (!route.path.includes(":")) urlsToPrerender.add(route.path === "/" ? "/" : route.path);
|
|
360
|
+
for (const url of dynamicUrls) urlsToPrerender.add(url);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (urlsToPrerender.size === 0) return;
|
|
364
|
+
console.log("\n\x1B[36m📦 Starting Static Site Generation (SSG)...\x1B[0m");
|
|
365
|
+
const base = process.env.BASE_URL || "/";
|
|
366
|
+
const baseNoSlash = base.endsWith("/") ? base.slice(0, -1) : base;
|
|
367
|
+
let generatedCount = 0;
|
|
368
|
+
const clientDir = path.resolve(viteConfigRoot, outDir, "client");
|
|
369
|
+
for (const urlPath of urlsToPrerender) {
|
|
370
|
+
const htmlReq = new Request(`http://localhost${baseNoSlash}${urlPath}`);
|
|
371
|
+
const htmlRes = await app.fetch(htmlReq);
|
|
372
|
+
if (htmlRes.ok && htmlRes.headers.get("content-type")?.includes("text/html")) {
|
|
373
|
+
const outDirRoute = path.join(clientDir, urlPath === "/" ? "" : urlPath);
|
|
374
|
+
fs.mkdirSync(outDirRoute, { recursive: true });
|
|
375
|
+
fs.writeFileSync(path.join(outDirRoute, "index.html"), await htmlRes.text());
|
|
376
|
+
} else console.error(`\u{1B}[31m✖ SSG HTML Error for ${urlPath}\u{1B}[0m`);
|
|
377
|
+
const jsonTarget = urlPath === "/" ? "/index" : urlPath;
|
|
378
|
+
const jsonReq = new Request(`http://localhost${baseNoSlash}${jsonTarget}.pageContext.json`);
|
|
379
|
+
const jsonRes = await app.fetch(jsonReq);
|
|
380
|
+
if (jsonRes.ok) {
|
|
381
|
+
const jsonOutPath = path.join(clientDir, `${jsonTarget}.pageContext.json`);
|
|
382
|
+
fs.mkdirSync(path.dirname(jsonOutPath), { recursive: true });
|
|
383
|
+
fs.writeFileSync(jsonOutPath, await jsonRes.text());
|
|
384
|
+
} else console.error(`\u{1B}[31m✖ SSG JSON Error for ${jsonTarget}\u{1B}[0m`);
|
|
385
|
+
console.log(`\u{1B}[32m✓\u{1B}[0m Pre-rendered: ${urlPath}`);
|
|
386
|
+
generatedCount++;
|
|
387
|
+
}
|
|
388
|
+
console.log(`\n\u{1B}[32m✨ SSG Completed! Generated ${generatedCount} static routes.\u{1B}[0m\n`);
|
|
389
|
+
},
|
|
321
390
|
configureServer(server) {
|
|
322
391
|
return () => {
|
|
323
392
|
const pagesPath = path.resolve(viteConfigRoot, pagesDir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vike-lite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"build": "tsdown"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@types/node": "^26.0
|
|
44
|
+
"@types/node": "^26.1.0",
|
|
45
45
|
"tsdown": "^0.22.3",
|
|
46
|
-
"vite": "^8.1.
|
|
46
|
+
"vite": "^8.1.3"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"vite": ">=8"
|