vike 0.4.150-commit-d9acc70 → 0.4.150-commit-d0822a3
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/index.js +0 -2
- package/dist/cjs/node/plugin/plugins/autoFullBuild.js +3 -2
- package/dist/cjs/node/plugin/plugins/buildConfig.js +17 -36
- package/dist/cjs/node/plugin/plugins/commonConfig.js +1 -1
- package/dist/cjs/node/plugin/plugins/config/resolveExtensions.js +1 -1
- package/dist/cjs/node/plugin/plugins/config/stemUtils.js +1 -1
- package/dist/cjs/node/plugin/plugins/devConfig/determineFsAllowList.js +1 -1
- package/dist/cjs/node/plugin/plugins/importBuild/getVikeManifest.js +38 -0
- package/dist/cjs/node/plugin/plugins/importBuild/index.js +50 -18
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +7 -0
- package/dist/cjs/node/plugin/utils.js +1 -0
- package/dist/cjs/node/runtime/html/serializePageContextClientSide.js +2 -1
- package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderAndDataHooks.js +33 -0
- package/dist/cjs/node/runtime/renderPage/getPageAssets.js +1 -1
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +4 -4
- package/dist/cjs/utils/getDependencyPackageJson.js +1 -1
- package/dist/cjs/utils/getFilePathAbsolute.js +1 -1
- package/dist/cjs/utils/injectRollupInputs.js +29 -0
- package/dist/cjs/utils/isPlainObject.js +1 -1
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/cjs/utils/requireResolve.js +1 -1
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +105 -66
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +1 -1
- package/dist/esm/node/plugin/index.js +0 -2
- package/dist/esm/node/plugin/plugins/autoFullBuild.js +3 -2
- package/dist/esm/node/plugin/plugins/buildConfig.js +17 -36
- package/dist/esm/node/plugin/plugins/commonConfig.js +1 -1
- package/dist/esm/node/plugin/plugins/config/resolveExtensions.js +1 -1
- package/dist/esm/node/plugin/plugins/config/stemUtils.js +1 -1
- package/dist/esm/node/plugin/plugins/devConfig/determineFsAllowList.js +1 -1
- package/dist/esm/node/plugin/plugins/importBuild/getVikeManifest.d.ts +5 -0
- package/dist/esm/node/plugin/plugins/importBuild/getVikeManifest.js +32 -0
- package/dist/esm/node/plugin/plugins/importBuild/index.js +52 -20
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +7 -0
- package/dist/esm/node/plugin/utils.d.ts +1 -0
- package/dist/esm/node/plugin/utils.js +1 -0
- package/dist/esm/node/runtime/html/serializePageContextClientSide.js +2 -1
- package/dist/esm/node/runtime/renderPage/{executeOnBeforeRenderHook.d.ts → executeOnBeforeRenderAndDataHooks.d.ts} +2 -2
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderAndDataHooks.js +30 -0
- package/dist/esm/node/runtime/renderPage/getPageAssets.js +1 -1
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +4 -4
- package/dist/esm/shared/VikeNamespace.d.ts +2 -1
- package/dist/esm/shared/page-configs/Config.d.ts +22 -5
- package/dist/esm/shared/types.d.ts +5 -0
- package/dist/esm/types/index.d.ts +1 -1
- package/dist/esm/utils/getDependencyPackageJson.js +1 -1
- package/dist/esm/utils/getFilePathAbsolute.js +1 -1
- package/dist/esm/utils/injectRollupInputs.d.ts +7 -0
- package/dist/esm/utils/injectRollupInputs.js +26 -0
- package/dist/esm/utils/isPlainObject.js +1 -1
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/dist/esm/utils/requireResolve.js +1 -1
- package/package.json +9 -2
- package/dist/cjs/node/plugin/plugins/manifest.js +0 -59
- package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderHook.js +0 -23
- package/dist/esm/node/plugin/plugins/manifest.d.ts +0 -3
- package/dist/esm/node/plugin/plugins/manifest.js +0 -53
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderHook.js +0 -20
|
@@ -25,10 +25,10 @@ async function getPageContextFromHooks_firstRender(pageContext) {
|
|
|
25
25
|
_hasPageContextFromClient: false
|
|
26
26
|
});
|
|
27
27
|
objectAssign(pageContextFromHooks, await loadPageFilesClientSide(pageContextFromHooks._pageId, pageContext));
|
|
28
|
-
{
|
|
28
|
+
for (const hookName of ['data', 'onBeforeRender']) {
|
|
29
29
|
const pageContextForHook = { ...pageContext, ...pageContextFromHooks };
|
|
30
|
-
if (
|
|
31
|
-
const pageContextFromHook = await
|
|
30
|
+
if (hookClientOnlyExists(hookName, pageContextForHook)) {
|
|
31
|
+
const pageContextFromHook = await executeHookClientSide(hookName, pageContextForHook);
|
|
32
32
|
objectAssign(pageContextFromHooks, pageContextFromHook);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -56,31 +56,34 @@ async function getPageContextFromHooks_uponNavigation(pageContext) {
|
|
|
56
56
|
return pageContextFromHooks;
|
|
57
57
|
}
|
|
58
58
|
async function getPageContextAlreadyRouted(pageContext, isErrorPage) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
const getPageContextFromHooksInit = async (pageId) => {
|
|
60
|
+
const pageContextFromHooks = {
|
|
61
|
+
_hasPageContextFromClient: false,
|
|
62
|
+
_pageId: pageId
|
|
63
|
+
};
|
|
64
|
+
const pageContextFromPageFiles = await loadPageFilesClientSide(pageId, pageContext);
|
|
65
|
+
objectAssign(pageContextFromHooks, pageContextFromPageFiles);
|
|
66
|
+
return pageContextFromHooks;
|
|
67
|
+
};
|
|
68
|
+
let pageContextFromHooks = await getPageContextFromHooksInit(pageContext._pageId);
|
|
69
|
+
let hasPageContextFromServer = false;
|
|
70
|
+
// If pageContextInit has some client data or if one of the hooks guard(), data() or onBeforeRender() is server-side
|
|
71
|
+
// only, then we need to fetch pageContext from the server.
|
|
72
|
+
// We do it before executing any client-side hook, because it contains pageContextInit which may be needed for guard() / data() / onBeforeRender(), for example pageContextInit.user is crucial for guard()
|
|
64
73
|
if (
|
|
65
74
|
// For the error page, we cannot fetch pageContext from the server because the pageContext JSON request is based on the URL
|
|
66
75
|
!isErrorPage &&
|
|
67
|
-
// true if pageContextInit has some client data or the onBeforeRender
|
|
76
|
+
// true if pageContextInit has some client data or at least one of the data() and onBeforeRender() hooks is server-side only:
|
|
68
77
|
(await hasPageContextServer({ ...pageContext, ...pageContextFromHooks }))) {
|
|
69
78
|
const pageContextFromServer = await fetchPageContextFromServer(pageContext);
|
|
70
|
-
|
|
79
|
+
hasPageContextFromServer = true;
|
|
71
80
|
if (!pageContextFromServer['_isError']) {
|
|
72
81
|
objectAssign(pageContextFromHooks, pageContextFromServer);
|
|
73
82
|
}
|
|
74
83
|
else {
|
|
75
84
|
const errorPageId = getErrorPageId(pageContext._pageFilesAll, pageContext._pageConfigs);
|
|
76
85
|
assert(errorPageId);
|
|
77
|
-
pageContextFromHooks =
|
|
78
|
-
objectAssign(pageContextFromHooks, {
|
|
79
|
-
_hasPageContextFromClient: false,
|
|
80
|
-
isHydration: false,
|
|
81
|
-
_pageId: errorPageId
|
|
82
|
-
});
|
|
83
|
-
objectAssign(pageContextFromHooks, await loadPageFilesClientSide(pageContextFromHooks._pageId, pageContext));
|
|
86
|
+
pageContextFromHooks = await getPageContextFromHooksInit(errorPageId);
|
|
84
87
|
assert(hasProp(pageContextFromServer, 'is404', 'boolean'));
|
|
85
88
|
assert(hasProp(pageContextFromServer, 'pageProps', 'object'));
|
|
86
89
|
assert(hasProp(pageContextFromServer.pageProps, 'is404', 'boolean'));
|
|
@@ -89,54 +92,73 @@ async function getPageContextAlreadyRouted(pageContext, isErrorPage) {
|
|
|
89
92
|
objectAssign(pageContextFromHooks, pageContextFromServer);
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
95
|
+
// At this point, we need to call the client-side guard(), data() and onBeforeRender() hooks, if they exist on client
|
|
96
|
+
// env. However if we have fetched pageContext from the server, some of them might have run already on the
|
|
97
|
+
// server-side, so we run only the client-only ones in this case.
|
|
98
|
+
// Note: for the error page, we also execute the client-side data() and onBeforeRender() hooks, but maybe we
|
|
99
|
+
// shouldn't? The server-side does it as well (but maybe it shouldn't).
|
|
100
|
+
for (const hookName of ['guard', 'data', 'onBeforeRender']) {
|
|
101
|
+
const pageContextForHook = {
|
|
102
|
+
_hasPageContextFromServer: hasPageContextFromServer,
|
|
103
|
+
...pageContext,
|
|
104
|
+
...pageContextFromHooks
|
|
105
|
+
};
|
|
106
|
+
if (hookName === 'guard') {
|
|
107
|
+
if (!isErrorPage &&
|
|
108
|
+
// We don't need to call guard() on the client-side if we fetch pageContext from the server side. (Because the `${url}.pageContext.json` HTTP request will already trigger the routing and guard() hook on the server-side.)
|
|
109
|
+
!hasPageContextFromServer) {
|
|
110
|
+
// Should we really call the guard() hook on the client-side? Shouldn't we make the guard() hook a server-side
|
|
111
|
+
// only hook? Or maybe make its env configurable like data() and onBeforeRender()?
|
|
112
|
+
await executeGuardHook(pageContextForHook, (pageContext) => preparePageContextForUserConsumptionClientSide(pageContext, true));
|
|
113
|
+
}
|
|
111
114
|
}
|
|
112
115
|
else {
|
|
113
|
-
assert(
|
|
116
|
+
assert(hookName === 'data' || hookName === 'onBeforeRender');
|
|
117
|
+
if (hookClientOnlyExists(hookName, pageContextForHook) || !hasPageContextFromServer) {
|
|
118
|
+
// This won't do anything if no hook has been defined or if the hook's env.client is false.
|
|
119
|
+
const pageContextFromHook = await executeHookClientSide(hookName, pageContextForHook);
|
|
120
|
+
objectAssign(pageContextFromHooks, pageContextFromHook);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
assert(hasPageContextFromServer);
|
|
124
|
+
}
|
|
114
125
|
}
|
|
115
126
|
}
|
|
127
|
+
objectAssign(pageContextFromHooks, {
|
|
128
|
+
_hasPageContextFromServer: hasPageContextFromServer
|
|
129
|
+
});
|
|
116
130
|
return pageContextFromHooks;
|
|
117
131
|
}
|
|
118
|
-
async function
|
|
119
|
-
const hook = getHook(pageContext,
|
|
132
|
+
async function executeHookClientSide(hookName, pageContext) {
|
|
133
|
+
const hook = getHook(pageContext, hookName);
|
|
120
134
|
if (!hook) {
|
|
121
135
|
// No hook defined or hook's env.client is false
|
|
122
|
-
|
|
123
|
-
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const pageContextForUserConsumption = preparePageContextForUserConsumptionClientSide(pageContext, true);
|
|
139
|
+
const hookResult = await executeHook(() => hook.hookFn(pageContextForUserConsumption), hook);
|
|
140
|
+
const pageContextFromHook = {};
|
|
141
|
+
if (hookName === 'onBeforeRender') {
|
|
142
|
+
assertOnBeforeRenderHookReturn(hookResult, hook.hookFilePath);
|
|
143
|
+
// Note: hookResult looks like { pageContext: { ... } }
|
|
144
|
+
const pageContextFromOnBeforeRender = hookResult?.pageContext;
|
|
145
|
+
if (pageContextFromOnBeforeRender) {
|
|
146
|
+
objectAssign(pageContextFromHook, { _hasPageContextFromClient: true });
|
|
147
|
+
objectAssign(pageContextFromHook, pageContextFromOnBeforeRender);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
assert(hookName === 'data');
|
|
152
|
+
// Note: hookResult can be anything (e.g. an object) and is to be assigned to pageContext.data
|
|
153
|
+
const pageContextFromData = {
|
|
154
|
+
data: hookResult
|
|
124
155
|
};
|
|
125
|
-
|
|
156
|
+
if (hookResult) {
|
|
157
|
+
objectAssign(pageContextFromHook, { _hasPageContextFromClient: true });
|
|
158
|
+
}
|
|
159
|
+
objectAssign(pageContextFromHook, pageContextFromData);
|
|
126
160
|
}
|
|
127
|
-
|
|
128
|
-
const pageContextFromOnBeforeRender = {
|
|
129
|
-
_hasPageContextFromClient: true
|
|
130
|
-
};
|
|
131
|
-
const pageContextForUserConsumption = preparePageContextForUserConsumptionClientSide({
|
|
132
|
-
...pageContext,
|
|
133
|
-
...pageContextFromOnBeforeRender
|
|
134
|
-
}, true);
|
|
135
|
-
const hookResult = await executeHook(() => onBeforeRender(pageContextForUserConsumption), hook);
|
|
136
|
-
assertOnBeforeRenderHookReturn(hookResult, hook.hookFilePath);
|
|
137
|
-
const pageContextFromHook = hookResult?.pageContext;
|
|
138
|
-
objectAssign(pageContextFromOnBeforeRender, pageContextFromHook);
|
|
139
|
-
return pageContextFromOnBeforeRender;
|
|
161
|
+
return pageContextFromHook;
|
|
140
162
|
}
|
|
141
163
|
// Workaround for the fact that the client-side cannot known whether a pageContext JSON request is needed in order to fetch pageContextInit data passed to the client.
|
|
142
164
|
// - The workaround is reliable as long as the user sets additional pageContextInit to undefined instead of not defining the property:
|
|
@@ -155,35 +177,53 @@ function setPageContextInitHasClientData(pageContext) {
|
|
|
155
177
|
globalObject.pageContextInitHasClientData = true;
|
|
156
178
|
}
|
|
157
179
|
}
|
|
180
|
+
// TODO/v1-release: make it sync
|
|
158
181
|
async function hasPageContextServer(pageContext) {
|
|
159
|
-
return !!globalObject.pageContextInitHasClientData ||
|
|
182
|
+
return (!!globalObject.pageContextInitHasClientData ||
|
|
183
|
+
(await hookServerOnlyExists('data', pageContext)) ||
|
|
184
|
+
(await hookServerOnlyExists('onBeforeRender', pageContext)));
|
|
160
185
|
}
|
|
161
|
-
|
|
186
|
+
// TODO/v1-release: make it sync
|
|
187
|
+
/**
|
|
188
|
+
* @param hookName
|
|
189
|
+
* @param pageContext
|
|
190
|
+
* @returns `true` if the given page has a `hookName` hook defined with a server-only env.
|
|
191
|
+
*/
|
|
192
|
+
async function hookServerOnlyExists(hookName, pageContext) {
|
|
162
193
|
if (pageContext._pageConfigs.length > 0) {
|
|
163
194
|
// V1
|
|
164
195
|
const pageConfig = getPageConfig(pageContext._pageId, pageContext._pageConfigs);
|
|
165
|
-
const
|
|
166
|
-
assert(isObject(
|
|
167
|
-
return !!
|
|
196
|
+
const hookEnv = getConfigValue(pageConfig, `${hookName}Env`)?.value ?? {};
|
|
197
|
+
assert(isObject(hookEnv));
|
|
198
|
+
return !!hookEnv.server && !hookEnv.client;
|
|
168
199
|
}
|
|
169
200
|
else {
|
|
170
201
|
// TODO/v1-release: remove
|
|
171
202
|
// V0.4
|
|
203
|
+
// data() hooks didn't exist in the V0.4 design
|
|
204
|
+
if (hookName === 'data')
|
|
205
|
+
return false;
|
|
206
|
+
assert(hookName === 'onBeforeRender');
|
|
172
207
|
const { hasOnBeforeRenderServerSideOnlyHook } = await analyzePageServerSide(pageContext._pageFilesAll, pageContext._pageId);
|
|
173
208
|
return hasOnBeforeRenderServerSideOnlyHook;
|
|
174
209
|
}
|
|
175
210
|
}
|
|
176
|
-
|
|
211
|
+
/**
|
|
212
|
+
* @param hookName
|
|
213
|
+
* @param pageContext
|
|
214
|
+
* @returns `true` if the given page has a `hookName` hook defined with a client-only env.
|
|
215
|
+
*/
|
|
216
|
+
function hookClientOnlyExists(hookName, pageContext) {
|
|
177
217
|
if (pageContext._pageConfigs.length > 0) {
|
|
178
218
|
// V1
|
|
179
219
|
const pageConfig = getPageConfig(pageContext._pageId, pageContext._pageConfigs);
|
|
180
|
-
const
|
|
181
|
-
assert(isObject(
|
|
182
|
-
return !!
|
|
220
|
+
const hookEnv = getConfigValue(pageConfig, `${hookName}Env`)?.value ?? {};
|
|
221
|
+
assert(isObject(hookEnv));
|
|
222
|
+
return !!hookEnv.client && !hookEnv.server;
|
|
183
223
|
}
|
|
184
224
|
else {
|
|
185
225
|
// TODO/v1-release: remove
|
|
186
|
-
// Client-only onBeforeRender() hooks were never supported for the V0.4 design
|
|
226
|
+
// Client-only onBeforeRender() or data() hooks were never supported for the V0.4 design
|
|
187
227
|
return false;
|
|
188
228
|
}
|
|
189
229
|
}
|
|
@@ -212,7 +252,6 @@ async function fetchPageContextFromServer(pageContext) {
|
|
|
212
252
|
}
|
|
213
253
|
assert(hasProp(pageContextFromServer, '_pageId', 'string'));
|
|
214
254
|
removeBuiltInOverrides(pageContextFromServer);
|
|
215
|
-
objectAssign(pageContextFromServer, { _hasPageContextFromServer: true });
|
|
216
255
|
return pageContextFromServer;
|
|
217
256
|
}
|
|
218
257
|
function isAlreadyServerSideRouted(err) {
|
|
@@ -133,7 +133,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
133
133
|
console.error(err);
|
|
134
134
|
}
|
|
135
135
|
else {
|
|
136
|
-
// We swallow throw redirect()/render() called by client-side hooks onBeforeRender() and guard()
|
|
136
|
+
// We swallow throw redirect()/render() called by client-side hooks onBeforeRender(), data() and guard()
|
|
137
137
|
// We handle the abort error down below.
|
|
138
138
|
}
|
|
139
139
|
if (shouldSwallowAndInterrupt(err, pageContext, isFirstRender))
|
|
@@ -8,7 +8,6 @@ import { buildConfig } from './plugins/buildConfig.js';
|
|
|
8
8
|
import { previewConfig } from './plugins/previewConfig.js';
|
|
9
9
|
import { autoFullBuild } from './plugins/autoFullBuild.js';
|
|
10
10
|
import { devConfig } from './plugins/devConfig/index.js';
|
|
11
|
-
import { manifest } from './plugins/manifest.js';
|
|
12
11
|
import { packageJsonFile } from './plugins/packageJsonFile.js';
|
|
13
12
|
import { removeRequireHookPlugin } from './plugins/removeRequireHookPlugin.js';
|
|
14
13
|
import { importUserCode } from './plugins/importUserCode/index.js';
|
|
@@ -35,7 +34,6 @@ function plugin(vikeConfig) {
|
|
|
35
34
|
buildConfig(),
|
|
36
35
|
previewConfig(),
|
|
37
36
|
...autoFullBuild(),
|
|
38
|
-
...manifest(),
|
|
39
37
|
packageJsonFile(),
|
|
40
38
|
removeRequireHookPlugin(),
|
|
41
39
|
distFileNames(),
|
|
@@ -57,9 +57,10 @@ async function triggerFullBuild(config, configVike, bundle) {
|
|
|
57
57
|
return; // already triggered
|
|
58
58
|
if (isDisabled(configVike))
|
|
59
59
|
return;
|
|
60
|
+
/* Is this @vitejs/plugin-legacy workaround still needed? Should we re-implement it?
|
|
60
61
|
// vike.json missing => it isn't a `$ vite build` call (e.g. @vitejs/plugin-legacy calls Vite's build() API) => skip
|
|
61
|
-
if (!bundle['vike.json'])
|
|
62
|
-
|
|
62
|
+
if (!bundle['vike.json']) return
|
|
63
|
+
*/
|
|
63
64
|
const configFromCli = !isViteCliCall() ? null : getViteConfigFromCli();
|
|
64
65
|
const configInline = {
|
|
65
66
|
...configFromCli,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export { buildConfig };
|
|
2
2
|
export { assertRollupInput };
|
|
3
3
|
export { analyzeClientEntries };
|
|
4
|
-
import { assert, resolveOutDir,
|
|
5
|
-
import { virtualFileIdImportUserCodeServer } from '../../shared/virtual-files/virtualFileImportUserCode.js';
|
|
4
|
+
import { assert, resolveOutDir, viteIsSSR, getFilePathAbsolute, addOnBeforeLogHook, removeFileExtention, unique, assertPosixPath, assertUsage, injectRollupInputs, normalizeRollupInput } from '../utils.js';
|
|
6
5
|
import { getVikeConfig } from './importUserCode/v1-design/getVikeConfig.js';
|
|
7
6
|
import { getConfigValue } from '../../../shared/page-configs/helpers.js';
|
|
8
7
|
import { findPageFiles } from '../shared/findPageFiles.js';
|
|
@@ -13,7 +12,7 @@ import { createRequire } from 'module';
|
|
|
13
12
|
import { getClientEntryFilePath } from '../../shared/getClientEntryFilePath.js';
|
|
14
13
|
import fs from 'fs/promises';
|
|
15
14
|
import path from 'path';
|
|
16
|
-
// @ts-ignore
|
|
15
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
17
16
|
const importMetaUrl = import.meta.url;
|
|
18
17
|
const require_ = createRequire(importMetaUrl);
|
|
19
18
|
const manifestTempFile = '_temp_manifest.json';
|
|
@@ -27,14 +26,9 @@ function buildConfig() {
|
|
|
27
26
|
order: 'post',
|
|
28
27
|
async handler(config) {
|
|
29
28
|
assertRollupInput(config);
|
|
30
|
-
const userInputs = normalizeRollupInput(config.build.rollupOptions.input);
|
|
31
29
|
const entries = await getEntries(config);
|
|
32
30
|
assert(Object.keys(entries).length > 0);
|
|
33
|
-
|
|
34
|
-
...entries,
|
|
35
|
-
...userInputs
|
|
36
|
-
};
|
|
37
|
-
config.build.rollupOptions.input = input;
|
|
31
|
+
config.build.rollupOptions.input = injectRollupInputs(entries, config);
|
|
38
32
|
addLogHook();
|
|
39
33
|
}
|
|
40
34
|
},
|
|
@@ -72,12 +66,12 @@ async function getEntries(config) {
|
|
|
72
66
|
const { pageConfigs } = await getVikeConfig(config, false);
|
|
73
67
|
assertUsage(Object.keys(pageFileEntries).length !== 0 || pageConfigs.length !== 0, 'At least one page should be defined, see https://vike.dev/add');
|
|
74
68
|
if (viteIsSSR(config)) {
|
|
75
|
-
const
|
|
69
|
+
const pageEntries = getPageEntries(pageConfigs);
|
|
76
70
|
const entries = {
|
|
77
|
-
|
|
78
|
-
importBuild: resolve('dist/esm/node/importBuild.js'),
|
|
71
|
+
// importBuild: resolve('dist/esm/node/importBuild.js'), // TODO/next-major-release: remove
|
|
79
72
|
...pageFileEntries,
|
|
80
|
-
|
|
73
|
+
// Ensure Rollup generates a bundle per page: https://github.com/vikejs/vike/issues/349#issuecomment-1166247275
|
|
74
|
+
...pageEntries
|
|
81
75
|
};
|
|
82
76
|
return entries;
|
|
83
77
|
}
|
|
@@ -102,6 +96,14 @@ async function getEntries(config) {
|
|
|
102
96
|
return entries;
|
|
103
97
|
}
|
|
104
98
|
}
|
|
99
|
+
function getPageEntries(pageConfigs) {
|
|
100
|
+
const pageEntries = {};
|
|
101
|
+
pageConfigs.forEach((pageConfig) => {
|
|
102
|
+
const { entryName, entryTarget } = getEntryFromPageConfig(pageConfig, false);
|
|
103
|
+
pageEntries[entryName] = entryTarget;
|
|
104
|
+
});
|
|
105
|
+
return pageEntries;
|
|
106
|
+
}
|
|
105
107
|
function analyzeClientEntries(pageConfigs, config) {
|
|
106
108
|
let hasClientRouting = false;
|
|
107
109
|
let hasServerRouting = false;
|
|
@@ -116,6 +118,7 @@ function analyzeClientEntries(pageConfigs, config) {
|
|
|
116
118
|
hasServerRouting = true;
|
|
117
119
|
}
|
|
118
120
|
{
|
|
121
|
+
// Ensure Rollup generates a bundle per page: https://github.com/vikejs/vike/issues/349#issuecomment-1166247275
|
|
119
122
|
const { entryName, entryTarget } = getEntryFromPageConfig(pageConfig, true);
|
|
120
123
|
clientEntries[entryName] = entryTarget;
|
|
121
124
|
}
|
|
@@ -133,14 +136,6 @@ function analyzeClientEntries(pageConfigs, config) {
|
|
|
133
136
|
});
|
|
134
137
|
return { hasClientRouting, hasServerRouting, clientEntries };
|
|
135
138
|
}
|
|
136
|
-
function analyzeServerEntries(pageConfigs) {
|
|
137
|
-
const serverEntries = {};
|
|
138
|
-
pageConfigs.forEach((pageConfig) => {
|
|
139
|
-
const { entryName, entryTarget } = getEntryFromPageConfig(pageConfig, false);
|
|
140
|
-
serverEntries[entryName] = entryTarget;
|
|
141
|
-
});
|
|
142
|
-
return serverEntries;
|
|
143
|
-
}
|
|
144
139
|
// Ensure Rollup creates entries for each page file, see https://github.com/vikejs/vike/issues/350
|
|
145
140
|
// (Otherwise the page files may be missing in the client manifest.json)
|
|
146
141
|
async function getPageFileEntries(config, includeAssetsImportedByServer) {
|
|
@@ -196,20 +191,6 @@ function resolve(filePath) {
|
|
|
196
191
|
// [RELATIVE_PATH_FROM_DIST] Current directory: node_modules/vike/dist/esm/node/plugin/plugins/
|
|
197
192
|
return require_.resolve(`../../../../../${filePath}`);
|
|
198
193
|
}
|
|
199
|
-
function normalizeRollupInput(input) {
|
|
200
|
-
if (!input) {
|
|
201
|
-
return {};
|
|
202
|
-
}
|
|
203
|
-
// Usually `input` is an oject, but the user can set it as a `string` or `string[]`
|
|
204
|
-
if (typeof input === 'string') {
|
|
205
|
-
input = [input];
|
|
206
|
-
}
|
|
207
|
-
if (Array.isArray(input)) {
|
|
208
|
-
return Object.fromEntries(input.map((input) => [input, input]));
|
|
209
|
-
}
|
|
210
|
-
assert(isObject(input));
|
|
211
|
-
return input;
|
|
212
|
-
}
|
|
213
194
|
function addLogHook() {
|
|
214
195
|
const tty = process.stdout.isTTY && !process.env.CI; // Equals https://github.com/vitejs/vite/blob/193d55c7b9cbfec5b79ebfca276d4a721e7de14d/packages/vite/src/node/plugins/reporter.ts#L27
|
|
215
196
|
if (!tty)
|
|
@@ -241,5 +222,5 @@ function assertRollupInput(config) {
|
|
|
241
222
|
const userInputs = normalizeRollupInput(config.build.rollupOptions.input);
|
|
242
223
|
const htmlInputs = Object.values(userInputs).filter((entry) => entry.endsWith('.html') || entry.endsWith('.htm'));
|
|
243
224
|
const htmlInput = htmlInputs[0];
|
|
244
|
-
assertUsage(htmlInput === undefined, `The entry ${htmlInput} of config build.rollupOptions.input is an HTML entry which is forbidden when using
|
|
225
|
+
assertUsage(htmlInput === undefined, `The entry ${htmlInput} of config build.rollupOptions.input is an HTML entry which is forbidden when using Vike, instead follow https://vike.dev/add`);
|
|
245
226
|
}
|
|
@@ -6,7 +6,7 @@ import pc from '@brillout/picocolors';
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import { assertResolveAlias } from './commonConfig/assertResolveAlias.js';
|
|
9
|
-
// @ts-ignore
|
|
9
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
10
10
|
const importMetaUrl = import.meta.url;
|
|
11
11
|
const require_ = createRequire(importMetaUrl);
|
|
12
12
|
function commonConfig() {
|
|
@@ -5,7 +5,7 @@ import fs from 'fs';
|
|
|
5
5
|
import { isValidFileType } from '../../../../shared/getPageFiles/fileTypes.js';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import pc from '@brillout/picocolors';
|
|
8
|
-
// @ts-ignore
|
|
8
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
9
9
|
const importMetaUrl = import.meta.url;
|
|
10
10
|
const require_ = createRequire(importMetaUrl);
|
|
11
11
|
function resolveExtensions(configs, config) {
|
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import { assert, assertUsage, assertWarning, toPosixPath, assertPosixPath, getDependencyRootDir, findUserPackageJsonPath } from '../../utils.js';
|
|
5
5
|
import { import_ } from '@brillout/import';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
|
-
// @ts-ignore
|
|
7
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
8
8
|
const importMetaUrl = import.meta.url;
|
|
9
9
|
const require_ = createRequire(importMetaUrl);
|
|
10
10
|
async function getStemPackages(userAppRootDir) {
|
|
@@ -6,7 +6,7 @@ import { assert } from '../../utils.js';
|
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import { dirname } from 'path';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
|
-
// @ts-ignore
|
|
9
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
10
10
|
const importMetaUrl = import.meta.url;
|
|
11
11
|
const require_ = createRequire(importMetaUrl);
|
|
12
12
|
const __dirname_ = dirname(fileURLToPath(importMetaUrl));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { getVikeManifest };
|
|
2
|
+
import { ResolvedConfig } from 'vite';
|
|
3
|
+
import { type PluginManifest } from '../../../shared/assertPluginManifest.js';
|
|
4
|
+
import type { ConfigVikeResolved } from '../../../../shared/ConfigVike.js';
|
|
5
|
+
declare function getVikeManifest(config: ResolvedConfig, configVike: ConfigVikeResolved): PluginManifest;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export { getVikeManifest };
|
|
2
|
+
import { projectInfo, toPosixPath, assertPosixPath, isNotNullish } from '../../utils.js';
|
|
3
|
+
import { assertPluginManifest } from '../../../shared/assertPluginManifest.js';
|
|
4
|
+
import { isUsingClientRouter } from '../extractExportNamesPlugin.js';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getRuntimeManifest } from '../../../runtime/globalContext.js';
|
|
7
|
+
function getVikeManifest(config, configVike) {
|
|
8
|
+
const runtimeManifest = getRuntimeManifest(configVike);
|
|
9
|
+
const manifest = {
|
|
10
|
+
version: projectInfo.projectVersion,
|
|
11
|
+
usesClientRouter: isUsingClientRouter(),
|
|
12
|
+
manifestKeyMap: getManifestKeyMap(configVike, config),
|
|
13
|
+
...runtimeManifest
|
|
14
|
+
};
|
|
15
|
+
assertPluginManifest(manifest);
|
|
16
|
+
return manifest;
|
|
17
|
+
}
|
|
18
|
+
function getManifestKeyMap(configVike, config) {
|
|
19
|
+
const manifestKeyMap = {};
|
|
20
|
+
configVike.extensions
|
|
21
|
+
.map(({ pageConfigsDistFiles }) => pageConfigsDistFiles)
|
|
22
|
+
.flat()
|
|
23
|
+
.filter(isNotNullish)
|
|
24
|
+
.forEach(({ importPath, filePath }) => {
|
|
25
|
+
// Recreating https://github.com/vitejs/vite/blob/8158ece72b66307e7b607b98496891610ca70ea2/packages/vite/src/node/plugins/manifest.ts#L38
|
|
26
|
+
const filePathRelative = path.posix.relative(config.root, toPosixPath(filePath));
|
|
27
|
+
assertPosixPath(filePathRelative);
|
|
28
|
+
assertPosixPath(importPath);
|
|
29
|
+
manifestKeyMap[importPath] = filePathRelative;
|
|
30
|
+
});
|
|
31
|
+
return manifestKeyMap;
|
|
32
|
+
}
|
|
@@ -1,54 +1,86 @@
|
|
|
1
1
|
export { importBuild };
|
|
2
|
-
import { importBuild as importBuild_ } from '@brillout/vite-plugin-import-build/plugin.js';
|
|
3
|
-
import { getOutDirs, projectInfo, toPosixPath } from '../../utils.js';
|
|
2
|
+
import { importBuild as importBuild_, findImportBuildBundleEntry } from '@brillout/vite-plugin-import-build/plugin.js';
|
|
3
|
+
import { assert, getOutDirs, projectInfo, toPosixPath, viteIsSSR } from '../../utils.js';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { createRequire } from 'module';
|
|
6
|
-
|
|
6
|
+
import { getConfigVike } from '../../../shared/getConfigVike.js';
|
|
7
|
+
import { getVikeManifest } from './getVikeManifest.js';
|
|
8
|
+
import fs from 'fs/promises';
|
|
9
|
+
import { virtualFileIdImportUserCodeServer } from '../../../shared/virtual-files/virtualFileImportUserCode.js';
|
|
10
|
+
// @ts-ignore Shimmed by dist-cjs-fixup.js for CJS build.
|
|
7
11
|
const importMetaUrl = import.meta.url;
|
|
8
12
|
const require_ = createRequire(importMetaUrl);
|
|
13
|
+
const ASSETS_MAP = '__VITE_ASSETS_MAP__';
|
|
9
14
|
function importBuild() {
|
|
10
15
|
let config;
|
|
16
|
+
let configVike;
|
|
11
17
|
return [
|
|
12
18
|
{
|
|
13
19
|
name: 'vike:importBuild:config',
|
|
14
20
|
enforce: 'post',
|
|
15
|
-
configResolved(config_) {
|
|
21
|
+
async configResolved(config_) {
|
|
16
22
|
config = config_;
|
|
23
|
+
configVike = await getConfigVike(config);
|
|
24
|
+
},
|
|
25
|
+
async writeBundle(options, bundle) {
|
|
26
|
+
if (!viteIsSSR(config))
|
|
27
|
+
return;
|
|
28
|
+
await replace_ASSETS_MAP(options, bundle);
|
|
17
29
|
}
|
|
18
30
|
},
|
|
19
31
|
importBuild_({
|
|
20
|
-
getImporterCode: (
|
|
21
|
-
|
|
22
|
-
return getImporterCode(config, pageFilesEntry);
|
|
32
|
+
getImporterCode: () => {
|
|
33
|
+
return getEntryCode(config, configVike);
|
|
23
34
|
},
|
|
24
35
|
libraryName: projectInfo.projectName
|
|
25
36
|
})
|
|
26
37
|
];
|
|
27
38
|
}
|
|
28
|
-
function
|
|
39
|
+
function getEntryCode(config, configVike) {
|
|
29
40
|
const importPath = getImportPath(config);
|
|
30
|
-
|
|
41
|
+
const vikeManifest = getVikeManifest(config, configVike);
|
|
31
42
|
const importerCode = [
|
|
32
|
-
|
|
33
|
-
`
|
|
43
|
+
` import { setImportBuildGetters } from '${importPath}';`,
|
|
44
|
+
` import * as pageFiles from '${virtualFileIdImportUserCodeServer}';`,
|
|
34
45
|
' setImportBuildGetters({',
|
|
35
|
-
` pageFiles: () =>
|
|
46
|
+
` pageFiles: () => pageFiles,`,
|
|
36
47
|
// TODO: rename clientManifest -> assetManifest
|
|
37
|
-
|
|
38
|
-
// TODO:
|
|
39
|
-
|
|
40
|
-
" pluginManifest: () => require('../client/vike.json'),",
|
|
48
|
+
` clientManifest: () => { return ${ASSETS_MAP} },`,
|
|
49
|
+
// TODO: rename pluginManifest -> vikeManifest
|
|
50
|
+
` pluginManifest: () => (${JSON.stringify(vikeManifest, null, 2)}),`,
|
|
41
51
|
' });',
|
|
42
|
-
'})()',
|
|
43
52
|
''
|
|
44
53
|
].join('\n');
|
|
45
54
|
return importerCode;
|
|
46
55
|
}
|
|
56
|
+
async function replace_ASSETS_MAP(options, bundle) {
|
|
57
|
+
const { dir } = options;
|
|
58
|
+
assert(dir);
|
|
59
|
+
// I guess importBuild won't be found in the bundle when using @vitejs/plugin-legacy
|
|
60
|
+
const importBuildEntry = findImportBuildBundleEntry(bundle);
|
|
61
|
+
const importBuildFilePath = path.join(dir, importBuildEntry.fileName);
|
|
62
|
+
const assetsJsonFilePath = path.join(dir, '..', 'assets.json');
|
|
63
|
+
const [assetsJsonString, importBuildFileContent] = await Promise.all([
|
|
64
|
+
await fs.readFile(assetsJsonFilePath, 'utf8'),
|
|
65
|
+
await fs.readFile(importBuildFilePath, 'utf8')
|
|
66
|
+
]);
|
|
67
|
+
const importBuildFileContentFixed = importBuildFileContent.replace(ASSETS_MAP, assetsJsonString);
|
|
68
|
+
assert(importBuildFileContentFixed !== importBuildFileContent);
|
|
69
|
+
await fs.writeFile(importBuildFilePath, importBuildFileContentFixed);
|
|
70
|
+
}
|
|
47
71
|
function getImportPath(config) {
|
|
72
|
+
// We resolve filePathAbsolute even if we don't use it: we use require.resolve() as an assertion that the relative path is correct
|
|
48
73
|
const filePathAbsolute = toPosixPath(
|
|
49
74
|
// [RELATIVE_PATH_FROM_DIST] Current file: node_modules/vike/dist/esm/node/plugin/plugins/importBuild/index.js
|
|
50
75
|
require_.resolve(`../../../../../../dist/esm/node/runtime/globalContext/loadImportBuild.js`));
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
if (
|
|
77
|
+
// Let's implement a new config if a user needs the import to be a relative path instead of 'vike/__internal/loadImportBuild' (AFAIK a relative path is needed only if a framework has npm package 'vike' as direct dependency instead of a peer dependency and if the user of that framework uses pnpm)
|
|
78
|
+
true) {
|
|
79
|
+
return 'vike/__internal/loadImportBuild';
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const { outDirServer } = getOutDirs(config);
|
|
83
|
+
const filePathRelative = path.posix.relative(outDirServer, filePathAbsolute);
|
|
84
|
+
return filePathRelative;
|
|
85
|
+
}
|
|
54
86
|
}
|
|
@@ -36,6 +36,9 @@ const configDefinitionsBuiltIn = {
|
|
|
36
36
|
guard: {
|
|
37
37
|
env: { server: true, client: 'if-client-routing' }
|
|
38
38
|
},
|
|
39
|
+
data: {
|
|
40
|
+
env: { server: true }
|
|
41
|
+
},
|
|
39
42
|
iKnowThePerformanceRisksOfAsyncRouteFunctions: {
|
|
40
43
|
env: { server: true, client: 'if-client-routing', eager: true }
|
|
41
44
|
},
|
|
@@ -76,6 +79,10 @@ const configDefinitionsBuiltIn = {
|
|
|
76
79
|
env: { client: true },
|
|
77
80
|
_computed: (configValueSources) => !isConfigSet(configValueSources, 'onBeforeRender') ? null : getConfigEnv(configValueSources, 'onBeforeRender')
|
|
78
81
|
},
|
|
82
|
+
dataEnv: {
|
|
83
|
+
env: { client: true },
|
|
84
|
+
_computed: (configValueSources) => !isConfigSet(configValueSources, 'data') ? null : getConfigEnv(configValueSources, 'data')
|
|
85
|
+
},
|
|
79
86
|
hooksTimeout: {
|
|
80
87
|
env: { server: true, client: true }
|
|
81
88
|
}
|
|
@@ -16,7 +16,8 @@ const PASS_TO_CLIENT = [
|
|
|
16
16
|
'_abortCaller',
|
|
17
17
|
*/
|
|
18
18
|
'_pageContextInitHasClientData',
|
|
19
|
-
'_pageId'
|
|
19
|
+
'_pageId',
|
|
20
|
+
'data' // for data() hook
|
|
20
21
|
];
|
|
21
22
|
const PASS_TO_CLIENT_ERROR_PAGE = ['pageProps', 'is404', '_isError'];
|
|
22
23
|
function serializePageContextClientSide(pageContext) {
|