vike 0.4.147 → 0.4.148-commit-7596dcd
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/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +116 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +33 -45
- package/dist/cjs/node/prerender/runPrerender.js +85 -84
- package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/cjs/node/runtime/html/renderHtml.js +1 -1
- package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +12 -12
- package/dist/cjs/node/runtime/renderPage/createHttpResponseObject.js +3 -3
- package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +21 -18
- package/dist/cjs/node/runtime/renderPage.js +73 -49
- package/dist/cjs/shared/getPageFiles/parseGlobResults.js +3 -3
- package/dist/cjs/shared/hooks/executeHook.js +18 -29
- package/dist/cjs/shared/hooks/getHook.js +104 -3
- package/dist/cjs/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/cjs/shared/route/executeGuardHook.js +3 -2
- package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +4 -4
- package/dist/cjs/shared/route/loadPageRoutes.js +10 -15
- package/dist/cjs/shared/route/resolveRedirects.js +8 -5
- package/dist/cjs/utils/parseUrl-extras.js +6 -1
- package/dist/cjs/utils/parseUrl.js +24 -16
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +20 -10
- package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +2 -2
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +18 -12
- package/dist/esm/client/shared/executeOnRenderClientHook.js +1 -1
- package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +5 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +110 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +34 -46
- package/dist/esm/node/prerender/runPrerender.js +87 -86
- package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/esm/node/runtime/html/renderHtml.js +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +13 -13
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject.js +3 -3
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.d.ts +2 -2
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +7 -7
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +22 -19
- package/dist/esm/node/runtime/renderPage.js +74 -50
- package/dist/esm/shared/getPageFiles/parseGlobResults.js +1 -1
- package/dist/esm/shared/hooks/executeHook.d.ts +2 -2
- package/dist/esm/shared/hooks/executeHook.js +18 -29
- package/dist/esm/shared/hooks/getHook.d.ts +17 -7
- package/dist/esm/shared/hooks/getHook.js +103 -3
- package/dist/esm/shared/page-configs/Config.d.ts +21 -13
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.d.ts +1 -1
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/esm/shared/route/executeGuardHook.js +4 -3
- package/dist/esm/shared/route/executeOnBeforeRouteHook.d.ts +1 -8
- package/dist/esm/shared/route/executeOnBeforeRouteHook.js +6 -6
- package/dist/esm/shared/route/index.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.js +11 -16
- package/dist/esm/shared/route/resolveRedirects.js +8 -5
- package/dist/esm/utils/parseUrl-extras.d.ts +2 -0
- package/dist/esm/utils/parseUrl-extras.js +5 -0
- package/dist/esm/utils/parseUrl.js +24 -16
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +3 -3
- /package/dist/cjs/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.d.ts → assertPageConfigsSerialized.d.ts} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
|
@@ -53,22 +53,27 @@ function getConfigValueSerialized(value, configName, definedAt) {
|
|
|
53
53
|
configValueSerialized = (0, stringify_1.stringify)(value, { valueName, forbidReactElements: true });
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
else {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
/*
|
|
57
|
+
let serializationErrMsg = ''
|
|
58
|
+
if (isJsonSerializerError(err)) {
|
|
59
|
+
serializationErrMsg = err.messageCore
|
|
60
|
+
} else {
|
|
61
|
+
// When a property getter throws an error
|
|
62
|
+
console.error('Serialization error:')
|
|
63
|
+
console.error(err)
|
|
64
|
+
serializationErrMsg = 'see serialization error printed above'
|
|
65
65
|
}
|
|
66
|
+
*/
|
|
66
67
|
const configValueFilePathToShowToUser = (0, helpers_js_1.getConfigValueFilePathToShowToUser)({ definedAt });
|
|
67
68
|
(0, utils_js_1.assert)(configValueFilePathToShowToUser);
|
|
68
69
|
(0, utils_js_1.assertUsage)(false, [
|
|
69
|
-
`The
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
`The code of ${picocolors_1.default.cyan(configName)} cannot live inside ${configValueFilePathToShowToUser},`,
|
|
71
|
+
'see https://vike.dev/header-file#runtime-code'
|
|
72
|
+
/* I guess showing this is more confusing than adding value.
|
|
73
|
+
`(technically speaking: the value of ${pc.cyan(
|
|
74
|
+
configName
|
|
75
|
+
)} isn't serializable (${serializationErrMsg}) and it's therefore runtime code that needs to be imported).`
|
|
76
|
+
//*/
|
|
72
77
|
].join(' '));
|
|
73
78
|
}
|
|
74
79
|
configValueSerialized = JSON.stringify(configValueSerialized);
|
|
@@ -76,6 +76,9 @@ const configDefinitionsBuiltIn = {
|
|
|
76
76
|
onBeforeRenderEnv: {
|
|
77
77
|
env: { client: true },
|
|
78
78
|
_computed: (configValueSources) => !isConfigSet(configValueSources, 'onBeforeRender') ? null : getConfigEnv(configValueSources, 'onBeforeRender')
|
|
79
|
+
},
|
|
80
|
+
hooksTimeout: {
|
|
81
|
+
env: { server: true, client: true }
|
|
79
82
|
}
|
|
80
83
|
};
|
|
81
84
|
exports.configDefinitionsBuiltIn = configDefinitionsBuiltIn;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.crawlPlusFiles = void 0;
|
|
7
|
+
const utils_js_1 = require("../../../../utils.js");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const execA = (0, util_1.promisify)(child_process_1.exec);
|
|
13
|
+
async function crawlPlusFiles(userRootDir, outDirAbsoluteFilesystem, isDev) {
|
|
14
|
+
(0, utils_js_1.assertPosixPath)(userRootDir);
|
|
15
|
+
(0, utils_js_1.assertPosixPath)(outDirAbsoluteFilesystem);
|
|
16
|
+
(0, utils_js_1.assert)(outDirAbsoluteFilesystem.startsWith(userRootDir));
|
|
17
|
+
const outDir = path_1.default.posix.relative(userRootDir, outDirAbsoluteFilesystem);
|
|
18
|
+
(0, utils_js_1.assert)(!outDir.startsWith('.'));
|
|
19
|
+
const timeBase = new Date().getTime();
|
|
20
|
+
let files = [];
|
|
21
|
+
const res = await gitLsFiles(userRootDir, outDir);
|
|
22
|
+
if (res &&
|
|
23
|
+
// Fallback to fast-glob for users that dynamically generate plus files (we assume generetad plus files to be skipped because they are usually included in .gitignore)
|
|
24
|
+
res.length > 0) {
|
|
25
|
+
files = res;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
files = await fastGlob(userRootDir, outDir);
|
|
29
|
+
}
|
|
30
|
+
{
|
|
31
|
+
const time = new Date().getTime() - timeBase;
|
|
32
|
+
if (isDev) {
|
|
33
|
+
// We only warn in dev, because while building it's expected to take a long time as fast-glob is competing for resources with other tasks
|
|
34
|
+
(0, utils_js_1.assertWarning)(time < 2 * 1000, `Crawling your user files took an unexpected long time (${time}ms). Create a new issue on Vike's GitHub.`, {
|
|
35
|
+
onlyOnce: 'slow-page-files-search'
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const plusFiles = files.map((p) => {
|
|
40
|
+
p = (0, utils_js_1.toPosixPath)(p);
|
|
41
|
+
(0, utils_js_1.assert)(!p.startsWith(userRootDir));
|
|
42
|
+
const filePathRelativeToUserRootDir = path_1.default.posix.join('/', p);
|
|
43
|
+
const filePathAbsoluteFilesystem = path_1.default.posix.join(userRootDir, p);
|
|
44
|
+
return {
|
|
45
|
+
filePathRelativeToUserRootDir,
|
|
46
|
+
filePathAbsoluteFilesystem
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
return plusFiles;
|
|
50
|
+
}
|
|
51
|
+
exports.crawlPlusFiles = crawlPlusFiles;
|
|
52
|
+
// Same as fastGlob() but using `$ git ls-files`
|
|
53
|
+
async function gitLsFiles(userRootDir, outDir) {
|
|
54
|
+
// Test if Git is installed
|
|
55
|
+
{
|
|
56
|
+
let stdout;
|
|
57
|
+
try {
|
|
58
|
+
const res = await execA('git --version', { cwd: userRootDir });
|
|
59
|
+
stdout = res.stdout;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
(0, utils_js_1.assert)(stdout.startsWith('git version '));
|
|
65
|
+
}
|
|
66
|
+
const cmd = [
|
|
67
|
+
'git ls-files',
|
|
68
|
+
...utils_js_1.scriptFileExtensionList.map((ext) => `"**/+*.${ext}"`),
|
|
69
|
+
...getIgnorePatterns(outDir).map((pattern) => `--exclude="${pattern}"`),
|
|
70
|
+
// --others lists untracked files only (but using .gitignore because --exclude-standard)
|
|
71
|
+
// --cached adds the tracked files to the output
|
|
72
|
+
'--others --cached --exclude-standard'
|
|
73
|
+
].join(' ');
|
|
74
|
+
let stdout;
|
|
75
|
+
try {
|
|
76
|
+
const res = await execA(cmd, { cwd: userRootDir });
|
|
77
|
+
stdout = res.stdout;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (err.message.includes('not a git repository'))
|
|
81
|
+
return null;
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
let files = stdout.split('\n').filter(Boolean);
|
|
85
|
+
(0, utils_js_1.assert)(!outDir.startsWith('/'));
|
|
86
|
+
files = files.filter(
|
|
87
|
+
// We have to repeat the same exclusion logic here because the `git ls-files` option --exclude only applies to untracked files. (We use --exclude only to speed up the command.)
|
|
88
|
+
(file) => getIgnoreFilter(file, outDir));
|
|
89
|
+
return files;
|
|
90
|
+
}
|
|
91
|
+
// Same as gitLsFiles() but using fast-glob
|
|
92
|
+
async function fastGlob(userRootDir, outDir) {
|
|
93
|
+
const files = await (0, fast_glob_1.default)(`**/+*.${utils_js_1.scriptFileExtensions}`, {
|
|
94
|
+
ignore: getIgnorePatterns(outDir),
|
|
95
|
+
cwd: userRootDir,
|
|
96
|
+
dot: false
|
|
97
|
+
});
|
|
98
|
+
return files;
|
|
99
|
+
}
|
|
100
|
+
// Same as getIgnoreFilter() but as glob pattern
|
|
101
|
+
function getIgnorePatterns(outDir) {
|
|
102
|
+
return [
|
|
103
|
+
'**/node_modules/**',
|
|
104
|
+
`${outDir}/**`,
|
|
105
|
+
// Allow:
|
|
106
|
+
// ```
|
|
107
|
+
// +Page.js
|
|
108
|
+
// +Page.telefunc.js
|
|
109
|
+
// ```
|
|
110
|
+
'**/*.telefunc.*'
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
// Same as getIgnorePatterns() but for Array.filter()
|
|
114
|
+
function getIgnoreFilter(file, outDir) {
|
|
115
|
+
return !file.includes('node_modules/') && !file.includes('.telefunc.') && !file.startsWith(`${outDir}/`);
|
|
116
|
+
}
|
|
@@ -7,7 +7,6 @@ exports.isVikeConfigFile = exports.vikeConfigDependencies = exports.reloadVikeCo
|
|
|
7
7
|
const utils_js_1 = require("../../../utils.js");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const configDefinitionsBuiltIn_js_1 = require("./getVikeConfig/configDefinitionsBuiltIn.js");
|
|
10
|
-
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
11
10
|
const filesystemRouting_js_1 = require("./getVikeConfig/filesystemRouting.js");
|
|
12
11
|
const transpileAndExecuteFile_js_1 = require("./transpileAndExecuteFile.js");
|
|
13
12
|
const replaceImportStatements_js_1 = require("./replaceImportStatements.js");
|
|
@@ -20,6 +19,7 @@ const helpers_js_1 = require("../../../../../shared/page-configs/helpers.js");
|
|
|
20
19
|
const assertExports_js_1 = require("../../../../../shared/page-configs/assertExports.js");
|
|
21
20
|
const getConfigVike_js_1 = require("../../../../shared/getConfigVike.js");
|
|
22
21
|
const getConfigValuesSerialized_js_1 = require("./getConfigValuesSerialized.js");
|
|
22
|
+
const crawlPlusFiles_js_1 = require("./getVikeConfig/crawlPlusFiles.js");
|
|
23
23
|
(0, utils_js_1.assertIsNotProductionRuntime)();
|
|
24
24
|
let devServerIsCorrupt = false;
|
|
25
25
|
let wasConfigInvalid = null;
|
|
@@ -75,7 +75,7 @@ async function getVikeConfig(config, isDev, tolerateInvalidConfig = false, exten
|
|
|
75
75
|
}
|
|
76
76
|
exports.getVikeConfig = getVikeConfig;
|
|
77
77
|
async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
|
|
78
|
-
const plusFiles = await findPlusFiles(userRootDir,
|
|
78
|
+
const plusFiles = await findPlusFiles(userRootDir, outDirRoot, isDev, extensions);
|
|
79
79
|
const configFiles = [];
|
|
80
80
|
const valueFiles = [];
|
|
81
81
|
plusFiles.forEach((f) => {
|
|
@@ -127,6 +127,7 @@ async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
|
|
|
127
127
|
interfaceFilesByLocationId[locationId].push(interfaceFile);
|
|
128
128
|
}
|
|
129
129
|
}));
|
|
130
|
+
assertAllConfigsAreKnown(interfaceFilesByLocationId);
|
|
130
131
|
return interfaceFilesByLocationId;
|
|
131
132
|
}
|
|
132
133
|
function getConfigDefinition(configDefinitionsRelevant, configName, filePathToShowToUser) {
|
|
@@ -180,6 +181,18 @@ function getInterfaceFileFromConfigFile(configFile, isConfigExtend) {
|
|
|
180
181
|
});
|
|
181
182
|
return interfaceFile;
|
|
182
183
|
}
|
|
184
|
+
/** Show error message upon unknown config */
|
|
185
|
+
function assertAllConfigsAreKnown(interfaceFilesByLocationId) {
|
|
186
|
+
Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
|
|
187
|
+
const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
|
|
188
|
+
const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
|
|
189
|
+
interfaceFiles.forEach((interfaceFile) => {
|
|
190
|
+
Object.keys(interfaceFile.configMap).forEach((configName) => {
|
|
191
|
+
assertConfigExists(configName, Object.keys(configDefinitionsRelevant), interfaceFile.filePath.filePathToShowToUser);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
183
196
|
async function loadVikeConfig_withErrorHandling(userRootDir, outDirRoot, isDev, extensions, tolerateInvalidConfig) {
|
|
184
197
|
let hasError = false;
|
|
185
198
|
let ret;
|
|
@@ -270,18 +283,23 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
|
|
|
270
283
|
};
|
|
271
284
|
return pageConfig;
|
|
272
285
|
}));
|
|
273
|
-
|
|
274
|
-
Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
|
|
275
|
-
const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
|
|
276
|
-
const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
|
|
277
|
-
interfaceFiles.forEach((interfaceFile) => {
|
|
278
|
-
Object.keys(interfaceFile.configMap).forEach((configName) => {
|
|
279
|
-
assertConfigExists(configName, Object.keys(configDefinitionsRelevant), interfaceFile.filePath.filePathToShowToUser);
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
});
|
|
286
|
+
assertPageConfigs(pageConfigs);
|
|
283
287
|
return { pageConfigs, pageConfigGlobal, globalVikeConfig };
|
|
284
288
|
}
|
|
289
|
+
function assertPageConfigs(pageConfigs) {
|
|
290
|
+
pageConfigs.forEach((pageConfig) => {
|
|
291
|
+
assertOnBeforeRenderEnv(pageConfig);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function assertOnBeforeRenderEnv(pageConfig) {
|
|
295
|
+
const onBeforeRenderConfig = pageConfig.configValueSources.onBeforeRender?.[0];
|
|
296
|
+
if (!onBeforeRenderConfig)
|
|
297
|
+
return;
|
|
298
|
+
const onBeforeRenderEnv = onBeforeRenderConfig.configEnv;
|
|
299
|
+
const isClientRouting = !!pageConfig.configValues.clientRouting?.value;
|
|
300
|
+
// When using Server Routing, loading a onBeforeRender() hook on the client-side hasn't any effect (the Server Routing's client runtime never calls it); it unnecessarily bloats client bundle sizes
|
|
301
|
+
(0, utils_js_1.assertUsage)(!(onBeforeRenderEnv.client && !isClientRouting), `Page ${pageConfig.pageId} has an onBeforeRender() hook with env ${picocolors_1.default.cyan(JSON.stringify(onBeforeRenderEnv))} which doesn't make sense because the page is using Server Routing: onBeforeRender() can be run in the client only when using Client Routing.`);
|
|
302
|
+
}
|
|
285
303
|
function interfacefileIsAlreaydLoaded(interfaceFile) {
|
|
286
304
|
const configMapValues = Object.values(interfaceFile.configMap);
|
|
287
305
|
const isAlreadyLoaded = configMapValues.some((conf) => 'configValue' in conf);
|
|
@@ -781,39 +799,9 @@ function getComputed(configValueSources, configDefinitionsRelevant) {
|
|
|
781
799
|
});
|
|
782
800
|
return configValuesComputed;
|
|
783
801
|
}
|
|
784
|
-
async function findPlusFiles(userRootDir,
|
|
785
|
-
const
|
|
786
|
-
(
|
|
787
|
-
const ignorePatterns = [];
|
|
788
|
-
for (const dir of ignoreDirs) {
|
|
789
|
-
(0, utils_js_1.assertPosixPath)(dir);
|
|
790
|
-
ignorePatterns.push(`${path_1.default.posix.relative(userRootDir, dir)}/**`);
|
|
791
|
-
}
|
|
792
|
-
const result = await (0, fast_glob_1.default)(`**/+*.${utils_js_1.scriptFileExtensions}`, {
|
|
793
|
-
ignore: [
|
|
794
|
-
'**/node_modules/**',
|
|
795
|
-
// Allow:
|
|
796
|
-
// ```
|
|
797
|
-
// +Page.js
|
|
798
|
-
// +Page.telefunc.js
|
|
799
|
-
// ```
|
|
800
|
-
'**/*.telefunc.*',
|
|
801
|
-
...ignorePatterns
|
|
802
|
-
],
|
|
803
|
-
cwd: userRootDir,
|
|
804
|
-
dot: false
|
|
805
|
-
});
|
|
806
|
-
const time = new Date().getTime() - timeBase;
|
|
807
|
-
if (isDev) {
|
|
808
|
-
// We only warn in dev, because while building it's expected to take a long time as fast-glob is competing for resources with other tasks
|
|
809
|
-
(0, utils_js_1.assertWarning)(time < 2 * 1000, `Crawling your user files took an unexpected long time (${time}ms). Create a new issue on Vike's GitHub.`, {
|
|
810
|
-
onlyOnce: 'slow-page-files-search'
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
const plusFiles = result.map((p) => {
|
|
814
|
-
p = (0, utils_js_1.toPosixPath)(p);
|
|
815
|
-
const filePathRelativeToUserRootDir = path_1.default.posix.join('/', p);
|
|
816
|
-
const filePathAbsoluteFilesystem = path_1.default.posix.join(userRootDir, p);
|
|
802
|
+
async function findPlusFiles(userRootDir, outDirRoot, isDev, extensions) {
|
|
803
|
+
const files = await (0, crawlPlusFiles_js_1.crawlPlusFiles)(userRootDir, outDirRoot, isDev);
|
|
804
|
+
const plusFiles = files.map(({ filePathRelativeToUserRootDir, filePathAbsoluteFilesystem }) => {
|
|
817
805
|
return {
|
|
818
806
|
filePathRelativeToUserRootDir,
|
|
819
807
|
filePathAbsoluteVite: filePathRelativeToUserRootDir,
|
|
@@ -102,16 +102,22 @@ async function runPrerender(options, manuallyTriggered) {
|
|
|
102
102
|
await callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit, doNotPrerenderList);
|
|
103
103
|
await handlePagesWithStaticRoutes(prerenderContext, renderContext, doNotPrerenderList, concurrencyLimit);
|
|
104
104
|
await callOnPrerenderStartHook(prerenderContext, renderContext);
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
const prerenderedPageContexts = {};
|
|
106
|
+
let prerenderedCount = 0;
|
|
107
|
+
const onComplete = async (htmlFile) => {
|
|
108
|
+
prerenderedCount++;
|
|
109
|
+
if (htmlFile.pageId) {
|
|
110
|
+
prerenderedPageContexts[htmlFile.pageId] = htmlFile.pageContext;
|
|
111
|
+
}
|
|
112
|
+
await writeFiles(htmlFile, root, outDirClient, options.onPagePrerender, logLevel);
|
|
113
|
+
};
|
|
114
|
+
await routeAndPrerender(prerenderContext, concurrencyLimit, onComplete);
|
|
115
|
+
warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerenderList);
|
|
116
|
+
await prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete);
|
|
110
117
|
if (logLevel === 'info') {
|
|
111
|
-
console.log(`${picocolors_1.default.green(`✓`)} ${
|
|
118
|
+
console.log(`${picocolors_1.default.green(`✓`)} ${prerenderedCount} HTML documents pre-rendered.`);
|
|
112
119
|
}
|
|
113
|
-
|
|
114
|
-
warnMissingPages(prerenderedPages, doNotPrerenderList, renderContext, partial);
|
|
120
|
+
warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial);
|
|
115
121
|
}
|
|
116
122
|
async function collectDoNoPrerenderList(renderContext, pageConfigs, doNotPrerenderList, concurrencyLimit) {
|
|
117
123
|
// V1 design
|
|
@@ -179,18 +185,16 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
179
185
|
await Promise.all(renderContext.pageConfigs.map((pageConfig) => concurrencyLimit(async () => {
|
|
180
186
|
const hookName = 'onBeforePrerenderStart';
|
|
181
187
|
const pageConfigLoaded = await (0, loadConfigValues_js_1.loadConfigValues)(pageConfig, false);
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
188
|
+
const hook = (0, getHook_js_1.getHookFromPageConfig)(pageConfigLoaded, hookName);
|
|
189
|
+
if (!hook)
|
|
184
190
|
return;
|
|
185
|
-
const hookFn =
|
|
186
|
-
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
187
|
-
(0, utils_js_1.assert)(hookFilePath);
|
|
188
|
-
(0, getHook_js_1.assertHookFn)(hookFn, { hookName, hookFilePath });
|
|
191
|
+
const { hookFn, hookFilePath, hookTimeout } = hook;
|
|
189
192
|
onBeforePrerenderStartHooks.push({
|
|
190
193
|
hookFn,
|
|
191
194
|
hookName: 'onBeforePrerenderStart',
|
|
192
195
|
hookFilePath,
|
|
193
|
-
pageId: pageConfig.pageId
|
|
196
|
+
pageId: pageConfig.pageId,
|
|
197
|
+
hookTimeout
|
|
194
198
|
});
|
|
195
199
|
})));
|
|
196
200
|
// 0.4 design
|
|
@@ -214,14 +218,15 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
214
218
|
hookFn,
|
|
215
219
|
hookName: 'prerender',
|
|
216
220
|
hookFilePath,
|
|
217
|
-
pageId: p.pageId
|
|
221
|
+
pageId: p.pageId,
|
|
222
|
+
hookTimeout: (0, getHook_js_1.getHookTimeoutDefault)('onBeforePrerenderStart')
|
|
218
223
|
});
|
|
219
224
|
})));
|
|
220
|
-
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId }) => concurrencyLimit(async () => {
|
|
225
|
+
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId, hookTimeout }) => concurrencyLimit(async () => {
|
|
221
226
|
if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
|
|
222
227
|
return;
|
|
223
228
|
}
|
|
224
|
-
const prerenderResult = await hookFn();
|
|
229
|
+
const prerenderResult = await (0, utils_js_1.executeHook)(() => hookFn(), { hookName, hookFilePath, hookTimeout });
|
|
225
230
|
const result = normalizeOnPrerenderHookResult(prerenderResult, hookFilePath, hookName);
|
|
226
231
|
result.forEach(({ url, pageContext }) => {
|
|
227
232
|
{
|
|
@@ -320,23 +325,21 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
320
325
|
let onPrerenderStartHook;
|
|
321
326
|
// V1 design
|
|
322
327
|
if (renderContext.pageConfigs.length > 0) {
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
if (
|
|
326
|
-
|
|
327
|
-
// config.onPrerenderStart isn't a computed nor a cumulative config => definedAt should always be defined
|
|
328
|
-
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
329
|
-
(0, utils_js_1.assert)(hookFilePath);
|
|
328
|
+
const hookName = 'onPrerenderStart';
|
|
329
|
+
const hook = (0, getHook_js_1.getHookFromPageConfigGlobal)(renderContext.pageConfigGlobal, hookName);
|
|
330
|
+
if (hook) {
|
|
331
|
+
(0, utils_js_1.assert)(hook.hookName === 'onPrerenderStart');
|
|
330
332
|
onPrerenderStartHook = {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
...hook,
|
|
334
|
+
// Make TypeScript happy
|
|
335
|
+
hookName
|
|
334
336
|
};
|
|
335
337
|
}
|
|
336
338
|
}
|
|
337
339
|
// Old design
|
|
338
340
|
// TODO/v1-release: remove
|
|
339
341
|
if (renderContext.pageConfigs.length === 0) {
|
|
342
|
+
const hookTimeout = (0, getHook_js_1.getHookTimeoutDefault)('onBeforePrerender');
|
|
340
343
|
const pageFilesWithOnBeforePrerenderHook = renderContext.pageFilesAll.filter((p) => {
|
|
341
344
|
assertExportNames(p);
|
|
342
345
|
if (!p.exportNames?.includes('onBeforePrerender'))
|
|
@@ -362,7 +365,8 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
362
365
|
onPrerenderStartHook = {
|
|
363
366
|
hookFn: hook.onBeforePrerender,
|
|
364
367
|
hookFilePath: hook.hookFilePath,
|
|
365
|
-
hookName: 'onBeforePrerender'
|
|
368
|
+
hookName: 'onBeforePrerender',
|
|
369
|
+
hookTimeout
|
|
366
370
|
};
|
|
367
371
|
}
|
|
368
372
|
if (!onPrerenderStartHook) {
|
|
@@ -397,7 +401,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
397
401
|
});
|
|
398
402
|
return prerenderContext.pageContexts;
|
|
399
403
|
}
|
|
400
|
-
}),
|
|
404
|
+
}), onPrerenderStartHook);
|
|
401
405
|
if (result === null || result === undefined) {
|
|
402
406
|
return;
|
|
403
407
|
}
|
|
@@ -439,7 +443,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
439
443
|
(0, addUrlComputedProps_js_1.addUrlComputedProps)(pageContext);
|
|
440
444
|
});
|
|
441
445
|
}
|
|
442
|
-
async function routeAndPrerender(prerenderContext,
|
|
446
|
+
async function routeAndPrerender(prerenderContext, concurrencyLimit, onComplete) {
|
|
443
447
|
const globalContext = (0, globalContext_js_1.getGlobalContext)();
|
|
444
448
|
(0, utils_js_1.assert)(globalContext.isPrerendering);
|
|
445
449
|
// Route all URLs
|
|
@@ -499,7 +503,7 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderedPages,
|
|
|
499
503
|
throw err;
|
|
500
504
|
}
|
|
501
505
|
const { documentHtml, pageContextSerialized } = res;
|
|
502
|
-
|
|
506
|
+
await onComplete({
|
|
503
507
|
urlOriginal,
|
|
504
508
|
pageContext,
|
|
505
509
|
htmlString: documentHtml,
|
|
@@ -507,11 +511,10 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderedPages,
|
|
|
507
511
|
doNotCreateExtraDirectory: prerenderContext._noExtraDir,
|
|
508
512
|
pageId
|
|
509
513
|
});
|
|
510
|
-
prerenderedPages[pageId] = pageContext;
|
|
511
514
|
})));
|
|
512
515
|
}
|
|
513
|
-
function warnContradictoryNoPrerenderList(
|
|
514
|
-
Object.entries(
|
|
516
|
+
function warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerenderList) {
|
|
517
|
+
Object.entries(prerenderedPageContexts).forEach(([pageId, pageContext]) => {
|
|
515
518
|
const doNotPrerenderListEntry = doNotPrerenderList.find((p) => p.pageId === pageId);
|
|
516
519
|
const { urlOriginal, _providedByHook: providedByHook } = pageContext;
|
|
517
520
|
{
|
|
@@ -523,7 +526,7 @@ function warnContradictoryNoPrerenderList(prerenderedPages, doNotPrerenderList)
|
|
|
523
526
|
(0, utils_js_1.assertWarning)(false, `The ${providedByHook.hookName}() hook defined by ${providedByHook.hookFilePath} returns the URL ${picocolors_1.default.cyan(urlOriginal)}, while ${setByConfigFile} sets the config ${picocolors_1.default.cyan(setByConfigName)} to ${picocolors_1.default.cyan(String(setByConfigValue))}. This is contradictory: either don't set the config ${picocolors_1.default.cyan(setByConfigName)} to ${picocolors_1.default.cyan(String(setByConfigValue))} or remove the URL ${picocolors_1.default.cyan(urlOriginal)} from the list of URLs to be pre-rendered.`, { onlyOnce: true });
|
|
524
527
|
});
|
|
525
528
|
}
|
|
526
|
-
function warnMissingPages(
|
|
529
|
+
function warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial) {
|
|
527
530
|
const isV1 = renderContext.pageConfigs.length > 0;
|
|
528
531
|
const hookName = isV1 ? 'onBeforePrerenderStart' : 'prerender';
|
|
529
532
|
/* TODO/after-v1-design-release: document setting `prerender: false` as an alternative to using prerender.partial (both in the warnings and the docs)
|
|
@@ -531,7 +534,7 @@ function warnMissingPages(prerenderedPages, doNotPrerenderList, renderContext, p
|
|
|
531
534
|
const msgAddendum = `Explicitly opt-out by setting the config ${optOutName} to ${isV1 ? 'false' : 'true'} or use the option prerender.partial`
|
|
532
535
|
*/
|
|
533
536
|
renderContext.allPageIds
|
|
534
|
-
.filter((pageId) => !
|
|
537
|
+
.filter((pageId) => !prerenderedPageContexts[pageId])
|
|
535
538
|
.filter((pageId) => !doNotPrerenderList.find((p) => p.pageId === pageId))
|
|
536
539
|
.filter((pageId) => !(0, error_page_js_1.isErrorPage)(pageId, renderContext.pageConfigs))
|
|
537
540
|
.forEach((pageId) => {
|
|
@@ -539,8 +542,8 @@ function warnMissingPages(prerenderedPages, doNotPrerenderList, renderContext, p
|
|
|
539
542
|
(0, utils_js_1.assertWarning)(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while no ${hookName}() hook returned any URL matching the page's route. You need to use a ${hookName}() hook (https://vike.dev/${hookName}) providing a list of URLs for ${pageAt} that should be pre-rendered. If you don't want to pre-render ${pageAt} then use the option prerender.partial (https://vike.dev/prerender-config#partial) to suppress this warning.`, { onlyOnce: true });
|
|
540
543
|
});
|
|
541
544
|
}
|
|
542
|
-
async function prerender404(
|
|
543
|
-
if (!
|
|
545
|
+
async function prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete) {
|
|
546
|
+
if (!Object.values(prerenderedPageContexts).find(({ urlOriginal }) => urlOriginal === '/404')) {
|
|
544
547
|
let result;
|
|
545
548
|
try {
|
|
546
549
|
result = await (0, renderPageAlreadyRouted_js_1.prerender404Page)(renderContext, prerenderContext.pageContextInit);
|
|
@@ -552,7 +555,7 @@ async function prerender404(htmlFiles, renderContext, prerenderContext) {
|
|
|
552
555
|
if (result) {
|
|
553
556
|
const urlOriginal = '/404';
|
|
554
557
|
const { documentHtml, pageContext } = result;
|
|
555
|
-
|
|
558
|
+
await onComplete({
|
|
556
559
|
urlOriginal,
|
|
557
560
|
pageContext,
|
|
558
561
|
htmlString: documentHtml,
|
|
@@ -563,59 +566,57 @@ async function prerender404(htmlFiles, renderContext, prerenderContext) {
|
|
|
563
566
|
}
|
|
564
567
|
}
|
|
565
568
|
}
|
|
566
|
-
async function
|
|
569
|
+
async function writeFiles({ urlOriginal, pageContext, htmlString, pageContextSerialized, doNotCreateExtraDirectory }, root, outDirClient, onPagePrerender, logLevel) {
|
|
567
570
|
(0, utils_js_1.assert)(urlOriginal.startsWith('/'));
|
|
568
571
|
const writeJobs = [
|
|
569
|
-
write(urlOriginal, pageContext, '.html', htmlString, root, outDirClient, doNotCreateExtraDirectory,
|
|
572
|
+
write(urlOriginal, pageContext, '.html', htmlString, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel)
|
|
570
573
|
];
|
|
571
574
|
if (pageContextSerialized !== null) {
|
|
572
|
-
writeJobs.push(write(urlOriginal, pageContext, '.pageContext.json', pageContextSerialized, root, outDirClient, doNotCreateExtraDirectory,
|
|
575
|
+
writeJobs.push(write(urlOriginal, pageContext, '.pageContext.json', pageContextSerialized, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel));
|
|
573
576
|
}
|
|
574
577
|
await Promise.all(writeJobs);
|
|
575
578
|
}
|
|
576
|
-
function write(urlOriginal, pageContext, fileExtension, fileContent, root, outDirClient, doNotCreateExtraDirectory,
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
outDirClientRelative = outDirClientRelative + '/';
|
|
614
|
-
}
|
|
615
|
-
console.log(`${picocolors_1.default.dim(outDirClientRelative)}${picocolors_1.default.blue(filePathRelative)}`);
|
|
579
|
+
async function write(urlOriginal, pageContext, fileExtension, fileContent, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel) {
|
|
580
|
+
let fileUrl;
|
|
581
|
+
if (fileExtension === '.html') {
|
|
582
|
+
fileUrl = (0, utils_js_1.urlToFile)(urlOriginal, '.html', doNotCreateExtraDirectory);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
fileUrl = (0, getPageContextRequestUrl_js_1.getPageContextRequestUrl)(urlOriginal);
|
|
586
|
+
}
|
|
587
|
+
(0, utils_js_1.assertPosixPath)(fileUrl);
|
|
588
|
+
(0, utils_js_1.assert)(fileUrl.startsWith('/'));
|
|
589
|
+
const filePathRelative = fileUrl.slice(1);
|
|
590
|
+
(0, utils_js_1.assert)(!filePathRelative.startsWith('/'));
|
|
591
|
+
(0, utils_js_1.assertPosixPath)(outDirClient);
|
|
592
|
+
(0, utils_js_1.assertPosixPath)(filePathRelative);
|
|
593
|
+
const filePath = path_1.default.posix.join(outDirClient, filePathRelative);
|
|
594
|
+
if (onPagePrerender) {
|
|
595
|
+
const prerenderPageContext = {};
|
|
596
|
+
(0, utils_js_1.objectAssign)(prerenderPageContext, pageContext);
|
|
597
|
+
(0, utils_js_1.objectAssign)(prerenderPageContext, {
|
|
598
|
+
_prerenderResult: {
|
|
599
|
+
filePath,
|
|
600
|
+
fileContent
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
await onPagePrerender(prerenderPageContext);
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
const { promises } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
607
|
+
const { writeFile, mkdir } = promises;
|
|
608
|
+
await mkdir(path_1.default.posix.dirname(filePath), { recursive: true });
|
|
609
|
+
await writeFile(filePath, fileContent);
|
|
610
|
+
if (logLevel === 'info') {
|
|
611
|
+
(0, utils_js_1.assertPosixPath)(root);
|
|
612
|
+
(0, utils_js_1.assertPosixPath)(outDirClient);
|
|
613
|
+
let outDirClientRelative = path_1.default.posix.relative(root, outDirClient);
|
|
614
|
+
if (!outDirClientRelative.endsWith('/')) {
|
|
615
|
+
outDirClientRelative = outDirClientRelative + '/';
|
|
616
616
|
}
|
|
617
|
+
console.log(`${picocolors_1.default.dim(outDirClientRelative)}${picocolors_1.default.blue(filePathRelative)}`);
|
|
617
618
|
}
|
|
618
|
-
}
|
|
619
|
+
}
|
|
619
620
|
}
|
|
620
621
|
function normalizeOnPrerenderHookResult(prerenderResult, prerenderHookFile, hookName) {
|
|
621
622
|
if (Array.isArray(prerenderResult)) {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.injectAssets__public = void 0;
|
|
4
4
|
const utils_js_1 = require("../../utils.js");
|
|
5
5
|
const injectAssets_js_1 = require("../injectAssets.js");
|
|
6
|
-
// TODO: remove
|
|
6
|
+
// TODO/v1-release: remove
|
|
7
7
|
async function injectAssets__public(htmlString, pageContext) {
|
|
8
8
|
(0, utils_js_1.assertWarning)(false, '`_injectAssets()` is deprecated and will be removed.', { onlyOnce: true, showStackTrace: true });
|
|
9
9
|
(0, utils_js_1.assertUsage)(typeof htmlString === 'string', '[injectAssets(htmlString, pageContext)]: Argument `htmlString` should be a string.', { showStackTrace: true });
|
|
@@ -179,7 +179,7 @@ async function renderTemplate(templateContent, pageContext) {
|
|
|
179
179
|
};
|
|
180
180
|
(0, utils_js_1.assertUsage)(!(0, utils_js_1.isPromise)(templateVar), getErrMsg('a promise', `Did you forget to ${picocolors_1.default.cyan('await')} the promise?`));
|
|
181
181
|
if (templateVar === undefined || templateVar === null) {
|
|
182
|
-
(0, utils_js_1.assertWarning)(false, getErrMsg(`${picocolors_1.default.cyan(String(templateVar))} which will be converted to an empty string`, `Pass
|
|
182
|
+
(0, utils_js_1.assertWarning)(false, getErrMsg(`${picocolors_1.default.cyan(String(templateVar))} which will be converted to an empty string`, `Pass the empty string ${picocolors_1.default.cyan("''")} instead of ${picocolors_1.default.cyan(String(templateVar))} to remove this warning.`), { onlyOnce: false });
|
|
183
183
|
templateVar = '';
|
|
184
184
|
}
|
|
185
185
|
{
|