@netlify/plugin-nextjs 4.2.0 → 4.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/lib/helpers/cache.js +3 -3
- package/lib/helpers/config.js +3 -3
- package/lib/helpers/files.js +90 -80
- package/lib/helpers/functions.js +18 -15
- package/lib/helpers/redirects.js +132 -39
- package/lib/helpers/utils.js +26 -18
- package/lib/helpers/verification.js +27 -21
- package/lib/index.js +27 -26
- package/lib/templates/getHandler.js +59 -46
- package/lib/templates/getPageResolver.js +4 -4
- package/lib/templates/handlerUtils.js +21 -8
- package/lib/templates/ipx.js +1 -1
- package/package.json +10 -15
package/README.md
CHANGED
|
@@ -31,6 +31,12 @@ npm install -D @netlify/plugin-nextjs
|
|
|
31
31
|
package = "@netlify/plugin-nextjs"
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Deploying
|
|
35
|
+
|
|
36
|
+
If you build on Netlify, this plugin will work with no additional configuration. However if you are building and
|
|
37
|
+
deploying locally using the Netlify CLI, you must deploy using `netlify deploy --build`. Running the
|
|
38
|
+
build and deploy commands separately will not work, because the plugin will not generate the required configuration.
|
|
39
|
+
|
|
34
40
|
## Migrating from an older version of the plugin
|
|
35
41
|
|
|
36
42
|
You can manually upgrade from the previous version of the plugin by running the following command:
|
|
@@ -58,7 +64,8 @@ it.
|
|
|
58
64
|
|
|
59
65
|
If you currently use redirects or rewrites on your site, see
|
|
60
66
|
[the Rewrites and Redirects guide](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/redirects-rewrites.md)
|
|
61
|
-
for information on changes to how they are handled in this version.
|
|
67
|
+
for information on changes to how they are handled in this version. In particular, note that `_redirects` and `_headers`
|
|
68
|
+
files must be placed in `public`, not in the root of the site.
|
|
62
69
|
|
|
63
70
|
If you want to use Next 12's beta Middleware feature, this will mostly work as expected but please
|
|
64
71
|
[read the docs on some caveats and workarounds](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/middleware.md)
|
|
@@ -85,6 +92,12 @@ you can remove it. Alternatively you can
|
|
|
85
92
|
support. See [`demos/next-export`](https://github.com/netlify/netlify-plugin-nextjs/tree/main/demos/next-export) for an
|
|
86
93
|
example.
|
|
87
94
|
|
|
95
|
+
## Asset optimization
|
|
96
|
+
|
|
97
|
+
Netlify [asset optimization](https://docs.netlify.com/site-deploys/post-processing/) should not be used with Next.js
|
|
98
|
+
sites. Assets are already optimized by Next.js at build time, and doing further optimization can break your site. Ensure
|
|
99
|
+
that it is not enabled at **Site settings > Build & deploy > Post processing > Asset optimization**.
|
|
100
|
+
|
|
88
101
|
## Generated functions
|
|
89
102
|
|
|
90
103
|
This plugin works by generating three Netlify functions that handle requests that haven't been pre-rendered. These are
|
package/lib/helpers/cache.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.saveCache = exports.restoreCache = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const restoreCache = async ({ cache, publish }) => {
|
|
6
|
-
const cacheDir = path_1.join(publish, 'cache');
|
|
6
|
+
const cacheDir = (0, path_1.join)(publish, 'cache');
|
|
7
7
|
if (await cache.restore(cacheDir)) {
|
|
8
8
|
console.log('Next.js cache restored.');
|
|
9
9
|
}
|
|
@@ -13,8 +13,8 @@ const restoreCache = async ({ cache, publish }) => {
|
|
|
13
13
|
};
|
|
14
14
|
exports.restoreCache = restoreCache;
|
|
15
15
|
const saveCache = async ({ cache, publish }) => {
|
|
16
|
-
const cacheDir = path_1.join(publish, 'cache');
|
|
17
|
-
const buildManifest = path_1.join(publish, 'build-manifest.json');
|
|
16
|
+
const cacheDir = (0, path_1.join)(publish, 'cache');
|
|
17
|
+
const buildManifest = (0, path_1.join)(publish, 'build-manifest.json');
|
|
18
18
|
if (await cache.save(cacheDir, { digests: [buildManifest] })) {
|
|
19
19
|
console.log('Next.js cache saved.');
|
|
20
20
|
}
|
package/lib/helpers/config.js
CHANGED
|
@@ -13,7 +13,7 @@ const defaultFailBuild = (message, { error }) => {
|
|
|
13
13
|
};
|
|
14
14
|
const getNextConfig = async function getNextConfig({ publish, failBuild = defaultFailBuild, }) {
|
|
15
15
|
try {
|
|
16
|
-
const { config, appDir, ignore } = await fs_extra_1.readJSON(pathe_1.join(publish, 'required-server-files.json'));
|
|
16
|
+
const { config, appDir, ignore } = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(publish, 'required-server-files.json'));
|
|
17
17
|
if (!config) {
|
|
18
18
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
19
19
|
// @ts-ignore
|
|
@@ -28,7 +28,7 @@ const getNextConfig = async function getNextConfig({ publish, failBuild = defaul
|
|
|
28
28
|
exports.getNextConfig = getNextConfig;
|
|
29
29
|
const resolveModuleRoot = (moduleName) => {
|
|
30
30
|
try {
|
|
31
|
-
return pathe_1.dirname(pathe_1.relative(process.cwd(), require.resolve(`${moduleName}/package.json`, { paths: [process.cwd()] })));
|
|
31
|
+
return (0, pathe_1.dirname)((0, pathe_1.relative)(process.cwd(), require.resolve(`${moduleName}/package.json`, { paths: [process.cwd()] })));
|
|
32
32
|
}
|
|
33
33
|
catch {
|
|
34
34
|
return null;
|
|
@@ -45,7 +45,7 @@ const configureHandlerFunctions = ({ netlifyConfig, publish, ignore = [] }) => {
|
|
|
45
45
|
(_a = netlifyConfig.functions)[functionName] || (_a[functionName] = { included_files: [], external_node_modules: [] });
|
|
46
46
|
netlifyConfig.functions[functionName].node_bundler = 'nft';
|
|
47
47
|
(_b = netlifyConfig.functions[functionName]).included_files || (_b.included_files = []);
|
|
48
|
-
netlifyConfig.functions[functionName].included_files.push('.env', '.env.local', '.env.production', '.env.production.local', `${publish}/server/**`, `${publish}/serverless/**`, `${publish}/*.json`, `${publish}/BUILD_ID`, `${publish}/static/chunks/webpack-middleware*.js`, `!${publish}/server/**/*.js.nft.json`, ...ignore.map((path) => `!${slash_1.default(path)}`));
|
|
48
|
+
netlifyConfig.functions[functionName].included_files.push('.env', '.env.local', '.env.production', '.env.production.local', `${publish}/server/**`, `${publish}/serverless/**`, `${publish}/*.json`, `${publish}/BUILD_ID`, `${publish}/static/chunks/webpack-middleware*.js`, `!${publish}/server/**/*.js.nft.json`, ...ignore.map((path) => `!${(0, slash_1.default)(path)}`));
|
|
49
49
|
const nextRoot = resolveModuleRoot('next');
|
|
50
50
|
if (nextRoot) {
|
|
51
51
|
netlifyConfig.functions[functionName].included_files.push(`!${nextRoot}/dist/server/lib/squoosh/**/*.wasm`, `!${nextRoot}/dist/next-server/server/lib/squoosh/**/*.wasm`, `!${nextRoot}/dist/compiled/webpack/bundle4.js`, `!${nextRoot}/dist/compiled/webpack/bundle5.js`, `!${nextRoot}/dist/compiled/terser/bundle.min.js`);
|
package/lib/helpers/files.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.movePublicFiles = exports.unpatchNextFiles = exports.patchNextFiles = exports.moveStaticPages = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
|
|
6
|
+
exports.movePublicFiles = exports.unpatchNextFiles = exports.patchNextFiles = exports.moveStaticPages = exports.getMiddleware = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
|
|
7
7
|
/* eslint-disable max-lines */
|
|
8
8
|
const os_1 = require("os");
|
|
9
9
|
const chalk_1 = require("chalk");
|
|
@@ -14,6 +14,7 @@ const p_limit_1 = __importDefault(require("p-limit"));
|
|
|
14
14
|
const pathe_1 = require("pathe");
|
|
15
15
|
const slash_1 = __importDefault(require("slash"));
|
|
16
16
|
const constants_1 = require("../constants");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
17
18
|
const TEST_ROUTE = /(|\/)\[[^/]+?](\/|\.html|$)/;
|
|
18
19
|
const isDynamicRoute = (route) => TEST_ROUTE.test(route);
|
|
19
20
|
exports.isDynamicRoute = isDynamicRoute;
|
|
@@ -43,33 +44,37 @@ const matchesRedirect = (file, redirects) => {
|
|
|
43
44
|
exports.matchesRedirect = matchesRedirect;
|
|
44
45
|
const matchesRewrite = (file, rewrites) => {
|
|
45
46
|
if (Array.isArray(rewrites)) {
|
|
46
|
-
return exports.matchesRedirect(file, rewrites);
|
|
47
|
+
return (0, exports.matchesRedirect)(file, rewrites);
|
|
47
48
|
}
|
|
48
49
|
if (!Array.isArray(rewrites === null || rewrites === void 0 ? void 0 : rewrites.beforeFiles)) {
|
|
49
50
|
return false;
|
|
50
51
|
}
|
|
51
|
-
return exports.matchesRedirect(file, rewrites.beforeFiles);
|
|
52
|
+
return (0, exports.matchesRedirect)(file, rewrites.beforeFiles);
|
|
52
53
|
};
|
|
53
54
|
exports.matchesRewrite = matchesRewrite;
|
|
55
|
+
const getMiddleware = async (publish) => {
|
|
56
|
+
var _a;
|
|
57
|
+
const manifestPath = (0, pathe_1.join)(publish, 'server', 'middleware-manifest.json');
|
|
58
|
+
if ((0, fs_extra_1.existsSync)(manifestPath)) {
|
|
59
|
+
const manifest = await (0, fs_extra_1.readJson)(manifestPath, { throws: false });
|
|
60
|
+
return (_a = manifest === null || manifest === void 0 ? void 0 : manifest.sortedMiddleware) !== null && _a !== void 0 ? _a : [];
|
|
61
|
+
}
|
|
62
|
+
return [];
|
|
63
|
+
};
|
|
64
|
+
exports.getMiddleware = getMiddleware;
|
|
54
65
|
// eslint-disable-next-line max-lines-per-function
|
|
55
66
|
const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
56
67
|
console.log('Moving static page files to serve from CDN...');
|
|
57
|
-
const outputDir = pathe_1.join(netlifyConfig.build.publish, target === 'server' ? 'server' : 'serverless');
|
|
58
|
-
const root = pathe_1.join(outputDir, 'pages');
|
|
59
|
-
const buildId = fs_extra_1.readFileSync(pathe_1.join(netlifyConfig.build.publish, 'BUILD_ID'), 'utf8').trim();
|
|
60
|
-
const dataDir = pathe_1.join('_next', 'data', buildId);
|
|
61
|
-
await fs_extra_1.ensureDir(dataDir);
|
|
68
|
+
const outputDir = (0, pathe_1.join)(netlifyConfig.build.publish, target === 'server' ? 'server' : 'serverless');
|
|
69
|
+
const root = (0, pathe_1.join)(outputDir, 'pages');
|
|
70
|
+
const buildId = (0, fs_extra_1.readFileSync)((0, pathe_1.join)(netlifyConfig.build.publish, 'BUILD_ID'), 'utf8').trim();
|
|
71
|
+
const dataDir = (0, pathe_1.join)('_next', 'data', buildId);
|
|
72
|
+
await (0, fs_extra_1.ensureDir)(dataDir);
|
|
62
73
|
// Load the middleware manifest so we can check if a file matches it before moving
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (manifest === null || manifest === void 0 ? void 0 : manifest.middleware) {
|
|
68
|
-
middleware = Object.keys(manifest.middleware).map((path) => path.slice(1));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const prerenderManifest = await fs_extra_1.readJson(pathe_1.join(netlifyConfig.build.publish, 'prerender-manifest.json'));
|
|
72
|
-
const { redirects, rewrites } = await fs_extra_1.readJson(pathe_1.join(netlifyConfig.build.publish, 'routes-manifest.json'));
|
|
74
|
+
const middlewarePaths = await (0, exports.getMiddleware)(netlifyConfig.build.publish);
|
|
75
|
+
const middleware = middlewarePaths.map((path) => path.slice(1));
|
|
76
|
+
const prerenderManifest = await (0, fs_extra_1.readJson)((0, pathe_1.join)(netlifyConfig.build.publish, 'prerender-manifest.json'));
|
|
77
|
+
const { redirects, rewrites } = await (0, fs_extra_1.readJson)((0, pathe_1.join)(netlifyConfig.build.publish, 'routes-manifest.json'));
|
|
73
78
|
const isrFiles = new Set();
|
|
74
79
|
const shortRevalidateRoutes = [];
|
|
75
80
|
Object.entries(prerenderManifest.routes).forEach(([route, { initialRevalidateSeconds }]) => {
|
|
@@ -87,20 +92,20 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
87
92
|
const filesManifest = {};
|
|
88
93
|
const moveFile = async (file) => {
|
|
89
94
|
const isData = file.endsWith('.json');
|
|
90
|
-
const source = pathe_1.join(root, file);
|
|
91
|
-
const targetFile = isData ? pathe_1.join(dataDir, file) : file;
|
|
95
|
+
const source = (0, pathe_1.join)(root, file);
|
|
96
|
+
const targetFile = isData ? (0, pathe_1.join)(dataDir, file) : file;
|
|
92
97
|
files.push(file);
|
|
93
98
|
filesManifest[file] = targetFile;
|
|
94
|
-
const dest = pathe_1.join(netlifyConfig.build.publish, targetFile);
|
|
99
|
+
const dest = (0, pathe_1.join)(netlifyConfig.build.publish, targetFile);
|
|
95
100
|
try {
|
|
96
|
-
await fs_extra_1.move(source, dest);
|
|
101
|
+
await (0, fs_extra_1.move)(source, dest);
|
|
97
102
|
}
|
|
98
103
|
catch (error) {
|
|
99
104
|
console.warn('Error moving file', source, error);
|
|
100
105
|
}
|
|
101
106
|
};
|
|
102
107
|
// Move all static files, except error documents and nft manifests
|
|
103
|
-
const pages = await globby_1.default(['**/*.{html,json}', '!**/(500|404|*.js.nft).{html,json}'], {
|
|
108
|
+
const pages = await (0, globby_1.default)(['**/*.{html,json}', '!**/(500|404|*.js.nft).{html,json}'], {
|
|
104
109
|
cwd: root,
|
|
105
110
|
dot: true,
|
|
106
111
|
});
|
|
@@ -109,27 +114,27 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
109
114
|
const matchedRedirects = new Set();
|
|
110
115
|
const matchedRewrites = new Set();
|
|
111
116
|
// Limit concurrent file moves to number of cpus or 2 if there is only 1
|
|
112
|
-
const limit = p_limit_1.default(Math.max(2, os_1.cpus().length));
|
|
117
|
+
const limit = (0, p_limit_1.default)(Math.max(2, (0, os_1.cpus)().length));
|
|
113
118
|
const promises = pages.map((rawPath) => {
|
|
114
|
-
const filePath = slash_1.default(rawPath);
|
|
119
|
+
const filePath = (0, slash_1.default)(rawPath);
|
|
115
120
|
// Don't move ISR files, as they're used for the first request
|
|
116
121
|
if (isrFiles.has(filePath)) {
|
|
117
122
|
return;
|
|
118
123
|
}
|
|
119
|
-
if (exports.isDynamicRoute(filePath)) {
|
|
124
|
+
if ((0, exports.isDynamicRoute)(filePath)) {
|
|
120
125
|
return;
|
|
121
126
|
}
|
|
122
|
-
if (exports.matchesRedirect(filePath, redirects)) {
|
|
127
|
+
if ((0, exports.matchesRedirect)(filePath, redirects)) {
|
|
123
128
|
matchedRedirects.add(filePath);
|
|
124
129
|
return;
|
|
125
130
|
}
|
|
126
|
-
if (exports.matchesRewrite(filePath, rewrites)) {
|
|
131
|
+
if ((0, exports.matchesRewrite)(filePath, rewrites)) {
|
|
127
132
|
matchedRewrites.add(filePath);
|
|
128
133
|
return;
|
|
129
134
|
}
|
|
130
135
|
// Middleware matches against the unlocalised path
|
|
131
|
-
const unlocalizedPath = exports.stripLocale(rawPath, i18n === null || i18n === void 0 ? void 0 : i18n.locales);
|
|
132
|
-
const middlewarePath = exports.matchMiddleware(middleware, unlocalizedPath);
|
|
136
|
+
const unlocalizedPath = (0, exports.stripLocale)(rawPath, i18n === null || i18n === void 0 ? void 0 : i18n.locales);
|
|
137
|
+
const middlewarePath = (0, exports.matchMiddleware)(middleware, unlocalizedPath);
|
|
133
138
|
// If a file matches middleware it can't be offloaded to the CDN, and needs to stay at the origin to be served by next/server
|
|
134
139
|
if (middlewarePath) {
|
|
135
140
|
matchingMiddleware.add(middlewarePath);
|
|
@@ -141,67 +146,67 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
141
146
|
await Promise.all(promises);
|
|
142
147
|
console.log(`Moved ${files.length} files`);
|
|
143
148
|
if (matchedPages.size !== 0) {
|
|
144
|
-
console.log(chalk_1.yellowBright(outdent_1.outdent `
|
|
149
|
+
console.log((0, chalk_1.yellowBright)((0, outdent_1.outdent) `
|
|
145
150
|
Skipped moving ${matchedPages.size} ${matchedPages.size === 1 ? 'file because it matches' : 'files because they match'} middleware, so cannot be deployed to the CDN and will be served from the origin instead.
|
|
146
151
|
This is fine, but we're letting you know because it may not be what you expect.
|
|
147
152
|
`));
|
|
148
|
-
console.log(outdent_1.outdent `
|
|
153
|
+
console.log((0, outdent_1.outdent) `
|
|
149
154
|
The following middleware matched statically-rendered pages:
|
|
150
155
|
|
|
151
|
-
${chalk_1.yellowBright([...matchingMiddleware].map((mid) => `- /${mid}/_middleware`).join('\n'))}
|
|
156
|
+
${(0, chalk_1.yellowBright)([...matchingMiddleware].map((mid) => `- /${mid}/_middleware`).join('\n'))}
|
|
152
157
|
${constants_1.DIVIDER}
|
|
153
158
|
`);
|
|
154
159
|
// There could potentially be thousands of matching pages, so we don't want to spam the console with this
|
|
155
160
|
if (matchedPages.size < 50) {
|
|
156
|
-
console.log(outdent_1.outdent `
|
|
161
|
+
console.log((0, outdent_1.outdent) `
|
|
157
162
|
The following files matched middleware and were not moved to the CDN:
|
|
158
163
|
|
|
159
|
-
${chalk_1.yellowBright([...matchedPages].map((mid) => `- ${mid}`).join('\n'))}
|
|
164
|
+
${(0, chalk_1.yellowBright)([...matchedPages].map((mid) => `- ${mid}`).join('\n'))}
|
|
160
165
|
${constants_1.DIVIDER}
|
|
161
166
|
`);
|
|
162
167
|
}
|
|
163
168
|
}
|
|
164
169
|
if (matchedRedirects.size !== 0 || matchedRewrites.size !== 0) {
|
|
165
|
-
console.log(chalk_1.yellowBright(outdent_1.outdent `
|
|
170
|
+
console.log((0, chalk_1.yellowBright)((0, outdent_1.outdent) `
|
|
166
171
|
Skipped moving ${matchedRedirects.size + matchedRewrites.size} files because they match redirects or beforeFiles rewrites, so cannot be deployed to the CDN and will be served from the origin instead.
|
|
167
172
|
`));
|
|
168
173
|
if (matchedRedirects.size < 50 && matchedRedirects.size !== 0) {
|
|
169
|
-
console.log(outdent_1.outdent `
|
|
174
|
+
console.log((0, outdent_1.outdent) `
|
|
170
175
|
The following files matched redirects and were not moved to the CDN:
|
|
171
176
|
|
|
172
|
-
${chalk_1.yellowBright([...matchedRedirects].map((mid) => `- ${mid}`).join('\n'))}
|
|
177
|
+
${(0, chalk_1.yellowBright)([...matchedRedirects].map((mid) => `- ${mid}`).join('\n'))}
|
|
173
178
|
${constants_1.DIVIDER}
|
|
174
179
|
`);
|
|
175
180
|
}
|
|
176
181
|
if (matchedRewrites.size < 50 && matchedRewrites.size !== 0) {
|
|
177
|
-
console.log(outdent_1.outdent `
|
|
182
|
+
console.log((0, outdent_1.outdent) `
|
|
178
183
|
The following files matched beforeFiles rewrites and were not moved to the CDN:
|
|
179
184
|
|
|
180
|
-
${chalk_1.yellowBright([...matchedRewrites].map((mid) => `- ${mid}`).join('\n'))}
|
|
185
|
+
${(0, chalk_1.yellowBright)([...matchedRewrites].map((mid) => `- ${mid}`).join('\n'))}
|
|
181
186
|
${constants_1.DIVIDER}
|
|
182
187
|
`);
|
|
183
188
|
}
|
|
184
189
|
}
|
|
185
190
|
// Write the manifest for use in the serverless functions
|
|
186
|
-
await fs_extra_1.writeJson(pathe_1.join(netlifyConfig.build.publish, 'static-manifest.json'), Object.entries(filesManifest));
|
|
191
|
+
await (0, fs_extra_1.writeJson)((0, pathe_1.join)(netlifyConfig.build.publish, 'static-manifest.json'), Object.entries(filesManifest));
|
|
187
192
|
if (i18n === null || i18n === void 0 ? void 0 : i18n.defaultLocale) {
|
|
188
193
|
// Copy the default locale into the root
|
|
189
|
-
const defaultLocaleDir = pathe_1.join(netlifyConfig.build.publish, i18n.defaultLocale);
|
|
190
|
-
if (fs_extra_1.existsSync(defaultLocaleDir)) {
|
|
191
|
-
await fs_extra_1.copy(defaultLocaleDir, `${netlifyConfig.build.publish}/`);
|
|
194
|
+
const defaultLocaleDir = (0, pathe_1.join)(netlifyConfig.build.publish, i18n.defaultLocale);
|
|
195
|
+
if ((0, fs_extra_1.existsSync)(defaultLocaleDir)) {
|
|
196
|
+
await (0, fs_extra_1.copy)(defaultLocaleDir, `${netlifyConfig.build.publish}/`);
|
|
192
197
|
}
|
|
193
|
-
const defaultLocaleIndex = pathe_1.join(netlifyConfig.build.publish, `${i18n.defaultLocale}.html`);
|
|
194
|
-
const indexHtml = pathe_1.join(netlifyConfig.build.publish, 'index.html');
|
|
195
|
-
if (fs_extra_1.existsSync(defaultLocaleIndex) && !fs_extra_1.existsSync(indexHtml)) {
|
|
198
|
+
const defaultLocaleIndex = (0, pathe_1.join)(netlifyConfig.build.publish, `${i18n.defaultLocale}.html`);
|
|
199
|
+
const indexHtml = (0, pathe_1.join)(netlifyConfig.build.publish, 'index.html');
|
|
200
|
+
if ((0, fs_extra_1.existsSync)(defaultLocaleIndex) && !(0, fs_extra_1.existsSync)(indexHtml)) {
|
|
196
201
|
try {
|
|
197
|
-
await fs_extra_1.copy(defaultLocaleIndex, indexHtml, { overwrite: false });
|
|
198
|
-
await fs_extra_1.copy(pathe_1.join(netlifyConfig.build.publish, `${i18n.defaultLocale}.json`), pathe_1.join(netlifyConfig.build.publish, 'index.json'), { overwrite: false });
|
|
202
|
+
await (0, fs_extra_1.copy)(defaultLocaleIndex, indexHtml, { overwrite: false });
|
|
203
|
+
await (0, fs_extra_1.copy)((0, pathe_1.join)(netlifyConfig.build.publish, `${i18n.defaultLocale}.json`), (0, pathe_1.join)(netlifyConfig.build.publish, 'index.json'), { overwrite: false });
|
|
199
204
|
}
|
|
200
205
|
catch { }
|
|
201
206
|
}
|
|
202
207
|
}
|
|
203
208
|
if (shortRevalidateRoutes.length !== 0) {
|
|
204
|
-
console.log(outdent_1.outdent `
|
|
209
|
+
console.log((0, outdent_1.outdent) `
|
|
205
210
|
The following routes use "revalidate" values of under ${constants_1.MINIMUM_REVALIDATE_SECONDS} seconds, which is not supported.
|
|
206
211
|
They will use a revalidate time of ${constants_1.MINIMUM_REVALIDATE_SECONDS} seconds instead.
|
|
207
212
|
`);
|
|
@@ -216,54 +221,59 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
216
221
|
}
|
|
217
222
|
};
|
|
218
223
|
exports.moveStaticPages = moveStaticPages;
|
|
224
|
+
/**
|
|
225
|
+
* Attempt to patch a source file, preserving a backup
|
|
226
|
+
*/
|
|
219
227
|
const patchFile = async ({ file, from, to }) => {
|
|
220
|
-
if (!fs_extra_1.existsSync(file)) {
|
|
221
|
-
|
|
228
|
+
if (!(0, fs_extra_1.existsSync)(file)) {
|
|
229
|
+
console.warn('File was not found');
|
|
230
|
+
return false;
|
|
222
231
|
}
|
|
223
|
-
const content = await fs_extra_1.readFile(file, 'utf8');
|
|
232
|
+
const content = await (0, fs_extra_1.readFile)(file, 'utf8');
|
|
224
233
|
if (content.includes(to)) {
|
|
225
|
-
|
|
234
|
+
console.log('File already patched');
|
|
235
|
+
return false;
|
|
226
236
|
}
|
|
227
237
|
const newContent = content.replace(from, to);
|
|
228
|
-
|
|
229
|
-
|
|
238
|
+
if (newContent === content) {
|
|
239
|
+
console.warn('File was not changed');
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
await (0, fs_extra_1.writeFile)(`${file}.orig`, content);
|
|
243
|
+
await (0, fs_extra_1.writeFile)(file, newContent);
|
|
244
|
+
console.log('Done');
|
|
245
|
+
return true;
|
|
230
246
|
};
|
|
247
|
+
/**
|
|
248
|
+
* The file we need has moved around a bit over the past few versions,
|
|
249
|
+
* so we iterate through the options until we find it
|
|
250
|
+
*/
|
|
231
251
|
const getServerFile = (root) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
if (!serverFile) {
|
|
240
|
-
try {
|
|
241
|
-
// eslint-disable-next-line node/no-missing-require
|
|
242
|
-
serverFile = require.resolve('next/dist/next-server/server/next-server', { paths: [root] });
|
|
243
|
-
}
|
|
244
|
-
catch {
|
|
245
|
-
// Ignore
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return serverFile;
|
|
252
|
+
const candidates = [
|
|
253
|
+
'next/dist/server/base-server',
|
|
254
|
+
'next/dist/server/next-server',
|
|
255
|
+
'next/dist/next-server/server/next-server',
|
|
256
|
+
];
|
|
257
|
+
return (0, utils_1.findModuleFromBase)({ candidates, paths: [root] });
|
|
249
258
|
};
|
|
250
|
-
const patchNextFiles =
|
|
259
|
+
const patchNextFiles = (root) => {
|
|
251
260
|
const serverFile = getServerFile(root);
|
|
252
261
|
console.log(`Patching ${serverFile}`);
|
|
253
262
|
if (serverFile) {
|
|
254
|
-
|
|
263
|
+
return patchFile({
|
|
255
264
|
file: serverFile,
|
|
256
265
|
from: `let ssgCacheKey = `,
|
|
257
266
|
to: `let ssgCacheKey = process.env._BYPASS_SSG || `,
|
|
258
267
|
});
|
|
259
268
|
}
|
|
269
|
+
return false;
|
|
260
270
|
};
|
|
261
271
|
exports.patchNextFiles = patchNextFiles;
|
|
262
272
|
const unpatchNextFiles = async (root) => {
|
|
263
273
|
const serverFile = getServerFile(root);
|
|
264
274
|
const origFile = `${serverFile}.orig`;
|
|
265
|
-
if (fs_extra_1.existsSync(origFile)) {
|
|
266
|
-
await fs_extra_1.move(origFile, serverFile, { overwrite: true });
|
|
275
|
+
if ((0, fs_extra_1.existsSync)(origFile)) {
|
|
276
|
+
await (0, fs_extra_1.move)(origFile, serverFile, { overwrite: true });
|
|
267
277
|
}
|
|
268
278
|
};
|
|
269
279
|
exports.unpatchNextFiles = unpatchNextFiles;
|
|
@@ -274,9 +284,9 @@ const movePublicFiles = async ({ appDir, outdir, publish, }) => {
|
|
|
274
284
|
// If it exists, copy the files from the public folder there in order to include
|
|
275
285
|
// any files that were generated during the build. Otherwise, copy the public
|
|
276
286
|
// directory from the original app directory.
|
|
277
|
-
const publicDir = outdir ? pathe_1.join(appDir, outdir, 'public') : pathe_1.join(appDir, 'public');
|
|
278
|
-
if (fs_extra_1.existsSync(publicDir)) {
|
|
279
|
-
await fs_extra_1.copy(publicDir, `${publish}/`);
|
|
287
|
+
const publicDir = outdir ? (0, pathe_1.join)(appDir, outdir, 'public') : (0, pathe_1.join)(appDir, 'public');
|
|
288
|
+
if ((0, fs_extra_1.existsSync)(publicDir)) {
|
|
289
|
+
await (0, fs_extra_1.copy)(publicDir, `${publish}/`);
|
|
280
290
|
}
|
|
281
291
|
};
|
|
282
292
|
exports.movePublicFiles = movePublicFiles;
|
package/lib/helpers/functions.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.setupImageFunction = exports.generatePagesResolver = exports.generateFunctions = void 0;
|
|
7
|
+
const node_bridge_1 = __importDefault(require("@vercel/node-bridge"));
|
|
4
8
|
const fs_extra_1 = require("fs-extra");
|
|
5
9
|
const pathe_1 = require("pathe");
|
|
6
10
|
const constants_1 = require("../constants");
|
|
@@ -8,15 +12,14 @@ const getHandler_1 = require("../templates/getHandler");
|
|
|
8
12
|
const getPageResolver_1 = require("../templates/getPageResolver");
|
|
9
13
|
const generateFunctions = async ({ FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, PUBLISH_DIR }, appDir) => {
|
|
10
14
|
const functionsDir = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const publishDir = pathe_1.relative(functionDir, pathe_1.join(process.cwd(), PUBLISH_DIR));
|
|
15
|
+
const functionDir = (0, pathe_1.join)(process.cwd(), functionsDir, constants_1.HANDLER_FUNCTION_NAME);
|
|
16
|
+
const publishDir = (0, pathe_1.relative)(functionDir, (0, pathe_1.join)(process.cwd(), PUBLISH_DIR));
|
|
14
17
|
const writeHandler = async (func, isODB) => {
|
|
15
|
-
const handlerSource = await getHandler_1.getHandler({ isODB, publishDir, appDir: pathe_1.relative(functionDir, appDir) });
|
|
16
|
-
await fs_extra_1.ensureDir(pathe_1.join(functionsDir, func));
|
|
17
|
-
await fs_extra_1.writeFile(pathe_1.join(functionsDir, func, `${func}.js`), handlerSource);
|
|
18
|
-
await fs_extra_1.copyFile(
|
|
19
|
-
await fs_extra_1.copyFile(pathe_1.join(__dirname, '..', '..', 'lib', 'templates', 'handlerUtils.js'), pathe_1.join(functionsDir, func, 'handlerUtils.js'));
|
|
18
|
+
const handlerSource = await (0, getHandler_1.getHandler)({ isODB, publishDir, appDir: (0, pathe_1.relative)(functionDir, appDir) });
|
|
19
|
+
await (0, fs_extra_1.ensureDir)((0, pathe_1.join)(functionsDir, func));
|
|
20
|
+
await (0, fs_extra_1.writeFile)((0, pathe_1.join)(functionsDir, func, `${func}.js`), handlerSource);
|
|
21
|
+
await (0, fs_extra_1.copyFile)(node_bridge_1.default, (0, pathe_1.join)(functionsDir, func, 'bridge.js'));
|
|
22
|
+
await (0, fs_extra_1.copyFile)((0, pathe_1.join)(__dirname, '..', '..', 'lib', 'templates', 'handlerUtils.js'), (0, pathe_1.join)(functionsDir, func, 'handlerUtils.js'));
|
|
20
23
|
};
|
|
21
24
|
await writeHandler(constants_1.HANDLER_FUNCTION_NAME, false);
|
|
22
25
|
await writeHandler(constants_1.ODB_FUNCTION_NAME, true);
|
|
@@ -28,25 +31,25 @@ exports.generateFunctions = generateFunctions;
|
|
|
28
31
|
*/
|
|
29
32
|
const generatePagesResolver = async ({ constants: { INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS_SRC, PUBLISH_DIR }, target, }) => {
|
|
30
33
|
const functionsPath = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC;
|
|
31
|
-
const jsSource = await getPageResolver_1.getPageResolver({
|
|
34
|
+
const jsSource = await (0, getPageResolver_1.getPageResolver)({
|
|
32
35
|
publish: PUBLISH_DIR,
|
|
33
36
|
target,
|
|
34
37
|
});
|
|
35
|
-
await fs_extra_1.writeFile(pathe_1.join(functionsPath, constants_1.ODB_FUNCTION_NAME, 'pages.js'), jsSource);
|
|
36
|
-
await fs_extra_1.writeFile(pathe_1.join(functionsPath, constants_1.HANDLER_FUNCTION_NAME, 'pages.js'), jsSource);
|
|
38
|
+
await (0, fs_extra_1.writeFile)((0, pathe_1.join)(functionsPath, constants_1.ODB_FUNCTION_NAME, 'pages.js'), jsSource);
|
|
39
|
+
await (0, fs_extra_1.writeFile)((0, pathe_1.join)(functionsPath, constants_1.HANDLER_FUNCTION_NAME, 'pages.js'), jsSource);
|
|
37
40
|
};
|
|
38
41
|
exports.generatePagesResolver = generatePagesResolver;
|
|
39
42
|
// Move our next/image function into the correct functions directory
|
|
40
43
|
const setupImageFunction = async ({ constants: { INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC = constants_1.DEFAULT_FUNCTIONS_SRC }, imageconfig = {}, netlifyConfig, basePath, }) => {
|
|
41
44
|
const functionsPath = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC;
|
|
42
45
|
const functionName = `${constants_1.IMAGE_FUNCTION_NAME}.js`;
|
|
43
|
-
const functionDirectory = pathe_1.join(functionsPath, constants_1.IMAGE_FUNCTION_NAME);
|
|
44
|
-
await fs_extra_1.ensureDir(functionDirectory);
|
|
45
|
-
await fs_extra_1.writeJSON(pathe_1.join(functionDirectory, 'imageconfig.json'), {
|
|
46
|
+
const functionDirectory = (0, pathe_1.join)(functionsPath, constants_1.IMAGE_FUNCTION_NAME);
|
|
47
|
+
await (0, fs_extra_1.ensureDir)(functionDirectory);
|
|
48
|
+
await (0, fs_extra_1.writeJSON)((0, pathe_1.join)(functionDirectory, 'imageconfig.json'), {
|
|
46
49
|
...imageconfig,
|
|
47
50
|
basePath: [basePath, constants_1.IMAGE_FUNCTION_NAME].join('/'),
|
|
48
51
|
});
|
|
49
|
-
await fs_extra_1.copyFile(pathe_1.join(__dirname, '..', '..', 'lib', 'templates', 'ipx.js'), pathe_1.join(functionDirectory, functionName));
|
|
52
|
+
await (0, fs_extra_1.copyFile)((0, pathe_1.join)(__dirname, '..', '..', 'lib', 'templates', 'ipx.js'), (0, pathe_1.join)(functionDirectory, functionName));
|
|
50
53
|
const imagePath = imageconfig.path || '/_next/image';
|
|
51
54
|
netlifyConfig.redirects.push({
|
|
52
55
|
from: `${imagePath}*`,
|