@opennextjs/aws 3.9.7 → 3.9.9
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/build/copyTracedFiles.js +8 -2
- package/dist/build/installDeps.js +17 -19
- package/dist/build/patch/codePatcher.d.ts +4 -0
- package/dist/build/patch/codePatcher.js +1 -0
- package/dist/build/patch/patches/index.d.ts +1 -0
- package/dist/build/patch/patches/index.js +1 -0
- package/dist/build/patch/patches/patchOriginalNextConfig.d.ts +10 -0
- package/dist/build/patch/patches/patchOriginalNextConfig.js +78 -0
- package/dist/build.js +3 -0
- package/dist/plugins/inline-require-resolve.d.ts +10 -0
- package/dist/plugins/inline-require-resolve.js +27 -0
- package/package.json +1 -1
|
@@ -217,13 +217,19 @@ File ${serverPath} does not exist
|
|
|
217
217
|
});
|
|
218
218
|
readdirSync(standaloneNextDir)
|
|
219
219
|
.filter((fileOrDir) => !statSync(path.join(standaloneNextDir, fileOrDir)).isDirectory())
|
|
220
|
-
.forEach((file) =>
|
|
220
|
+
.forEach((file) => {
|
|
221
|
+
copyFileSync(path.join(standaloneNextDir, file), path.join(outputNextDir, file));
|
|
222
|
+
tracedFiles.push(path.join(outputNextDir, file));
|
|
223
|
+
});
|
|
221
224
|
// We then need to copy all the files at the root of server
|
|
222
225
|
mkdirSync(path.join(outputNextDir, "server"), { recursive: true });
|
|
223
226
|
readdirSync(standaloneServerDir)
|
|
224
227
|
.filter((fileOrDir) => !statSync(path.join(standaloneServerDir, fileOrDir)).isDirectory())
|
|
225
228
|
.filter((file) => file !== "server.js")
|
|
226
|
-
.forEach((file) =>
|
|
229
|
+
.forEach((file) => {
|
|
230
|
+
copyFileSync(path.join(standaloneServerDir, file), path.join(path.join(outputNextDir, "server"), file));
|
|
231
|
+
tracedFiles.push(path.join(outputNextDir, "server", file));
|
|
232
|
+
});
|
|
227
233
|
// Copy patch file
|
|
228
234
|
copyPatchFile(path.join(outputDir, packagePath));
|
|
229
235
|
// TODO: Recompute all the files.
|
|
@@ -3,7 +3,6 @@ import os from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { execSync } from "node:child_process";
|
|
5
5
|
import logger from "../logger.js";
|
|
6
|
-
const AFFECTED_NODE_VERSIONS = ["22.17.0", "22.17.1", "22.18.0"];
|
|
7
6
|
export function installDependencies(outputDir, installOptions) {
|
|
8
7
|
try {
|
|
9
8
|
if (!installOptions) {
|
|
@@ -37,28 +36,27 @@ export function installDependencies(outputDir, installOptions) {
|
|
|
37
36
|
});
|
|
38
37
|
// Copy the node_modules to the outputDir
|
|
39
38
|
fs.cpSync(path.join(tempInstallDir, "node_modules"), path.join(outputDir, "node_modules"), { recursive: true, force: true, dereference: true });
|
|
40
|
-
// This is a workaround for Node `22.17.0` and `22.17.1`
|
|
41
39
|
// https://github.com/nodejs/node/issues/59168
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
fs.copyFileSync(realFilePath, outputFilePath);
|
|
57
|
-
fs.chmodSync(outputFilePath, "755");
|
|
58
|
-
logger.debug(`Replaced symlink ${fileName} with actual file`);
|
|
40
|
+
// This is a workaround for all Node versions. It seems to be an issue continue to affect new versions aswell.
|
|
41
|
+
// Therefor I think the most logical solution is to always run this workaround instead of trying to figure out which versions are affected.
|
|
42
|
+
const tempBinDir = path.join(tempInstallDir, "node_modules", ".bin");
|
|
43
|
+
const outputBinDir = path.join(outputDir, "node_modules", ".bin");
|
|
44
|
+
for (const fileName of fs.readdirSync(tempBinDir)) {
|
|
45
|
+
const symlinkPath = path.join(tempBinDir, fileName);
|
|
46
|
+
const stat = fs.lstatSync(symlinkPath);
|
|
47
|
+
if (stat.isSymbolicLink()) {
|
|
48
|
+
const linkTarget = fs.readlinkSync(symlinkPath);
|
|
49
|
+
const realFilePath = path.resolve(tempBinDir, linkTarget);
|
|
50
|
+
const outputFilePath = path.join(outputBinDir, fileName);
|
|
51
|
+
if (fs.existsSync(outputFilePath)) {
|
|
52
|
+
fs.unlinkSync(outputFilePath);
|
|
59
53
|
}
|
|
54
|
+
fs.copyFileSync(realFilePath, outputFilePath);
|
|
55
|
+
fs.chmodSync(outputFilePath, "755");
|
|
56
|
+
logger.debug(`Replaced symlink ${fileName} with actual file`);
|
|
60
57
|
}
|
|
61
58
|
}
|
|
59
|
+
// End of Node Workaround
|
|
62
60
|
// Cleanup tempDir
|
|
63
61
|
fs.rmSync(tempInstallDir, { recursive: true, force: true });
|
|
64
62
|
logger.info(`Dependencies installed for ${name}`);
|
|
@@ -26,6 +26,10 @@ export type PatchCodeFn = (args: {
|
|
|
26
26
|
* Next.js manifests that are used by Next at runtime
|
|
27
27
|
*/
|
|
28
28
|
manifests: ReturnType<typeof getManifests>;
|
|
29
|
+
/**
|
|
30
|
+
* OpenNext build options
|
|
31
|
+
*/
|
|
32
|
+
buildOptions: buildHelper.BuildOptions;
|
|
29
33
|
}) => Promise<string>;
|
|
30
34
|
interface IndividualPatch {
|
|
31
35
|
pathFilter: RegExp;
|
|
@@ -4,3 +4,4 @@ export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, }
|
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
6
|
export { patchNodeEnvironment } from "./patchNodeEnvironment.js";
|
|
7
|
+
export { patchOriginalNextConfig } from "./patchOriginalNextConfig.js";
|
|
@@ -4,3 +4,4 @@ export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, }
|
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
6
|
export { patchNodeEnvironment } from "./patchNodeEnvironment.js";
|
|
7
|
+
export { patchOriginalNextConfig } from "./patchOriginalNextConfig.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as buildHelper from "../../helper.js";
|
|
2
|
+
/**
|
|
3
|
+
* Next 16.1+ removes `skipTrailingSlashRedirect` from the config in `required-server-files.json`.
|
|
4
|
+
*
|
|
5
|
+
* This patch adds it back in by compiling and importing the user's `next.config.js` file.
|
|
6
|
+
*
|
|
7
|
+
* It is a regression in https://github.com/vercel/next.js/pull/86830
|
|
8
|
+
* TODO(#1082): revisit when Next is fixed
|
|
9
|
+
*/
|
|
10
|
+
export declare function patchOriginalNextConfig(options: buildHelper.BuildOptions): Promise<void>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { build } from "esbuild";
|
|
4
|
+
import { inlineRequireResolvePlugin } from "../../../plugins/inline-require-resolve.js";
|
|
5
|
+
import * as buildHelper from "../../helper.js";
|
|
6
|
+
/**
|
|
7
|
+
* Next 16.1+ removes `skipTrailingSlashRedirect` from the config in `required-server-files.json`.
|
|
8
|
+
*
|
|
9
|
+
* This patch adds it back in by compiling and importing the user's `next.config.js` file.
|
|
10
|
+
*
|
|
11
|
+
* It is a regression in https://github.com/vercel/next.js/pull/86830
|
|
12
|
+
* TODO(#1082): revisit when Next is fixed
|
|
13
|
+
*/
|
|
14
|
+
export async function patchOriginalNextConfig(options) {
|
|
15
|
+
if (buildHelper.compareSemver(options.nextVersion, "<", "16.1.0")) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// The manifests in both `.next` and `.next/standalone` folders
|
|
19
|
+
// are patched as Open Next uses either of them.
|
|
20
|
+
const manifestPath = path.join(options.appBuildOutputPath, ".next/required-server-files.json");
|
|
21
|
+
const manifestStandalonePath = path.join(options.appBuildOutputPath, ".next/standalone", buildHelper.getPackagePath(options), ".next/required-server-files.json");
|
|
22
|
+
if (fs.existsSync(manifestPath)) {
|
|
23
|
+
const manifest = JSON.parse(await fs.promises.readFile(manifestPath, "utf-8"));
|
|
24
|
+
if (manifest.config.skipTrailingSlashRedirect === undefined) {
|
|
25
|
+
const { skipTrailingSlashRedirect } = await importNextConfigFromSource(options);
|
|
26
|
+
manifest.config.skipTrailingSlashRedirect =
|
|
27
|
+
skipTrailingSlashRedirect ?? false;
|
|
28
|
+
await fs.promises.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
29
|
+
if (fs.existsSync(manifestStandalonePath)) {
|
|
30
|
+
await fs.promises.writeFile(manifestStandalonePath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
throw new Error(`Could not find required-server-files.json at path: ${manifestPath}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Compile and import the user's `next.config` file
|
|
40
|
+
*
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
async function importNextConfigFromSource(buildOptions) {
|
|
44
|
+
// Find the `next.config file with any supported extension
|
|
45
|
+
const tsExtensions = [".ts", ".mts", ".cts"];
|
|
46
|
+
const possibleExtensions = [...tsExtensions, ".mjs", ".js", ".cjs"];
|
|
47
|
+
let configPath;
|
|
48
|
+
let configExtension;
|
|
49
|
+
for (const ext of possibleExtensions) {
|
|
50
|
+
const testPath = path.join(buildOptions.appPath, `next.config${ext}`);
|
|
51
|
+
if (fs.existsSync(testPath)) {
|
|
52
|
+
configPath = testPath;
|
|
53
|
+
configExtension = ext;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!configPath || !configExtension) {
|
|
58
|
+
throw new Error("Could not find next.config file");
|
|
59
|
+
}
|
|
60
|
+
let configToImport;
|
|
61
|
+
// Only compile if the extension is a TypeScript extension
|
|
62
|
+
if (tsExtensions.includes(configExtension)) {
|
|
63
|
+
await build({
|
|
64
|
+
entryPoints: [configPath],
|
|
65
|
+
outfile: path.join(buildOptions.tempBuildDir, "next.config.mjs"),
|
|
66
|
+
bundle: true,
|
|
67
|
+
format: "esm",
|
|
68
|
+
platform: "node",
|
|
69
|
+
plugins: [inlineRequireResolvePlugin],
|
|
70
|
+
});
|
|
71
|
+
configToImport = path.join(buildOptions.tempBuildDir, "next.config.mjs");
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// For .js, .mjs, .cjs, use the file directly
|
|
75
|
+
configToImport = configPath;
|
|
76
|
+
}
|
|
77
|
+
return (await import(configToImport)).default;
|
|
78
|
+
}
|
package/dist/build.js
CHANGED
|
@@ -12,6 +12,7 @@ import { createServerBundle } from "./build/createServerBundle.js";
|
|
|
12
12
|
import { createWarmerBundle } from "./build/createWarmerBundle.js";
|
|
13
13
|
import { generateOutput } from "./build/generateOutput.js";
|
|
14
14
|
import * as buildHelper from "./build/helper.js";
|
|
15
|
+
import { patchOriginalNextConfig } from "./build/patch/patches/index.js";
|
|
15
16
|
import { printHeader, showWarningOnWindows } from "./build/utils.js";
|
|
16
17
|
import logger from "./logger.js";
|
|
17
18
|
export async function build(openNextConfigPath, nodeExternals) {
|
|
@@ -33,6 +34,8 @@ export async function build(openNextConfigPath, nodeExternals) {
|
|
|
33
34
|
buildNextjsApp(options);
|
|
34
35
|
// Generate deployable bundle
|
|
35
36
|
printHeader("Generating bundle");
|
|
37
|
+
// Patch the original Next.js config
|
|
38
|
+
await patchOriginalNextConfig(options);
|
|
36
39
|
// Compile cache.ts
|
|
37
40
|
compileCache(options);
|
|
38
41
|
// Compile middleware
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
/**
|
|
3
|
+
* Inlines calls to `require.resolve` in JavaScript files.
|
|
4
|
+
*
|
|
5
|
+
* esbuild does not statically analyse `require.resolve` calls, and the polyfill
|
|
6
|
+
* does not include an implementation to handle them. This can be problematic
|
|
7
|
+
* if you attempt to dynamically import a file built by esbuild that unknowingly
|
|
8
|
+
* contains `require.resolve` calls, as they will throw an error during import.
|
|
9
|
+
*/
|
|
10
|
+
export declare const inlineRequireResolvePlugin: Plugin;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
/**
|
|
4
|
+
* Inlines calls to `require.resolve` in JavaScript files.
|
|
5
|
+
*
|
|
6
|
+
* esbuild does not statically analyse `require.resolve` calls, and the polyfill
|
|
7
|
+
* does not include an implementation to handle them. This can be problematic
|
|
8
|
+
* if you attempt to dynamically import a file built by esbuild that unknowingly
|
|
9
|
+
* contains `require.resolve` calls, as they will throw an error during import.
|
|
10
|
+
*/
|
|
11
|
+
export const inlineRequireResolvePlugin = {
|
|
12
|
+
name: "inline-require-resolve",
|
|
13
|
+
setup: (build) => {
|
|
14
|
+
build.onLoad({ filter: /\.(js|ts|mjs|cjs)$/ }, async (args) => {
|
|
15
|
+
const source = await fs.promises.readFile(args.path, "utf-8");
|
|
16
|
+
const transformed = source.replace(/require\.resolve\((?<quote>['"])((?:\\.|.)*?)\k<quote>\)/g, (_, quote, modulePath) => {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.stringify(createRequire(args.path).resolve(modulePath));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return `require.resolve(${quote}${modulePath}${quote})`;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return { contents: transformed, loader: "default" };
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|