@opennextjs/cloudflare 0.0.0-5454280 → 0.0.0-88fe982

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.
Files changed (3) hide show
  1. package/README.md +14 -23
  2. package/dist/index.mjs +128 -27
  3. package/package.json +9 -5
package/README.md CHANGED
@@ -1,32 +1,21 @@
1
1
  # Next.js builder for Cloudflare
2
2
 
3
- ## Build your app
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
- ```json
22
- "node-url": "npm:url@^0.11.4",
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
- - Use `wrangler dev`
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 { readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
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 = readFileSync3(nextjsAppPaths.standaloneAppDir + "/server.js", "utf8")?.match(
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-5454280",
4
+ "version": "0.0.0-88fe982",
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
  }