@netlify/plugin-nextjs 4.38.1 → 4.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/helpers/config.js +18 -11
- package/lib/helpers/flags.js +7 -1
- package/lib/helpers/functions.js +86 -5
- package/lib/index.js +3 -1
- package/lib/templates/getHandler.js +2 -0
- package/lib/templates/handlerUtils.js +6 -0
- package/lib/templates/requireHooks.js +79 -70
- package/lib/templates/server.js +8 -3
- package/package.json +3 -3
- package/src/templates/edge-shared/utils.ts +3 -0
package/lib/helpers/config.js
CHANGED
|
@@ -69,8 +69,8 @@ exports.hasManuallyAddedModule = hasManuallyAddedModule;
|
|
|
69
69
|
* so that the file `[id].js` is matched correctly.
|
|
70
70
|
*/
|
|
71
71
|
const escapeGlob = (path) => path.replace(/\[/g, '*').replace(/]/g, '*');
|
|
72
|
-
const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [], apiLambdas, splitApiRoutes, }) => {
|
|
73
|
-
var _a
|
|
72
|
+
const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [], apiLambdas, ssrLambdas, splitApiRoutes, }) => {
|
|
73
|
+
var _a;
|
|
74
74
|
const config = await (0, exports.getRequiredServerFiles)(publish);
|
|
75
75
|
const files = config.files || [];
|
|
76
76
|
const cssFilesToInclude = files.filter((f) => f.startsWith(`${publish}/static/css/`));
|
|
@@ -97,16 +97,23 @@ const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [],
|
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
const configureLambda = (lambda) => {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
const { functionName, includedFiles } = lambda;
|
|
103
|
+
(_a = netlifyConfig.functions)[functionName] || (_a[functionName] = { included_files: [] });
|
|
104
|
+
netlifyConfig.functions[functionName].node_bundler = 'none';
|
|
105
|
+
(_b = netlifyConfig.functions[functionName]).included_files || (_b.included_files = []);
|
|
106
|
+
netlifyConfig.functions[functionName].included_files.push(...includedFiles.map(escapeGlob));
|
|
107
|
+
};
|
|
108
|
+
if (ssrLambdas.length === 0) {
|
|
109
|
+
configureFunction(constants_1.HANDLER_FUNCTION_NAME);
|
|
110
|
+
configureFunction(constants_1.ODB_FUNCTION_NAME);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
ssrLambdas.forEach(configureLambda);
|
|
114
|
+
}
|
|
102
115
|
if (splitApiRoutes) {
|
|
103
|
-
|
|
104
|
-
const { functionName, includedFiles } = apiLambda;
|
|
105
|
-
(_b = netlifyConfig.functions)[functionName] || (_b[functionName] = { included_files: [] });
|
|
106
|
-
netlifyConfig.functions[functionName].node_bundler = 'none';
|
|
107
|
-
(_c = netlifyConfig.functions[functionName]).included_files || (_c.included_files = []);
|
|
108
|
-
netlifyConfig.functions[functionName].included_files.push(...includedFiles.map(escapeGlob));
|
|
109
|
-
}
|
|
116
|
+
apiLambdas.forEach(configureLambda);
|
|
110
117
|
}
|
|
111
118
|
else {
|
|
112
119
|
configureFunction('_api_*');
|
package/lib/helpers/flags.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.splitApiRoutes = void 0;
|
|
6
|
+
exports.bundleBasedOnNftFiles = exports.splitApiRoutes = void 0;
|
|
7
7
|
const destr_1 = __importDefault(require("destr"));
|
|
8
8
|
const fs_extra_1 = require("fs-extra");
|
|
9
9
|
const pathe_1 = require("pathe");
|
|
@@ -32,3 +32,9 @@ const splitApiRoutes = (featureFlags, publish) => {
|
|
|
32
32
|
return isEnabled;
|
|
33
33
|
};
|
|
34
34
|
exports.splitApiRoutes = splitApiRoutes;
|
|
35
|
+
const bundleBasedOnNftFiles = (featureFlags) => {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const isEnabled = (_b = (_a = (0, destr_1.default)(process.env.NEXT_BUNDLE_BASED_ON_NFT_FILES)) !== null && _a !== void 0 ? _a : featureFlags.next_bundle_based_on_nft_files) !== null && _b !== void 0 ? _b : false;
|
|
38
|
+
return isEnabled;
|
|
39
|
+
};
|
|
40
|
+
exports.bundleBasedOnNftFiles = bundleBasedOnNftFiles;
|
package/lib/helpers/functions.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.warnOnApiRoutes = exports.packSingleFunction = exports.getExtendedApiRouteConfigs = exports.getApiRouteConfigs = exports.getAPILambdas = exports.
|
|
6
|
+
exports.warnOnApiRoutes = exports.packSingleFunction = exports.getExtendedApiRouteConfigs = exports.getApiRouteConfigs = exports.getAPILambdas = exports.getSSRLambdas = exports.getCommonDependencies = exports.traceNPMPackage = exports.setupImageFunction = exports.generatePagesResolver = exports.generateFunctions = void 0;
|
|
7
7
|
const node_bridge_1 = __importDefault(require("@vercel/node-bridge"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const destr_1 = __importDefault(require("destr"));
|
|
@@ -21,7 +21,7 @@ const files_1 = require("./files");
|
|
|
21
21
|
const functionsMetaData_1 = require("./functionsMetaData");
|
|
22
22
|
const pack_1 = require("./pack");
|
|
23
23
|
const utils_1 = require("./utils");
|
|
24
|
-
const generateFunctions = async ({ FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, PUBLISH_DIR }, appDir, apiLambdas) => {
|
|
24
|
+
const generateFunctions = async ({ FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, PUBLISH_DIR }, appDir, apiLambdas, ssrLambdas) => {
|
|
25
25
|
const publish = (0, pathe_1.resolve)(PUBLISH_DIR);
|
|
26
26
|
const functionsDir = (0, pathe_1.resolve)(INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC);
|
|
27
27
|
const functionDir = (0, pathe_1.join)(functionsDir, constants_1.HANDLER_FUNCTION_NAME);
|
|
@@ -81,6 +81,11 @@ const generateFunctions = async ({ FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS
|
|
|
81
81
|
await (0, fs_extra_1.copyFile)((0, pathe_1.join)(__dirname, '..', '..', 'lib', 'templates', 'requireHooks.js'), (0, pathe_1.join)(functionsDir, functionName, 'requireHooks.js'));
|
|
82
82
|
await (0, fs_extra_1.copyFile)((0, pathe_1.join)(__dirname, '..', '..', 'lib', 'templates', 'handlerUtils.js'), (0, pathe_1.join)(functionsDir, functionName, 'handlerUtils.js'));
|
|
83
83
|
await (0, functionsMetaData_1.writeFunctionConfiguration)({ functionName, functionTitle, functionsDir });
|
|
84
|
+
const nfInternalFiles = await (0, tiny_glob_1.default)((0, pathe_1.join)(functionsDir, functionName, '**'));
|
|
85
|
+
const lambda = ssrLambdas.find((l) => l.functionName === functionName);
|
|
86
|
+
if (lambda) {
|
|
87
|
+
lambda.includedFiles.push(...nfInternalFiles);
|
|
88
|
+
}
|
|
84
89
|
};
|
|
85
90
|
await writeHandler(constants_1.HANDLER_FUNCTION_NAME, constants_1.HANDLER_FUNCTION_TITLE, false);
|
|
86
91
|
await writeHandler(constants_1.ODB_FUNCTION_NAME, constants_1.ODB_FUNCTION_TITLE, true);
|
|
@@ -199,16 +204,19 @@ const traceNPMPackage = async (packageName, publish) => {
|
|
|
199
204
|
}
|
|
200
205
|
};
|
|
201
206
|
exports.traceNPMPackage = traceNPMPackage;
|
|
202
|
-
const
|
|
207
|
+
const getCommonDependencies = async (publish) => {
|
|
203
208
|
const deps = await Promise.all([
|
|
204
209
|
traceRequiredServerFiles(publish),
|
|
205
210
|
traceNextServer(publish),
|
|
206
211
|
// used by our own bridge.js
|
|
207
212
|
(0, exports.traceNPMPackage)('follow-redirects', publish),
|
|
213
|
+
// using package.json because otherwise, we'd find some /dist/... path
|
|
214
|
+
(0, exports.traceNPMPackage)('@netlify/functions/package.json', publish),
|
|
215
|
+
(0, exports.traceNPMPackage)('is-promise', publish),
|
|
208
216
|
]);
|
|
209
217
|
return deps.flat(1);
|
|
210
218
|
};
|
|
211
|
-
exports.
|
|
219
|
+
exports.getCommonDependencies = getCommonDependencies;
|
|
212
220
|
const sum = (arr) => arr.reduce((v, current) => v + current, 0);
|
|
213
221
|
// TODO: cache results
|
|
214
222
|
const getBundleWeight = async (patterns) => {
|
|
@@ -224,8 +232,81 @@ const getBundleWeight = async (patterns) => {
|
|
|
224
232
|
}));
|
|
225
233
|
return sum(sizes.flat(1));
|
|
226
234
|
};
|
|
235
|
+
const changeExtension = (file, extension) => {
|
|
236
|
+
const base = (0, pathe_1.basename)(file, (0, pathe_1.extname)(file));
|
|
237
|
+
return (0, pathe_1.join)((0, pathe_1.dirname)(file), base + extension);
|
|
238
|
+
};
|
|
239
|
+
const getSSRDependencies = async (publish) => {
|
|
240
|
+
const prerenderManifest = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(publish, 'prerender-manifest.json'));
|
|
241
|
+
return [
|
|
242
|
+
...Object.entries(prerenderManifest.routes).flatMap(([route, ssgRoute]) => {
|
|
243
|
+
if (ssgRoute.initialRevalidateSeconds === false) {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
if (ssgRoute.dataRoute.endsWith('.rsc')) {
|
|
247
|
+
return [
|
|
248
|
+
(0, pathe_1.join)(publish, 'server', 'app', ssgRoute.dataRoute),
|
|
249
|
+
(0, pathe_1.join)(publish, 'server', 'app', changeExtension(ssgRoute.dataRoute, '.html')),
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
const trimmedPath = route === '/' ? 'index' : route.slice(1);
|
|
253
|
+
return [
|
|
254
|
+
(0, pathe_1.join)(publish, 'server', 'pages', `${trimmedPath}.html`),
|
|
255
|
+
(0, pathe_1.join)(publish, 'server', 'pages', `${trimmedPath}.json`),
|
|
256
|
+
];
|
|
257
|
+
}),
|
|
258
|
+
(0, pathe_1.join)(publish, '**', '*.html'),
|
|
259
|
+
(0, pathe_1.join)(publish, 'static-manifest.json'),
|
|
260
|
+
];
|
|
261
|
+
};
|
|
262
|
+
const getSSRLambdas = async (publish) => {
|
|
263
|
+
const commonDependencies = await (0, exports.getCommonDependencies)(publish);
|
|
264
|
+
const ssrRoutes = await getSSRRoutes(publish);
|
|
265
|
+
// TODO: for now, they're the same - but we should separate them
|
|
266
|
+
const nonOdbRoutes = ssrRoutes;
|
|
267
|
+
const odbRoutes = ssrRoutes;
|
|
268
|
+
const ssrDependencies = await getSSRDependencies(publish);
|
|
269
|
+
return [
|
|
270
|
+
{
|
|
271
|
+
functionName: constants_1.HANDLER_FUNCTION_NAME,
|
|
272
|
+
functionTitle: constants_1.HANDLER_FUNCTION_TITLE,
|
|
273
|
+
includedFiles: [
|
|
274
|
+
...commonDependencies,
|
|
275
|
+
...ssrDependencies,
|
|
276
|
+
...nonOdbRoutes.flatMap((route) => route.includedFiles),
|
|
277
|
+
],
|
|
278
|
+
routes: nonOdbRoutes,
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
functionName: constants_1.ODB_FUNCTION_NAME,
|
|
282
|
+
functionTitle: constants_1.ODB_FUNCTION_TITLE,
|
|
283
|
+
includedFiles: [...commonDependencies, ...ssrDependencies, ...odbRoutes.flatMap((route) => route.includedFiles)],
|
|
284
|
+
routes: odbRoutes,
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
};
|
|
288
|
+
exports.getSSRLambdas = getSSRLambdas;
|
|
289
|
+
const getSSRRoutes = async (publish) => {
|
|
290
|
+
const pageManifest = (await (0, fs_extra_1.readJSON)((0, pathe_1.join)(publish, 'server', 'pages-manifest.json')));
|
|
291
|
+
const pageManifestRoutes = Object.entries(pageManifest).filter(([page, compiled]) => !page.startsWith('/api/') && !compiled.endsWith('.html'));
|
|
292
|
+
const appPathsManifest = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(publish, 'server', 'app-paths-manifest.json')).catch(() => ({}));
|
|
293
|
+
const appRoutes = Object.entries(appPathsManifest);
|
|
294
|
+
const routes = [...pageManifestRoutes, ...appRoutes];
|
|
295
|
+
return await Promise.all(routes.map(async ([route, compiled]) => {
|
|
296
|
+
const functionName = (0, utils_1.getFunctionNameForPage)(route);
|
|
297
|
+
const compiledPath = (0, pathe_1.join)(publish, 'server', compiled);
|
|
298
|
+
const routeDependencies = await (0, files_1.getDependenciesOfFile)(compiledPath);
|
|
299
|
+
const includedFiles = [compiledPath, ...routeDependencies];
|
|
300
|
+
return {
|
|
301
|
+
functionName,
|
|
302
|
+
route,
|
|
303
|
+
compiled,
|
|
304
|
+
includedFiles,
|
|
305
|
+
};
|
|
306
|
+
}));
|
|
307
|
+
};
|
|
227
308
|
const getAPILambdas = async (publish, baseDir, pageExtensions) => {
|
|
228
|
-
const commonDependencies = await (0, exports.
|
|
309
|
+
const commonDependencies = await (0, exports.getCommonDependencies)(publish);
|
|
229
310
|
const threshold = constants_1.LAMBDA_WARNING_SIZE - (await getBundleWeight(commonDependencies));
|
|
230
311
|
const apiRoutes = await (0, exports.getApiRouteConfigs)(publish, baseDir, pageExtensions);
|
|
231
312
|
const packFunctions = async (routes, type) => {
|
package/lib/index.js
CHANGED
|
@@ -95,13 +95,15 @@ const plugin = {
|
|
|
95
95
|
const apiLambdas = (0, flags_1.splitApiRoutes)(featureFlags, publish)
|
|
96
96
|
? await (0, functions_1.getAPILambdas)(publish, appDir, pageExtensions)
|
|
97
97
|
: await (0, functions_1.getExtendedApiRouteConfigs)(publish, appDir, pageExtensions).then((extendedRoutes) => extendedRoutes.map(functions_1.packSingleFunction));
|
|
98
|
-
await (0, functions_1.
|
|
98
|
+
const ssrLambdas = (0, flags_1.bundleBasedOnNftFiles)(featureFlags) ? await (0, functions_1.getSSRLambdas)(publish) : [];
|
|
99
|
+
await (0, functions_1.generateFunctions)(constants, appDir, apiLambdas, ssrLambdas);
|
|
99
100
|
await (0, functions_1.generatePagesResolver)(constants);
|
|
100
101
|
await (0, config_1.configureHandlerFunctions)({
|
|
101
102
|
netlifyConfig,
|
|
102
103
|
ignore,
|
|
103
104
|
publish: (0, path_1.relative)(process.cwd(), publish),
|
|
104
105
|
apiLambdas,
|
|
106
|
+
ssrLambdas,
|
|
105
107
|
splitApiRoutes: (0, flags_1.splitApiRoutes)(featureFlags, publish),
|
|
106
108
|
});
|
|
107
109
|
await (0, files_1.movePublicFiles)({ appDir, outdir, publish, basePath });
|
|
@@ -148,6 +148,8 @@ const getHandler = ({ isODB = false, publishDir = '../../../.next', appDir = '..
|
|
|
148
148
|
throw new Error('Could not find Next.js server')
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
process.env.NODE_ENV = 'production';
|
|
152
|
+
|
|
151
153
|
const { Server } = require("http");
|
|
152
154
|
const { promises } = require("fs");
|
|
153
155
|
// We copy the file here rather than requiring from the node module
|
|
@@ -169,6 +169,12 @@ const normalizePath = (event) => {
|
|
|
169
169
|
return originalPath;
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
+
if (event.headers['x-original-path']) {
|
|
173
|
+
if (event.headers['x-next-debug-logging']) {
|
|
174
|
+
console.log('Original path:', event.headers['x-original-path']);
|
|
175
|
+
}
|
|
176
|
+
return event.headers['x-original-path'];
|
|
177
|
+
}
|
|
172
178
|
// Ensure that paths are encoded - but don't double-encode them
|
|
173
179
|
return new URL(event.rawUrl).pathname;
|
|
174
180
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable
|
|
2
|
+
/* eslint-disable no-underscore-dangle, @typescript-eslint/no-explicit-any */
|
|
3
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
@@ -11,86 +11,95 @@ const module_1 = __importDefault(require("module"));
|
|
|
11
11
|
const resolveFilename = module_1.default._resolveFilename;
|
|
12
12
|
const requireHooks = new Map();
|
|
13
13
|
const overrideRequireHooks = (config) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
setRequireHooks(config);
|
|
15
|
+
resolveRequireHooks();
|
|
16
|
+
};
|
|
17
|
+
exports.overrideRequireHooks = overrideRequireHooks;
|
|
18
|
+
const setRequireHooks = (config) => {
|
|
18
19
|
requireHooks.set('default', new Map([
|
|
19
|
-
['react',
|
|
20
|
-
['react/jsx-runtime',
|
|
20
|
+
['react', `react`],
|
|
21
|
+
['react/jsx-runtime', `react/jsx-runtime`],
|
|
21
22
|
]));
|
|
22
23
|
if (config.experimental.appDir) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'react-server-dom-webpack/client',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
'react-server-dom-webpack/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
require.resolve(`next/dist/compiled/react-server-dom-webpack-experimental/client.edge`, opts),
|
|
69
|
-
],
|
|
70
|
-
[
|
|
71
|
-
'react-server-dom-webpack/server.edge',
|
|
72
|
-
require.resolve(`next/dist/compiled/react-server-dom-webpack-experimental/server.edge`, opts),
|
|
73
|
-
],
|
|
74
|
-
[
|
|
75
|
-
'react-server-dom-webpack/server.node',
|
|
76
|
-
require.resolve(`next/dist/compiled/react-server-dom-webpack-experimental/server.node`, opts),
|
|
77
|
-
],
|
|
78
|
-
['styled-jsx', require.resolve('styled-jsx', opts)],
|
|
79
|
-
['styled-jsx/style', require.resolve('styled-jsx/style', opts)],
|
|
80
|
-
]));
|
|
24
|
+
if (config.experimental.serverActions) {
|
|
25
|
+
requireHooks.set('experimental', new Map([
|
|
26
|
+
['react', `next/dist/compiled/react-experimental`],
|
|
27
|
+
['react/jsx-runtime', `next/dist/compiled/react-experimental/jsx-runtime`],
|
|
28
|
+
['react/jsx-dev-runtime', `next/dist/compiled/react-experimental/jsx-dev-runtime`],
|
|
29
|
+
['react-dom', `next/dist/compiled/react-dom-experimental/server-rendering-stub`],
|
|
30
|
+
['react-dom/client', `next/dist/compiled/react-dom-experimental/client`],
|
|
31
|
+
['react-dom/server', `next/dist/compiled/react-dom-experimental/server`],
|
|
32
|
+
['react-dom/server.browser', `next/dist/compiled/react-dom-experimental/server.browser`],
|
|
33
|
+
['react-dom/server.edge', `next/dist/compiled/react-dom-experimental/server.edge`],
|
|
34
|
+
['react-server-dom-webpack/client', `next/dist/compiled/react-server-dom-webpack-experimental/client`],
|
|
35
|
+
[
|
|
36
|
+
'react-server-dom-webpack/client.edge',
|
|
37
|
+
`next/dist/compiled/react-server-dom-webpack-experimental/client.edge`,
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
'react-server-dom-webpack/server.edge',
|
|
41
|
+
`next/dist/compiled/react-server-dom-webpack-experimental/server.edge`,
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
'react-server-dom-webpack/server.node',
|
|
45
|
+
`next/dist/compiled/react-server-dom-webpack-experimental/server.node`,
|
|
46
|
+
],
|
|
47
|
+
['styled-jsx', 'styled-jsx'],
|
|
48
|
+
['styled-jsx/style', 'styled-jsx/style'],
|
|
49
|
+
]));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
requireHooks.set('next', new Map([
|
|
53
|
+
['react', `next/dist/compiled/react`],
|
|
54
|
+
['react/jsx-runtime', `next/dist/compiled/react/jsx-runtime`],
|
|
55
|
+
['react/jsx-dev-runtime', `next/dist/compiled/react/jsx-dev-runtime`],
|
|
56
|
+
['react-dom', `next/dist/compiled/react-dom/server-rendering-stub`],
|
|
57
|
+
['react-dom/client', `next/dist/compiled/react-dom/client`],
|
|
58
|
+
['react-dom/server', `next/dist/compiled/react-dom/server`],
|
|
59
|
+
['react-dom/server.browser', `next/dist/compiled/react-dom/server.browser`],
|
|
60
|
+
['react-dom/server.edge', `next/dist/compiled/react-dom/server.edge`],
|
|
61
|
+
['react-server-dom-webpack/client', `next/dist/compiled/react-server-dom-webpack/client`],
|
|
62
|
+
['react-server-dom-webpack/client.edge', `next/dist/compiled/react-server-dom-webpack/client.edge`],
|
|
63
|
+
['react-server-dom-webpack/server.edge', `next/dist/compiled/react-server-dom-webpack/server.edge`],
|
|
64
|
+
['react-server-dom-webpack/server.node', `next/dist/compiled/react-server-dom-webpack/server.node`],
|
|
65
|
+
['styled-jsx', 'styled-jsx'],
|
|
66
|
+
['styled-jsx/style', 'styled-jsx/style'],
|
|
67
|
+
]));
|
|
68
|
+
}
|
|
81
69
|
}
|
|
82
70
|
};
|
|
83
|
-
|
|
71
|
+
const resolveRequireHooks = () => {
|
|
72
|
+
// we may have changed the working directory in the handler
|
|
73
|
+
const opts = { paths: [process.cwd()] };
|
|
74
|
+
// resolve require hooks with module paths
|
|
75
|
+
requireHooks.forEach((mode) => {
|
|
76
|
+
mode.forEach((path, hook) => {
|
|
77
|
+
try {
|
|
78
|
+
const resolvedPath = require.resolve(path, opts);
|
|
79
|
+
mode.set(hook, resolvedPath);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error.code === 'MODULE_NOT_FOUND') {
|
|
83
|
+
// module not present (older version of Next.js)
|
|
84
|
+
mode.delete(hook);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
};
|
|
84
93
|
const applyRequireHooks = () => {
|
|
85
94
|
// eslint-disable-next-line max-params, func-names
|
|
86
95
|
;
|
|
87
96
|
module_1.default._resolveFilename = function (originalResolveFilename, hooks, request, parent, isMain, options) {
|
|
88
|
-
var _a, _b
|
|
89
|
-
const reactMode =
|
|
90
|
-
const resolvedRequest = (
|
|
97
|
+
var _a, _b;
|
|
98
|
+
const reactMode = process.env.__NEXT_PRIVATE_PREBUNDLED_REACT || 'default';
|
|
99
|
+
const resolvedRequest = (_b = (_a = hooks.get(reactMode)) === null || _a === void 0 ? void 0 : _a.get(request)) !== null && _b !== void 0 ? _b : request;
|
|
91
100
|
return originalResolveFilename.call(module_1.default, resolvedRequest, parent, isMain, options);
|
|
92
101
|
// We use `bind` here to avoid referencing outside variables to create potential memory leaks.
|
|
93
102
|
}.bind(null, resolveFilename, requireHooks);
|
|
94
103
|
};
|
|
95
104
|
exports.applyRequireHooks = applyRequireHooks;
|
|
96
|
-
/* eslint-enable
|
|
105
|
+
/* eslint-enable no-underscore-dangle, @typescript-eslint/no-explicit-any */
|
package/lib/templates/server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNetlifyNextServer = void 0;
|
|
4
|
+
// eslint-disable-next-line n/no-deprecated-api -- this is what Next.js uses as well
|
|
5
|
+
const url_1 = require("url");
|
|
4
6
|
const handlerUtils_1 = require("./handlerUtils");
|
|
5
7
|
const getNetlifyNextServer = (NextServer) => {
|
|
6
8
|
class NetlifyNextServer extends NextServer {
|
|
@@ -18,7 +20,10 @@ const getNetlifyNextServer = (NextServer) => {
|
|
|
18
20
|
getRequestHandler() {
|
|
19
21
|
const handler = super.getRequestHandler();
|
|
20
22
|
return async (req, res, parsedUrl) => {
|
|
21
|
-
var _a;
|
|
23
|
+
var _a, _b;
|
|
24
|
+
if (!parsedUrl && typeof ((_a = req === null || req === void 0 ? void 0 : req.headers) === null || _a === void 0 ? void 0 : _a['x-middleware-rewrite']) === 'string') {
|
|
25
|
+
parsedUrl = (0, url_1.parse)(req.headers['x-middleware-rewrite'], true);
|
|
26
|
+
}
|
|
22
27
|
// preserve the URL before Next.js mutates it for i18n
|
|
23
28
|
const { url, headers } = req;
|
|
24
29
|
// conditionally use the prebundled React module
|
|
@@ -37,7 +42,7 @@ const getNetlifyNextServer = (NextServer) => {
|
|
|
37
42
|
// for our ODBs and middleware is disabled at the origin
|
|
38
43
|
// but ignore in preview mode (prerender_bypass is set to true in preview mode)
|
|
39
44
|
// because otherwise revalidate will override preview mode
|
|
40
|
-
if (!((
|
|
45
|
+
if (!((_b = headers.cookie) === null || _b === void 0 ? void 0 : _b.includes('__prerender_bypass'))) {
|
|
41
46
|
// this header controls whether Next.js will revalidate the page
|
|
42
47
|
// and needs to be set to the preview mode id to enable it
|
|
43
48
|
headers['x-prerender-revalidate'] = this.renderOpts.previewProps.previewModeId;
|
|
@@ -51,7 +56,7 @@ const getNetlifyNextServer = (NextServer) => {
|
|
|
51
56
|
const routesManifest = (_a = this.getRoutesManifest) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
52
57
|
const appPathsManifest = (_b = this.getAppPathsManifest) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
53
58
|
const routes = routesManifest && [...routesManifest.staticRoutes, ...routesManifest.dynamicRoutes];
|
|
54
|
-
const matchedRoute = routes === null || routes === void 0 ? void 0 : routes.find((route) => new RegExp(route.regex).test(path));
|
|
59
|
+
const matchedRoute = routes === null || routes === void 0 ? void 0 : routes.find((route) => new RegExp(route.regex).test(path.split('?')[0]));
|
|
55
60
|
const isAppRoute = appPathsManifest && matchedRoute ? appPathsManifest[(0, handlerUtils_1.joinPaths)(matchedRoute.page, 'page')] : false;
|
|
56
61
|
if (isAppRoute) {
|
|
57
62
|
// app routes should use prebundled React
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/plugin-nextjs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.39.0",
|
|
4
4
|
"description": "Run Next.js seamlessly on Netlify",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node-stream-zip": "^1.15.0",
|
|
29
29
|
"outdent": "^0.8.0",
|
|
30
30
|
"p-limit": "^3.1.0",
|
|
31
|
-
"pathe": "^0.
|
|
31
|
+
"pathe": "^0.3.0",
|
|
32
32
|
"pretty-bytes": "^5.6.0",
|
|
33
33
|
"regexp-tree": "^0.1.24",
|
|
34
34
|
"semver": "^7.3.5",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@delucis/if-env": "^1.1.2",
|
|
40
|
-
"@netlify/build": "^29.
|
|
40
|
+
"@netlify/build": "^29.15.0",
|
|
41
41
|
"@types/fs-extra": "^9.0.13",
|
|
42
42
|
"@types/jest": "^27.4.1",
|
|
43
43
|
"@types/merge-stream": "^1.1.2",
|
|
@@ -270,6 +270,9 @@ export const buildResponse = async ({
|
|
|
270
270
|
}
|
|
271
271
|
res.headers.set('x-middleware-rewrite', relativeUrl)
|
|
272
272
|
|
|
273
|
+
request.headers.set('x-original-path', new URL(request.url, `http://n`).pathname)
|
|
274
|
+
request.headers.set('x-middleware-rewrite', rewrite)
|
|
275
|
+
|
|
273
276
|
return addMiddlewareHeaders(context.rewrite(rewrite), res)
|
|
274
277
|
}
|
|
275
278
|
|