@opennextjs/cloudflare 0.0.0-5454280 → 0.0.0-fd3c2b9
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 -23
- package/dist/index.mjs +128 -27
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,32 +1,21 @@
|
|
|
1
1
|
# Next.js builder for Cloudflare
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
- update the `next.config.mjs` as follows
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
/** @type {import('next').NextConfig} */
|
|
9
|
-
const nextConfig = {
|
|
10
|
-
output: "standalone",
|
|
11
|
-
experimental: {
|
|
12
|
-
serverMinification: false,
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default nextConfig;
|
|
17
|
-
```
|
|
3
|
+
## Configure your app
|
|
18
4
|
|
|
19
5
|
- add the following `devDependency` to the `package.json`:
|
|
20
6
|
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
"wrangler": "^3.77.0"
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add -D wrangler@latest @opennextjs/cloudflare
|
|
24
9
|
```
|
|
25
10
|
|
|
26
|
-
- Execute `npx @flarelabs-net/builder@latest` in your app folder
|
|
27
|
-
|
|
28
11
|
## Serve your app
|
|
29
12
|
|
|
13
|
+
- build the app and adapt it for Cloudflare
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpx cloudflare
|
|
17
|
+
```
|
|
18
|
+
|
|
30
19
|
- add a `wrangler.toml` at the root of your project
|
|
31
20
|
|
|
32
21
|
```toml
|
|
@@ -36,11 +25,13 @@
|
|
|
36
25
|
|
|
37
26
|
compatibility_date = "2024-08-29"
|
|
38
27
|
compatibility_flags = ["nodejs_compat_v2"]
|
|
39
|
-
workers_dev = true
|
|
40
|
-
minify = false
|
|
41
28
|
|
|
42
29
|
# Use the new Workers + Assets to host the static frontend files
|
|
43
30
|
experimental_assets = { directory = ".worker-next/assets", binding = "ASSETS" }
|
|
44
31
|
```
|
|
45
32
|
|
|
46
|
-
-
|
|
33
|
+
- Preview the app in Wrangler
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm wrangler dev
|
|
37
|
+
```
|
package/dist/index.mjs
CHANGED
|
@@ -309,7 +309,7 @@ function runNextBuildCommand(packager, nextAppDir2) {
|
|
|
309
309
|
|
|
310
310
|
// src/build/build-worker.ts
|
|
311
311
|
import { build } from "esbuild";
|
|
312
|
-
import {
|
|
312
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
313
313
|
import { cp, readFile, writeFile } from "node:fs/promises";
|
|
314
314
|
|
|
315
315
|
// src/build/patches/investigated/patch-require.ts
|
|
@@ -6842,12 +6842,138 @@ function patchWranglerDeps(paths) {
|
|
|
6842
6842
|
writeFileSync(tracerFile, pacthedTracer);
|
|
6843
6843
|
}
|
|
6844
6844
|
|
|
6845
|
+
// src/build/patches/investigated/update-webpack-chunks-file/index.ts
|
|
6846
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
6847
|
+
|
|
6848
|
+
// src/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.ts
|
|
6849
|
+
import * as ts from "ts-morph";
|
|
6850
|
+
async function getChunkInstallationIdentifiers(sourceFile) {
|
|
6851
|
+
const installChunkDeclaration = getInstallChunkDeclaration(sourceFile);
|
|
6852
|
+
const installedChunksDeclaration = getInstalledChunksDeclaration(sourceFile, installChunkDeclaration);
|
|
6853
|
+
return {
|
|
6854
|
+
installChunk: installChunkDeclaration.getName(),
|
|
6855
|
+
installedChunks: installedChunksDeclaration.getName()
|
|
6856
|
+
};
|
|
6857
|
+
}
|
|
6858
|
+
function getInstallChunkDeclaration(sourceFile) {
|
|
6859
|
+
const installChunkDeclaration = sourceFile.getDescendantsOfKind(ts.SyntaxKind.VariableDeclaration).find((declaration) => {
|
|
6860
|
+
const arrowFunction = declaration.getInitializerIfKind(ts.SyntaxKind.ArrowFunction);
|
|
6861
|
+
if (!arrowFunction) return false;
|
|
6862
|
+
const functionParameters = arrowFunction.getParameters();
|
|
6863
|
+
if (functionParameters.length !== 1) return false;
|
|
6864
|
+
const arrowFunctionBodyBlock = arrowFunction.getFirstChildByKind(ts.SyntaxKind.Block);
|
|
6865
|
+
if (!arrowFunctionBodyBlock) return false;
|
|
6866
|
+
const statementKinds = arrowFunctionBodyBlock.getStatements().map((statement) => statement.getKind());
|
|
6867
|
+
const forInStatements = statementKinds.filter((s) => s === ts.SyntaxKind.ForInStatement);
|
|
6868
|
+
const forStatements = statementKinds.filter((s) => s === ts.SyntaxKind.ForStatement);
|
|
6869
|
+
if (forInStatements.length !== 1 || forStatements.length !== 1) return false;
|
|
6870
|
+
const parameterName = functionParameters[0].getText();
|
|
6871
|
+
const functionParameterAccessedProperties = arrowFunctionBodyBlock.getDescendantsOfKind(ts.SyntaxKind.PropertyAccessExpression).filter(
|
|
6872
|
+
(propertyAccessExpression) => propertyAccessExpression.getExpression().getText() === parameterName
|
|
6873
|
+
).map((propertyAccessExpression) => propertyAccessExpression.getName());
|
|
6874
|
+
if (functionParameterAccessedProperties.join(", ") !== "modules, ids, runtime") return false;
|
|
6875
|
+
return true;
|
|
6876
|
+
});
|
|
6877
|
+
if (!installChunkDeclaration) {
|
|
6878
|
+
throw new Error("ERROR: unable to find the installChunk function declaration");
|
|
6879
|
+
}
|
|
6880
|
+
return installChunkDeclaration;
|
|
6881
|
+
}
|
|
6882
|
+
function getInstalledChunksDeclaration(sourceFile, installChunkDeclaration) {
|
|
6883
|
+
const allVariableDeclarations = sourceFile.getDescendantsOfKind(ts.SyntaxKind.VariableDeclaration);
|
|
6884
|
+
const installChunkDeclarationIdx = allVariableDeclarations.findIndex(
|
|
6885
|
+
(declaration) => declaration === installChunkDeclaration
|
|
6886
|
+
);
|
|
6887
|
+
const installedChunksDeclaration = allVariableDeclarations[installChunkDeclarationIdx - 1];
|
|
6888
|
+
if (!installedChunksDeclaration?.getInitializer()?.isKind(ts.SyntaxKind.ObjectLiteralExpression)) {
|
|
6889
|
+
throw new Error("ERROR: unable to find the installedChunks declaration");
|
|
6890
|
+
}
|
|
6891
|
+
return installedChunksDeclaration;
|
|
6892
|
+
}
|
|
6893
|
+
|
|
6894
|
+
// src/build/patches/investigated/update-webpack-chunks-file/get-file-content-with-updated-webpack-f-require-code.ts
|
|
6895
|
+
import * as ts2 from "ts-morph";
|
|
6896
|
+
async function getFileContentWithUpdatedWebpackFRequireCode(sourceFile, { installedChunks, installChunk }, chunks) {
|
|
6897
|
+
const webpackFRequireFunction = sourceFile.getDescendantsOfKind(ts2.SyntaxKind.ArrowFunction).find((arrowFunction) => {
|
|
6898
|
+
const binaryExpression = arrowFunction.getFirstAncestorByKind(ts2.SyntaxKind.BinaryExpression);
|
|
6899
|
+
if (!binaryExpression) return false;
|
|
6900
|
+
const binaryExpressionLeft = binaryExpression.getLeft();
|
|
6901
|
+
if (!binaryExpressionLeft.getText().endsWith(".f.require")) return false;
|
|
6902
|
+
const binaryExpressionOperator = binaryExpression.getOperatorToken();
|
|
6903
|
+
if (binaryExpressionOperator.getText() !== "=") return false;
|
|
6904
|
+
const binaryExpressionRight = binaryExpression.getRight();
|
|
6905
|
+
if (binaryExpressionRight !== arrowFunction) return false;
|
|
6906
|
+
const arrowFunctionBody = arrowFunction.getBody();
|
|
6907
|
+
if (!arrowFunctionBody.isKind(ts2.SyntaxKind.Block)) return false;
|
|
6908
|
+
const arrowFunctionBodyText = arrowFunctionBody.getText();
|
|
6909
|
+
const functionUsesChunkInstallationVariables = arrowFunctionBodyText.includes(installChunk) && arrowFunctionBodyText.includes(installedChunks);
|
|
6910
|
+
if (!functionUsesChunkInstallationVariables) return false;
|
|
6911
|
+
const functionParameters = arrowFunction.getParameters();
|
|
6912
|
+
if (functionParameters.length !== 2) return false;
|
|
6913
|
+
const callsInstallChunk = arrowFunctionBody.getDescendantsOfKind(ts2.SyntaxKind.CallExpression).some((callExpression) => callExpression.getExpression().getText() === installChunk);
|
|
6914
|
+
if (!callsInstallChunk) return false;
|
|
6915
|
+
const functionFirstParameterName = functionParameters[0]?.getName();
|
|
6916
|
+
const accessesInstalledChunksUsingItsFirstParameter = arrowFunctionBody.getDescendantsOfKind(ts2.SyntaxKind.ElementAccessExpression).some((elementAccess) => {
|
|
6917
|
+
return elementAccess.getExpression().getText() === installedChunks && elementAccess.getArgumentExpression()?.getText() === functionFirstParameterName;
|
|
6918
|
+
});
|
|
6919
|
+
if (!accessesInstalledChunksUsingItsFirstParameter) return false;
|
|
6920
|
+
return true;
|
|
6921
|
+
});
|
|
6922
|
+
if (!webpackFRequireFunction) {
|
|
6923
|
+
throw new Error("ERROR: unable to find the webpack f require function declaration");
|
|
6924
|
+
}
|
|
6925
|
+
const functionParameterNames = webpackFRequireFunction.getParameters().map((parameter) => parameter.getName());
|
|
6926
|
+
const chunkId = functionParameterNames[0];
|
|
6927
|
+
const functionBody = webpackFRequireFunction.getBody();
|
|
6928
|
+
functionBody.insertStatements(0, [
|
|
6929
|
+
`if (${installedChunks}[${chunkId}]) return;`,
|
|
6930
|
+
...chunks.map(
|
|
6931
|
+
(chunk) => `
|
|
6932
|
+
if(${chunkId} === ${chunk}) return ${installChunk}(require("./chunks/${chunk}.js"));`
|
|
6933
|
+
)
|
|
6934
|
+
]);
|
|
6935
|
+
return sourceFile.print();
|
|
6936
|
+
}
|
|
6937
|
+
|
|
6938
|
+
// src/build/utils/ts-parse-file.ts
|
|
6939
|
+
import * as ts3 from "ts-morph";
|
|
6940
|
+
function tsParseFile(fileContent) {
|
|
6941
|
+
const project = new ts3.Project();
|
|
6942
|
+
const sourceFile = project.createSourceFile("file.js", fileContent);
|
|
6943
|
+
return sourceFile;
|
|
6944
|
+
}
|
|
6945
|
+
|
|
6946
|
+
// src/build/patches/investigated/update-webpack-chunks-file/get-updated-webpack-chunks-file-content.ts
|
|
6947
|
+
async function getUpdatedWebpackChunksFileContent(fileContent, chunks) {
|
|
6948
|
+
const tsSourceFile = tsParseFile(fileContent);
|
|
6949
|
+
const chunkInstallationIdentifiers = await getChunkInstallationIdentifiers(tsSourceFile);
|
|
6950
|
+
const updatedFileContent = getFileContentWithUpdatedWebpackFRequireCode(
|
|
6951
|
+
tsSourceFile,
|
|
6952
|
+
chunkInstallationIdentifiers,
|
|
6953
|
+
chunks
|
|
6954
|
+
);
|
|
6955
|
+
return updatedFileContent;
|
|
6956
|
+
}
|
|
6957
|
+
|
|
6958
|
+
// src/build/patches/investigated/update-webpack-chunks-file/index.ts
|
|
6959
|
+
async function updateWebpackChunksFile(nextjsAppPaths) {
|
|
6960
|
+
console.log("# updateWebpackChunksFile");
|
|
6961
|
+
const webpackRuntimeFile = `${nextjsAppPaths.standaloneAppServerDir}/webpack-runtime.js`;
|
|
6962
|
+
const fileContent = readFileSync3(webpackRuntimeFile, "utf-8");
|
|
6963
|
+
const chunks = readdirSync2(`${nextjsAppPaths.standaloneAppServerDir}/chunks`).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
|
|
6964
|
+
console.log(` - chunk ${chunk}`);
|
|
6965
|
+
return chunk.replace(/\.js$/, "");
|
|
6966
|
+
});
|
|
6967
|
+
const updatedFileContent = await getUpdatedWebpackChunksFileContent(fileContent, chunks);
|
|
6968
|
+
writeFileSync2(webpackRuntimeFile, updatedFileContent);
|
|
6969
|
+
}
|
|
6970
|
+
|
|
6845
6971
|
// src/build/build-worker.ts
|
|
6846
6972
|
async function buildWorker(outputDir2, nextjsAppPaths, templateSrcDir) {
|
|
6847
6973
|
const templateDir = copyTemplates(templateSrcDir, nextjsAppPaths);
|
|
6848
6974
|
const workerEntrypoint = `${templateDir}/worker.ts`;
|
|
6849
6975
|
const workerOutputFile = `${outputDir2}/index.mjs`;
|
|
6850
|
-
const nextConfigStr =
|
|
6976
|
+
const nextConfigStr = readFileSync4(nextjsAppPaths.standaloneAppDir + "/server.js", "utf8")?.match(
|
|
6851
6977
|
/const nextConfig = ({.+?})\n/
|
|
6852
6978
|
)?.[1] ?? {};
|
|
6853
6979
|
console.log(`\x1B[35m\u2699\uFE0F Bundling the worker file...
|
|
@@ -6954,31 +7080,6 @@ async function updateWorkerBundledCode(workerOutputFile, nextjsAppPaths) {
|
|
|
6954
7080
|
patchedCode = inlineEvalManifest(patchedCode, nextjsAppPaths);
|
|
6955
7081
|
await writeFile(workerOutputFile, patchedCode);
|
|
6956
7082
|
}
|
|
6957
|
-
async function updateWebpackChunksFile(nextjsAppPaths) {
|
|
6958
|
-
console.log("# updateWebpackChunksFile");
|
|
6959
|
-
const webpackRuntimeFile = `${nextjsAppPaths.standaloneAppServerDir}/webpack-runtime.js`;
|
|
6960
|
-
console.log({ webpackRuntimeFile });
|
|
6961
|
-
const fileContent = readFileSync3(webpackRuntimeFile, "utf-8");
|
|
6962
|
-
const chunks = readdirSync2(`${nextjsAppPaths.standaloneAppServerDir}/chunks`).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
|
|
6963
|
-
console.log(` - chunk ${chunk}`);
|
|
6964
|
-
return chunk.replace(/\.js$/, "");
|
|
6965
|
-
});
|
|
6966
|
-
const updatedFileContent = fileContent.replace(
|
|
6967
|
-
"__webpack_require__.f.require = (chunkId, promises) => {",
|
|
6968
|
-
`__webpack_require__.f.require = (chunkId, promises) => {
|
|
6969
|
-
if (installedChunks[chunkId]) return;
|
|
6970
|
-
${chunks.map(
|
|
6971
|
-
(chunk) => `
|
|
6972
|
-
if (chunkId === ${chunk}) {
|
|
6973
|
-
installChunk(require("./chunks/${chunk}.js"));
|
|
6974
|
-
return;
|
|
6975
|
-
}
|
|
6976
|
-
`
|
|
6977
|
-
).join("\n")}
|
|
6978
|
-
`
|
|
6979
|
-
);
|
|
6980
|
-
writeFileSync2(webpackRuntimeFile, updatedFileContent);
|
|
6981
|
-
}
|
|
6982
7083
|
function createFixRequiresESBuildPlugin(templateDir) {
|
|
6983
7084
|
return {
|
|
6984
7085
|
name: "replaceRelative",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennextjs/cloudflare",
|
|
3
3
|
"description": "Cloudflare builder for next apps",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-fd3c2b9",
|
|
5
5
|
"bin": "dist/index.mjs",
|
|
6
6
|
"files": [
|
|
7
7
|
"README.md",
|
|
@@ -23,16 +23,20 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/flarelabs-net/poc-next",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@cloudflare/workers-types": "^4.20240909.0",
|
|
27
26
|
"@types/node": "^22.2.0",
|
|
28
27
|
"esbuild": "^0.23.0",
|
|
29
28
|
"glob": "^11.0.0",
|
|
30
|
-
"next": "14.2.5",
|
|
31
29
|
"tsup": "^8.2.4",
|
|
32
|
-
"typescript": "^5.5.4"
|
|
30
|
+
"typescript": "^5.5.4",
|
|
31
|
+
"vitest": "^2.1.1"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"ts-morph": "^23.0.0"
|
|
33
35
|
},
|
|
34
36
|
"scripts": {
|
|
35
37
|
"build": "tsup",
|
|
36
|
-
"build:watch": "tsup --watch src"
|
|
38
|
+
"build:watch": "tsup --watch src",
|
|
39
|
+
"test": "vitest --run",
|
|
40
|
+
"test:watch": "vitest"
|
|
37
41
|
}
|
|
38
42
|
}
|