@tanstack/start-plugin-core 1.120.4-alpha.16 → 1.120.4-alpha.2
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/cjs/nitro/dev-server-plugin.cjs +3 -11
- package/dist/cjs/nitro/dev-server-plugin.cjs.map +1 -1
- package/dist/cjs/nitro/nitro-plugin.cjs +5 -40
- package/dist/cjs/nitro/nitro-plugin.cjs.map +1 -1
- package/dist/cjs/plugin.cjs +15 -42
- package/dist/cjs/plugin.cjs.map +1 -1
- package/dist/cjs/plugin.d.cts +1 -626
- package/dist/cjs/prerender.cjs +15 -27
- package/dist/cjs/prerender.cjs.map +1 -1
- package/dist/cjs/schema.cjs +1 -15
- package/dist/cjs/schema.cjs.map +1 -1
- package/dist/cjs/schema.d.cts +542 -2319
- package/dist/cjs/start-server-routes-plugin/plugin.cjs +2 -6
- package/dist/cjs/start-server-routes-plugin/plugin.cjs.map +1 -1
- package/dist/esm/nitro/dev-server-plugin.js +3 -11
- package/dist/esm/nitro/dev-server-plugin.js.map +1 -1
- package/dist/esm/nitro/nitro-plugin.js +5 -40
- package/dist/esm/nitro/nitro-plugin.js.map +1 -1
- package/dist/esm/plugin.d.ts +1 -626
- package/dist/esm/plugin.js +15 -42
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/prerender.js +15 -27
- package/dist/esm/prerender.js.map +1 -1
- package/dist/esm/schema.d.ts +542 -2319
- package/dist/esm/schema.js +1 -15
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/start-server-routes-plugin/plugin.js +2 -6
- package/dist/esm/start-server-routes-plugin/plugin.js.map +1 -1
- package/package.json +5 -11
- package/src/nitro/dev-server-plugin.ts +4 -14
- package/src/nitro/nitro-plugin.ts +3 -46
- package/src/plugin.ts +15 -51
- package/src/prerender.ts +19 -34
- package/src/schema.ts +0 -18
- package/src/start-server-routes-plugin/plugin.ts +2 -10
- package/dist/cjs/constants.cjs +0 -10
- package/dist/cjs/constants.cjs.map +0 -1
- package/dist/cjs/constants.d.cts +0 -4
- package/dist/esm/constants.d.ts +0 -4
- package/dist/esm/constants.js +0 -10
- package/dist/esm/constants.js.map +0 -1
- package/src/constants.ts +0 -6
package/dist/esm/plugin.js
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { createNitro } from "nitropack";
|
|
3
|
-
import { TanStackServerFnPluginEnv } from "@tanstack/server-functions-plugin";
|
|
4
3
|
import { createTanStackStartOptionsSchema, createTanStackConfig } from "./schema.js";
|
|
5
4
|
import { nitroPlugin } from "./nitro/nitro-plugin.js";
|
|
6
5
|
import { startManifestPlugin } from "./routesManifestPlugin.js";
|
|
7
6
|
import { TanStackStartCompilerPlugin } from "./start-compiler-plugin.js";
|
|
8
|
-
import { VITE_ENVIRONMENT_NAMES } from "./constants.js";
|
|
9
7
|
createTanStackStartOptionsSchema();
|
|
10
8
|
createTanStackConfig();
|
|
11
9
|
const clientDistDir = ".tanstack-start/build/client-dist";
|
|
12
10
|
const ssrEntryFile = "ssr.mjs";
|
|
13
11
|
let ssrBundle;
|
|
14
|
-
function TanStackStartVitePluginCore(
|
|
12
|
+
function TanStackStartVitePluginCore(framework, opts) {
|
|
15
13
|
return [
|
|
16
14
|
{
|
|
17
15
|
name: "tanstack-start-core:config-client",
|
|
18
16
|
async config() {
|
|
19
17
|
const nitroOutputPublicDir = await (async () => {
|
|
20
18
|
const dummyNitroApp = await createNitro({
|
|
21
|
-
preset:
|
|
19
|
+
preset: opts.target,
|
|
22
20
|
compatibilityDate: "2024-12-01"
|
|
23
21
|
});
|
|
24
22
|
const nitroOutputPublicDir2 = dummyNitroApp.options.output.publicDir;
|
|
@@ -27,23 +25,23 @@ function TanStackStartVitePluginCore(opts, startConfig) {
|
|
|
27
25
|
})();
|
|
28
26
|
return {
|
|
29
27
|
environments: {
|
|
30
|
-
|
|
28
|
+
client: {
|
|
31
29
|
consumer: "client",
|
|
32
30
|
build: {
|
|
33
31
|
manifest: true,
|
|
34
32
|
rollupOptions: {
|
|
35
33
|
input: {
|
|
36
|
-
main:
|
|
34
|
+
main: opts.clientEntryPath
|
|
37
35
|
},
|
|
38
36
|
output: {
|
|
39
|
-
dir: path.resolve(
|
|
37
|
+
dir: path.resolve(opts.root, clientDistDir)
|
|
40
38
|
},
|
|
41
39
|
// TODO this should be removed
|
|
42
40
|
external: ["node:fs", "node:path", "node:os", "node:crypto"]
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
},
|
|
46
|
-
|
|
44
|
+
server: {
|
|
47
45
|
consumer: "server",
|
|
48
46
|
build: {
|
|
49
47
|
ssr: true,
|
|
@@ -86,48 +84,23 @@ function TanStackStartVitePluginCore(opts, startConfig) {
|
|
|
86
84
|
"tanstack:server-fn-manifest",
|
|
87
85
|
"nitropack",
|
|
88
86
|
"@tanstack/**"
|
|
89
|
-
]
|
|
87
|
+
],
|
|
88
|
+
external: ["undici"]
|
|
90
89
|
},
|
|
91
90
|
/* prettier-ignore */
|
|
92
91
|
define: {
|
|
93
|
-
...injectDefineEnv("TSS_PUBLIC_BASE",
|
|
94
|
-
...injectDefineEnv("TSS_CLIENT_BASE",
|
|
95
|
-
...injectDefineEnv("TSS_CLIENT_ENTRY",
|
|
96
|
-
...injectDefineEnv("TSS_SERVER_FN_BASE",
|
|
92
|
+
...injectDefineEnv("TSS_PUBLIC_BASE", opts.public.base),
|
|
93
|
+
...injectDefineEnv("TSS_CLIENT_BASE", opts.client.base),
|
|
94
|
+
...injectDefineEnv("TSS_CLIENT_ENTRY", opts.clientEntryPath),
|
|
95
|
+
...injectDefineEnv("TSS_SERVER_FN_BASE", opts.serverFns.base),
|
|
97
96
|
...injectDefineEnv("TSS_OUTPUT_PUBLIC_DIR", nitroOutputPublicDir)
|
|
98
97
|
}
|
|
99
98
|
};
|
|
100
99
|
}
|
|
101
100
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
server: { envName: VITE_ENVIRONMENT_NAMES.server }
|
|
106
|
-
}),
|
|
107
|
-
TanStackServerFnPluginEnv({
|
|
108
|
-
// This is the ID that will be available to look up and import
|
|
109
|
-
// our server function manifest and resolve its module
|
|
110
|
-
manifestVirtualImportId: "tanstack:server-fn-manifest",
|
|
111
|
-
client: {
|
|
112
|
-
getRuntimeCode: () => `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,
|
|
113
|
-
replacer: (d) => `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,
|
|
114
|
-
envName: VITE_ENVIRONMENT_NAMES.client
|
|
115
|
-
},
|
|
116
|
-
server: {
|
|
117
|
-
getRuntimeCode: () => `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,
|
|
118
|
-
replacer: (d) => `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,
|
|
119
|
-
envName: VITE_ENVIRONMENT_NAMES.server
|
|
120
|
-
},
|
|
121
|
-
importer: (fn) => {
|
|
122
|
-
const serverEnv = globalThis.viteDevServer.environments[VITE_ENVIRONMENT_NAMES.server];
|
|
123
|
-
if (!serverEnv) {
|
|
124
|
-
throw new Error(`'ssr' vite dev environment not found`);
|
|
125
|
-
}
|
|
126
|
-
return serverEnv.runner.import(fn.extractedFilename);
|
|
127
|
-
}
|
|
128
|
-
}),
|
|
129
|
-
startManifestPlugin(startConfig),
|
|
130
|
-
nitroPlugin(startConfig, () => ssrBundle)
|
|
101
|
+
TanStackStartCompilerPlugin(framework),
|
|
102
|
+
startManifestPlugin(opts),
|
|
103
|
+
nitroPlugin(opts, () => ssrBundle)
|
|
131
104
|
];
|
|
132
105
|
}
|
|
133
106
|
function injectDefineEnv(key, value) {
|
package/dist/esm/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport {
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport {\n createTanStackConfig,\n createTanStackStartOptionsSchema,\n} from './schema'\nimport { nitroPlugin } from './nitro/nitro-plugin'\nimport { startManifestPlugin } from './routesManifestPlugin'\nimport { TanStackStartCompilerPlugin } from './start-compiler-plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nconst TanStackStartOptionsSchema = createTanStackStartOptionsSchema()\nexport type TanStackStartInputConfig = z.input<\n typeof TanStackStartOptionsSchema\n>\n\nconst defaultConfig = createTanStackConfig()\nexport function getTanStackStartOptions(opts?: TanStackStartInputConfig) {\n return defaultConfig.parse(opts)\n}\n\nexport type TanStackStartOutputConfig = ReturnType<\n typeof getTanStackStartOptions\n>\n\nexport const clientDistDir = '.tanstack-start/build/client-dist'\nexport const ssrEntryFile = 'ssr.mjs'\n\n// this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite\nlet ssrBundle: Rollup.OutputBundle\n\nexport function TanStackStartVitePluginCore(\n framework: CompileStartFrameworkOptions,\n opts: TanStackStartOutputConfig,\n): Array<PluginOption> {\n return [\n {\n name: 'tanstack-start-core:config-client',\n async config() {\n const nitroOutputPublicDir = await (async () => {\n // Create a dummy nitro app to get the resolved public output path\n const dummyNitroApp = await createNitro({\n preset: opts.target,\n compatibilityDate: '2024-12-01',\n })\n\n const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir\n await dummyNitroApp.close()\n\n return nitroOutputPublicDir\n })()\n\n return {\n environments: {\n client: {\n consumer: 'client',\n build: {\n manifest: true,\n rollupOptions: {\n input: {\n main: opts.clientEntryPath,\n },\n output: {\n dir: path.resolve(opts.root, clientDistDir),\n },\n // TODO this should be removed\n external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],\n },\n },\n },\n server: {\n consumer: 'server',\n build: {\n ssr: true,\n // we don't write to the file system as the below 'capture-output' plugin will\n // capture the output and write it to the virtual file system\n write: false,\n copyPublicDir: false,\n rollupOptions: {\n output: {\n entryFileNames: ssrEntryFile,\n },\n plugins: [\n {\n name: 'capture-output',\n generateBundle(options, bundle) {\n // TODO can this hook be called more than once?\n ssrBundle = bundle\n },\n },\n ],\n },\n commonjsOptions: {\n include: [/node_modules/],\n },\n },\n },\n },\n resolve: {\n noExternal: [\n '@tanstack/start-client',\n '@tanstack/start-client-core',\n '@tanstack/start-server',\n '@tanstack/start-server-core',\n '@tanstack/start-server-functions-fetcher',\n '@tanstack/start-server-functions-client',\n '@tanstack/start-server-functions-server',\n '@tanstack/start-router-manifest',\n '@tanstack/start-config',\n '@tanstack/server-functions-plugin',\n 'tanstack:start-manifest',\n 'tanstack:server-fn-manifest',\n 'nitropack',\n '@tanstack/**',\n ],\n external: ['undici'],\n },\n /* prettier-ignore */\n define: {\n ...injectDefineEnv('TSS_PUBLIC_BASE', opts.public.base),\n ...injectDefineEnv('TSS_CLIENT_BASE', opts.client.base),\n ...injectDefineEnv('TSS_CLIENT_ENTRY', opts.clientEntryPath),\n ...injectDefineEnv('TSS_SERVER_FN_BASE', opts.serverFns.base),\n ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n },\n }\n },\n },\n TanStackStartCompilerPlugin(framework),\n startManifestPlugin(opts),\n nitroPlugin(opts, () => ssrBundle),\n ]\n}\n\nfunction injectDefineEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n"],"names":["nitroOutputPublicDir"],"mappings":";;;;;;AAamC,iCAAiC;AAK9C,qBAAqB;AASpC,MAAM,gBAAgB;AACtB,MAAM,eAAe;AAG5B,IAAI;AAEY,SAAA,4BACd,WACA,MACqB;AACd,SAAA;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM,SAAS;AACP,cAAA,uBAAuB,OAAO,YAAY;AAExC,gBAAA,gBAAgB,MAAM,YAAY;AAAA,YACtC,QAAQ,KAAK;AAAA,YACb,mBAAmB;AAAA,UAAA,CACpB;AAEKA,gBAAAA,wBAAuB,cAAc,QAAQ,OAAO;AAC1D,gBAAM,cAAc,MAAM;AAEnBA,iBAAAA;AAAAA,QAAAA,GACN;AAEI,eAAA;AAAA,UACL,cAAc;AAAA,YACZ,QAAQ;AAAA,cACN,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,eAAe;AAAA,kBACb,OAAO;AAAA,oBACL,MAAM,KAAK;AAAA,kBACb;AAAA,kBACA,QAAQ;AAAA,oBACN,KAAK,KAAK,QAAQ,KAAK,MAAM,aAAa;AAAA,kBAC5C;AAAA;AAAA,kBAEA,UAAU,CAAC,WAAW,aAAa,WAAW,aAAa;AAAA,gBAAA;AAAA,cAC7D;AAAA,YAEJ;AAAA,YACA,QAAQ;AAAA,cACN,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,KAAK;AAAA;AAAA;AAAA,gBAGL,OAAO;AAAA,gBACP,eAAe;AAAA,gBACf,eAAe;AAAA,kBACb,QAAQ;AAAA,oBACN,gBAAgB;AAAA,kBAClB;AAAA,kBACA,SAAS;AAAA,oBACP;AAAA,sBACE,MAAM;AAAA,sBACN,eAAe,SAAS,QAAQ;AAElB,oCAAA;AAAA,sBAAA;AAAA,oBACd;AAAA,kBACF;AAAA,gBAEJ;AAAA,gBACA,iBAAiB;AAAA,kBACf,SAAS,CAAC,cAAc;AAAA,gBAAA;AAAA,cAC1B;AAAA,YACF;AAAA,UAEJ;AAAA,UACA,SAAS;AAAA,YACP,YAAY;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,UAAU,CAAC,QAAQ;AAAA,UACrB;AAAA;AAAA,UAEA,QAAQ;AAAA,YACN,GAAG,gBAAgB,mBAAmB,KAAK,OAAO,IAAI;AAAA,YACtD,GAAG,gBAAgB,mBAAmB,KAAK,OAAO,IAAI;AAAA,YACtD,GAAG,gBAAgB,oBAAoB,KAAK,eAAe;AAAA,YAC3D,GAAG,gBAAgB,sBAAsB,KAAK,UAAU,IAAI;AAAA,YAC5D,GAAG,gBAAgB,yBAAyB,oBAAoB;AAAA,UAAA;AAAA,QAEpE;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,4BAA4B,SAAS;AAAA,IACrC,oBAAoB,IAAI;AAAA,IACxB,YAAY,MAAM,MAAM,SAAS;AAAA,EACnC;AACF;AAEA,SAAS,gBACP,KACA,OACsE;AAC/D,SAAA;AAAA,IACL,CAAC,eAAe,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,IAC5C,CAAC,mBAAmB,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,EAClD;AACF;"}
|
package/dist/esm/prerender.js
CHANGED
|
@@ -6,14 +6,13 @@ import { createNitro, build } from "nitropack";
|
|
|
6
6
|
import { withBase, joinURL, withoutBase } from "ufo";
|
|
7
7
|
import { Queue } from "./queue.js";
|
|
8
8
|
import { buildNitroEnvironment } from "./nitro/build-nitro.js";
|
|
9
|
-
import { VITE_ENVIRONMENT_NAMES } from "./constants.js";
|
|
10
9
|
async function prerender({
|
|
11
10
|
options,
|
|
12
11
|
nitro,
|
|
13
12
|
builder
|
|
14
13
|
}) {
|
|
15
14
|
var _a;
|
|
16
|
-
|
|
15
|
+
nitro.logger.info("Prendering pages...");
|
|
17
16
|
if (((_a = options.prerender) == null ? void 0 : _a.enabled) && !options.pages.length) {
|
|
18
17
|
options.pages = [
|
|
19
18
|
{
|
|
@@ -21,11 +20,9 @@ async function prerender({
|
|
|
21
20
|
}
|
|
22
21
|
];
|
|
23
22
|
}
|
|
24
|
-
const serverEnv = builder.environments[
|
|
23
|
+
const serverEnv = builder.environments["server"];
|
|
25
24
|
if (!serverEnv) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`Vite's "${VITE_ENVIRONMENT_NAMES.server}" environment not found`
|
|
28
|
-
);
|
|
25
|
+
throw new Error(`Vite's "server" environment not found`);
|
|
29
26
|
}
|
|
30
27
|
const prerenderOutputDir = path.resolve(
|
|
31
28
|
options.root,
|
|
@@ -33,14 +30,6 @@ async function prerender({
|
|
|
33
30
|
);
|
|
34
31
|
const nodeNitro = await createNitro({
|
|
35
32
|
...nitro.options._config,
|
|
36
|
-
routeRules: {
|
|
37
|
-
// Filter out our shell redirect rule if it exists
|
|
38
|
-
...Object.fromEntries(
|
|
39
|
-
Object.entries(nitro.options._config.routeRules ?? {}).filter(
|
|
40
|
-
([_, value]) => !value.__TSS_SHELL
|
|
41
|
-
)
|
|
42
|
-
)
|
|
43
|
-
},
|
|
44
33
|
preset: "nitro-prerender",
|
|
45
34
|
logLevel: 0,
|
|
46
35
|
output: {
|
|
@@ -69,12 +58,12 @@ async function prerender({
|
|
|
69
58
|
const { closePrerenderer, localFetch } = await import(serverEntrypoint);
|
|
70
59
|
try {
|
|
71
60
|
const pages = await prerenderPages();
|
|
72
|
-
|
|
61
|
+
nitro.logger.info(`Prerendered ${pages.length} pages:`);
|
|
73
62
|
pages.forEach((page) => {
|
|
74
|
-
|
|
63
|
+
nitro.logger.info(`- ${page}`);
|
|
75
64
|
});
|
|
76
65
|
} catch (error) {
|
|
77
|
-
|
|
66
|
+
nitro.logger.error(error);
|
|
78
67
|
} finally {
|
|
79
68
|
closePrerenderer();
|
|
80
69
|
}
|
|
@@ -95,7 +84,7 @@ async function prerender({
|
|
|
95
84
|
const seen = /* @__PURE__ */ new Set();
|
|
96
85
|
const retriesByPath = /* @__PURE__ */ new Map();
|
|
97
86
|
const concurrency = ((_a2 = options.prerender) == null ? void 0 : _a2.concurrency) ?? os.cpus().length;
|
|
98
|
-
|
|
87
|
+
nitro.logger.info(`Concurrency: ${concurrency}`);
|
|
99
88
|
const queue = new Queue({ concurrency });
|
|
100
89
|
options.pages.forEach((_page) => {
|
|
101
90
|
let page = _page;
|
|
@@ -121,7 +110,7 @@ async function prerender({
|
|
|
121
110
|
};
|
|
122
111
|
queue.add(async () => {
|
|
123
112
|
var _a4;
|
|
124
|
-
|
|
113
|
+
nitro.logger.info(`Crawling: ${page.path}`);
|
|
125
114
|
const retries = retriesByPath.get(page.path) || 0;
|
|
126
115
|
try {
|
|
127
116
|
const encodedRoute = encodeURI(page.path);
|
|
@@ -132,15 +121,12 @@ async function prerender({
|
|
|
132
121
|
}
|
|
133
122
|
);
|
|
134
123
|
if (!res.ok) {
|
|
135
|
-
throw new Error(`Failed to fetch ${page.path}: ${res.statusText}
|
|
136
|
-
cause: res
|
|
137
|
-
});
|
|
124
|
+
throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`);
|
|
138
125
|
}
|
|
139
|
-
const cleanPagePath = (prerenderOptions.outputPath || page.path).split(/[?#]/)[0];
|
|
140
126
|
const contentType = res.headers.get("content-type") || "";
|
|
141
|
-
const isImplicitHTML = !
|
|
142
|
-
const routeWithIndex =
|
|
143
|
-
const htmlPath =
|
|
127
|
+
const isImplicitHTML = !page.path.endsWith(".html") && contentType.includes("html");
|
|
128
|
+
const routeWithIndex = page.path.endsWith("/") ? page.path + "index" : page.path;
|
|
129
|
+
const htmlPath = page.path.endsWith("/") || prerenderOptions.autoSubfolderIndex ? joinURL(page.path, "index.html") : page.path + ".html";
|
|
144
130
|
const filename = withoutBase(
|
|
145
131
|
isImplicitHTML ? htmlPath : routeWithIndex,
|
|
146
132
|
nitro.options.baseURL
|
|
@@ -163,7 +149,9 @@ async function prerender({
|
|
|
163
149
|
}
|
|
164
150
|
} catch (error) {
|
|
165
151
|
if (retries < (prerenderOptions.retryCount ?? 0)) {
|
|
166
|
-
|
|
152
|
+
nitro.logger.warn(
|
|
153
|
+
`Encountered error, retrying: ${page.path} in 500ms`
|
|
154
|
+
);
|
|
167
155
|
await new Promise(
|
|
168
156
|
(resolve) => setTimeout(resolve, prerenderOptions.retryDelay)
|
|
169
157
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerender.js","sources":["../../src/prerender.ts"],"sourcesContent":["import { promises as fsp } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { getRollupConfig } from 'nitropack/rollup'\nimport { build as buildNitro, createNitro } from 'nitropack'\nimport { joinURL, withBase, withoutBase } from 'ufo'\nimport { Queue } from './queue'\nimport { buildNitroEnvironment } from './nitro/build-nitro'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport type { ViteBuilder } from 'vite'\nimport type { $Fetch, Nitro } from 'nitropack'\nimport type { TanStackStartOutputConfig } from './plugin'\nimport type { Page } from './schema'\n\nexport async function prerender({\n options,\n nitro,\n builder,\n}: {\n options: TanStackStartOutputConfig\n nitro: Nitro\n builder: ViteBuilder\n}) {\n console.info('Prendering pages...')\n\n // If prerender is enabled but no pages are provided, default to prerendering the root page\n if (options.prerender?.enabled && !options.pages.length) {\n options.pages = [\n {\n path: '/',\n },\n ]\n }\n\n const serverEnv = builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!serverEnv) {\n throw new Error(\n `Vite's \"${VITE_ENVIRONMENT_NAMES.server}\" environment not found`,\n )\n }\n\n const prerenderOutputDir = path.resolve(\n options.root,\n '.tanstack-start/build/prerenderer',\n )\n\n const nodeNitro = await createNitro({\n ...nitro.options._config,\n routeRules: {\n // Filter out our shell redirect rule if it exists\n ...Object.fromEntries(\n Object.entries(nitro.options._config.routeRules ?? {}).filter(\n ([_, value]) => !(value as any).__TSS_SHELL,\n ),\n ),\n },\n preset: 'nitro-prerender',\n logLevel: 0,\n output: {\n dir: prerenderOutputDir,\n serverDir: path.resolve(prerenderOutputDir, 'server'),\n publicDir: path.resolve(prerenderOutputDir, 'public'),\n },\n })\n\n const nodeNitroRollupOptions = getRollupConfig(nodeNitro)\n\n const build = serverEnv.config.build\n\n build.outDir = prerenderOutputDir\n\n build.rollupOptions = {\n ...build.rollupOptions,\n ...nodeNitroRollupOptions,\n output: {\n ...build.rollupOptions.output,\n ...nodeNitroRollupOptions.output,\n sourcemap: undefined,\n },\n }\n\n await buildNitroEnvironment(nodeNitro, () => buildNitro(nodeNitro))\n\n // Import renderer entry\n const serverFilename =\n typeof nodeNitroRollupOptions.output.entryFileNames === 'string'\n ? nodeNitroRollupOptions.output.entryFileNames\n : 'index.mjs'\n\n const serverEntrypoint = path.resolve(\n path.join(nodeNitro.options.output.serverDir, serverFilename),\n )\n\n const { closePrerenderer, localFetch } = (await import(serverEntrypoint)) as {\n closePrerenderer: () => void\n localFetch: $Fetch\n }\n\n try {\n // Crawl all pages\n const pages = await prerenderPages()\n\n console.info(`Prerendered ${pages.length} pages:`)\n pages.forEach((page) => {\n console.info(`- ${page}`)\n })\n\n // TODO: Write the prerendered pages to the output directory\n } catch (error) {\n console.error(error)\n } finally {\n // Ensure server is always closed\n // server.process.kill()\n closePrerenderer()\n }\n\n function extractLinks(html: string): Array<string> {\n const linkRegex = /<a[^>]+href=[\"']([^\"']+)[\"'][^>]*>/g\n const links: Array<string> = []\n let match\n\n while ((match = linkRegex.exec(html)) !== null) {\n const href = match[1]\n if (href && (href.startsWith('/') || href.startsWith('./'))) {\n links.push(href)\n }\n }\n\n return links\n }\n\n async function prerenderPages() {\n const seen = new Set<string>()\n const retriesByPath = new Map<string, number>()\n const concurrency = options.prerender?.concurrency ?? os.cpus().length\n console.info(`Concurrency: ${concurrency}`)\n const queue = new Queue({ concurrency })\n\n options.pages.forEach((_page) => {\n let page = _page as Page\n\n if (typeof _page === 'string') {\n page = { path: _page }\n }\n\n addCrawlPageTask(page)\n })\n\n await queue.start()\n\n return Array.from(seen)\n\n function addCrawlPageTask(page: Page) {\n // Was the page already seen?\n if (seen.has(page.path)) return\n\n // Add the page to the seen set\n seen.add(page.path)\n\n if (page.fromCrawl) {\n options.pages.push(page)\n }\n\n // If not enabled, skip\n if (!(page.prerender?.enabled ?? true)) return\n\n // If there is a filter link, check if the page should be prerendered\n if (options.prerender?.filter && !options.prerender.filter(page)) return\n\n // Resolve the merged default and page-specific prerender options\n const prerenderOptions = {\n ...options.prerender,\n ...page.prerender,\n }\n\n // Add the task\n queue.add(async () => {\n console.info(`Crawling: ${page.path}`)\n const retries = retriesByPath.get(page.path) || 0\n try {\n // Fetch the route\n const encodedRoute = encodeURI(page.path)\n\n const res = await localFetch<Response>(\n withBase(encodedRoute, nodeNitro.options.baseURL),\n {\n headers: { 'x-nitro-prerender': encodedRoute },\n },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`, {\n cause: res,\n })\n }\n\n const cleanPagePath = (\n prerenderOptions.outputPath || page.path\n ).split(/[?#]/)[0]!\n\n // Guess route type and populate fileName\n const contentType = res.headers.get('content-type') || ''\n const isImplicitHTML =\n !cleanPagePath.endsWith('.html') && contentType.includes('html')\n // &&\n // !JsonSigRx.test(dataBuff.subarray(0, 32).toString('utf8'))\n const routeWithIndex = cleanPagePath.endsWith('/')\n ? cleanPagePath + 'index'\n : cleanPagePath\n\n const htmlPath =\n cleanPagePath.endsWith('/') || prerenderOptions.autoSubfolderIndex\n ? joinURL(cleanPagePath, 'index.html')\n : cleanPagePath + '.html'\n\n const filename = withoutBase(\n isImplicitHTML ? htmlPath : routeWithIndex,\n nitro.options.baseURL,\n )\n\n const html = await res.text()\n\n const filepath = path.join(nitro.options.output.publicDir, filename)\n\n await fsp.mkdir(path.dirname(filepath), {\n recursive: true,\n })\n\n await fsp.writeFile(filepath, html)\n\n const newPage = await prerenderOptions.onSuccess?.({ page, html })\n\n if (newPage) {\n Object.assign(page, newPage)\n }\n\n // Find new links\n if (prerenderOptions.crawlLinks ?? true) {\n const links = extractLinks(html)\n for (const link of links) {\n addCrawlPageTask({ path: link, fromCrawl: true })\n }\n }\n } catch (error) {\n if (retries < (prerenderOptions.retryCount ?? 0)) {\n console.warn(`Encountered error, retrying: ${page.path} in 500ms`)\n await new Promise((resolve) =>\n setTimeout(resolve, prerenderOptions.retryDelay),\n )\n retriesByPath.set(page.path, retries + 1)\n addCrawlPageTask(page)\n } else {\n throw error\n }\n }\n })\n }\n }\n}\n"],"names":["build","buildNitro","_a","fsp"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prerender.js","sources":["../../src/prerender.ts"],"sourcesContent":["import { promises as fsp } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { getRollupConfig } from 'nitropack/rollup'\nimport { build as buildNitro, createNitro } from 'nitropack'\nimport { joinURL, withBase, withoutBase } from 'ufo'\nimport { Queue } from './queue'\nimport { buildNitroEnvironment } from './nitro/build-nitro'\nimport type { ViteBuilder } from 'vite'\nimport type { $Fetch, Nitro } from 'nitropack'\nimport type { TanStackStartOutputConfig } from './plugin'\nimport type { Page } from './schema'\n\nexport async function prerender({\n options,\n nitro,\n builder,\n}: {\n options: TanStackStartOutputConfig\n nitro: Nitro\n builder: ViteBuilder\n}) {\n nitro.logger.info('Prendering pages...')\n\n // If prerender is enabled but no pages are provided, default to prerendering the root page\n if (options.prerender?.enabled && !options.pages.length) {\n options.pages = [\n {\n path: '/',\n },\n ]\n }\n\n const serverEnv = builder.environments['server']\n\n if (!serverEnv) {\n throw new Error(`Vite's \"server\" environment not found`)\n }\n\n const prerenderOutputDir = path.resolve(\n options.root,\n '.tanstack-start/build/prerenderer',\n )\n\n const nodeNitro = await createNitro({\n ...nitro.options._config,\n preset: 'nitro-prerender',\n logLevel: 0,\n output: {\n dir: prerenderOutputDir,\n serverDir: path.resolve(prerenderOutputDir, 'server'),\n publicDir: path.resolve(prerenderOutputDir, 'public'),\n },\n })\n\n const nodeNitroRollupOptions = getRollupConfig(nodeNitro)\n\n const build = serverEnv.config.build\n\n build.outDir = prerenderOutputDir\n\n build.rollupOptions = {\n ...build.rollupOptions,\n ...nodeNitroRollupOptions,\n output: {\n ...build.rollupOptions.output,\n ...nodeNitroRollupOptions.output,\n sourcemap: undefined,\n },\n }\n\n await buildNitroEnvironment(nodeNitro, () => buildNitro(nodeNitro))\n\n // Import renderer entry\n const serverFilename =\n typeof nodeNitroRollupOptions.output.entryFileNames === 'string'\n ? nodeNitroRollupOptions.output.entryFileNames\n : 'index.mjs'\n\n const serverEntrypoint = path.resolve(\n path.join(nodeNitro.options.output.serverDir, serverFilename),\n )\n\n const { closePrerenderer, localFetch } = (await import(serverEntrypoint)) as {\n closePrerenderer: () => void\n localFetch: $Fetch\n }\n\n try {\n // Crawl all pages\n const pages = await prerenderPages()\n\n nitro.logger.info(`Prerendered ${pages.length} pages:`)\n pages.forEach((page) => {\n nitro.logger.info(`- ${page}`)\n })\n\n // TODO: Write the prerendered pages to the output directory\n } catch (error) {\n nitro.logger.error(error)\n } finally {\n // Ensure server is always closed\n // server.process.kill()\n closePrerenderer()\n }\n\n function extractLinks(html: string): Array<string> {\n const linkRegex = /<a[^>]+href=[\"']([^\"']+)[\"'][^>]*>/g\n const links: Array<string> = []\n let match\n\n while ((match = linkRegex.exec(html)) !== null) {\n const href = match[1]\n if (href && (href.startsWith('/') || href.startsWith('./'))) {\n links.push(href)\n }\n }\n\n return links\n }\n\n async function prerenderPages() {\n const seen = new Set<string>()\n const retriesByPath = new Map<string, number>()\n const concurrency = options.prerender?.concurrency ?? os.cpus().length\n nitro.logger.info(`Concurrency: ${concurrency}`)\n const queue = new Queue({ concurrency })\n\n options.pages.forEach((_page) => {\n let page = _page as Page\n\n if (typeof _page === 'string') {\n page = { path: _page }\n }\n\n addCrawlPageTask(page)\n })\n\n await queue.start()\n\n return Array.from(seen)\n\n function addCrawlPageTask(page: Page) {\n // Was the page already seen?\n if (seen.has(page.path)) return\n\n // Add the page to the seen set\n seen.add(page.path)\n\n if (page.fromCrawl) {\n options.pages.push(page)\n }\n\n // If not enabled, skip\n if (!(page.prerender?.enabled ?? true)) return\n\n // If there is a filter link, check if the page should be prerendered\n if (options.prerender?.filter && !options.prerender.filter(page)) return\n\n // Resolve the merged default and page-specific prerender options\n const prerenderOptions = {\n ...options.prerender,\n ...page.prerender,\n }\n\n // Add the task\n queue.add(async () => {\n nitro.logger.info(`Crawling: ${page.path}`)\n const retries = retriesByPath.get(page.path) || 0\n try {\n // Fetch the route\n const encodedRoute = encodeURI(page.path)\n\n const res = await localFetch<Response>(\n withBase(encodedRoute, nodeNitro.options.baseURL),\n {\n headers: { 'x-nitro-prerender': encodedRoute },\n },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`)\n }\n\n // Guess route type and populate fileName\n const contentType = res.headers.get('content-type') || ''\n const isImplicitHTML =\n !page.path.endsWith('.html') && contentType.includes('html')\n // &&\n // !JsonSigRx.test(dataBuff.subarray(0, 32).toString('utf8'))\n const routeWithIndex = page.path.endsWith('/')\n ? page.path + 'index'\n : page.path\n\n const htmlPath =\n page.path.endsWith('/') || prerenderOptions.autoSubfolderIndex\n ? joinURL(page.path, 'index.html')\n : page.path + '.html'\n\n const filename = withoutBase(\n isImplicitHTML ? htmlPath : routeWithIndex,\n nitro.options.baseURL,\n )\n\n const html = await res.text()\n\n const filepath = path.join(nitro.options.output.publicDir, filename)\n\n await fsp.mkdir(path.dirname(filepath), {\n recursive: true,\n })\n\n await fsp.writeFile(filepath, html)\n\n const newPage = await prerenderOptions.onSuccess?.({ page, html })\n\n if (newPage) {\n Object.assign(page, newPage)\n }\n\n // Find new links\n if (prerenderOptions.crawlLinks ?? true) {\n const links = extractLinks(html)\n for (const link of links) {\n addCrawlPageTask({ path: link, fromCrawl: true })\n }\n }\n } catch (error) {\n if (retries < (prerenderOptions.retryCount ?? 0)) {\n nitro.logger.warn(\n `Encountered error, retrying: ${page.path} in 500ms`,\n )\n await new Promise((resolve) =>\n setTimeout(resolve, prerenderOptions.retryDelay),\n )\n retriesByPath.set(page.path, retries + 1)\n addCrawlPageTask(page)\n } else {\n throw error\n }\n }\n })\n }\n }\n}\n"],"names":["build","buildNitro","_a","fsp"],"mappings":"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"}
|