-
Notifications
You must be signed in to change notification settings - Fork 774
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: second-cut of using unenv to create a hybrid node.js compatibil…
…ity setting (via inject) (#5878) * feat: first-cut of using unenv to create a hybrid node.js compatibility setting * fix up pg cloudflare socket detection * fix up unenv integration, use inject instead of various hacks * make the side-effects of injected globals tree-shakeable * mark unenv as external so that it doesn't get bundled into wrangler * don't configure esbuild with a define to rewrite global to globalThis - use unenv instead * correctly provide the global polyfill if inject is defined as a string * fix lint issues * add turbo.json file * update the activation mechanism to be just a runtime flag 'nodejs_compat_v2' accompanied by 'experimental' * update to unenv-nightly@1.10.0-1717495514.cea841e * switch to experimenta:nodejs_compat_v2 activation flag * fix: ignore aliases for packages that are not installed in the current app for example consola/core * prettify * fixup: update unenv to 1.10.0-1717606461.a117952 * post-review fixups * Add changeset * Update the fixture and add a test * Separate out the require call conversion from the alias import handling in the hybrid plugin * Make sure we don't match packages that don't exist * Fix formatting on the new fixture test * Fix deploy test snapshot for change to warning * Fix fixture test to be resilient to timezone changes The previous test would pass/fail depending upon which timezone you are in when you run it. * update the fixture to include an built-in alias currently this fails with: nodejs-hybrid-app:build: ✘ [ERROR] Plugin "unenv-cloudflare" returned a non-absolute path: node:assert (set a namespace if this is not a file path) nodejs-hybrid-app:build: nodejs-hybrid-app:build: src/index.ts:2:19: nodejs-hybrid-app:build: 2 │ import assert from "node:assert/strict"; nodejs-hybrid-app:build: ╵ ~~~~~~~~~~~~~~~~~~~~ nodejs-hybrid-app:build: * Match externals against the alias rather than the original path This was problematic because if you import from `node:assert/strict` there is no entry in the `external` map for that path, instead you need to map it to its alias first (e.g. `node:assert`). * Refactor node-compat validation and handling into a helper function * Remove extra node-compat validation call, which was messing things up since it mutates compat flags * Use a global (Buffer) in the fixture and test it works * Use named parameters for the validateNodeCompat() function --------- Co-authored-by: Peter Bacon Darwin <pbacondarwin@cloudflare.com>
- Loading branch information
1 parent
35b1a2f
commit 1e68fe5
Showing
34 changed files
with
1,140 additions
and
441 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
"wrangler": minor | ||
--- | ||
|
||
feat: add experimental support for hybrid Node.js compatibility | ||
|
||
_This feature is experimental and not yet available for general consumption._ | ||
|
||
Use a combination of workerd Node.js builtins (behind the `experimental:nodejs_compat_v2` flag) and | ||
Unenv polyfills (configured to only add those missing from the runtime) to provide a new more effective | ||
Node.js compatibility approach. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "nodejs-hybrid-app", | ||
"private": true, | ||
"scripts": { | ||
"dev": "wrangler dev", | ||
"build": "wrangler deploy --dry-run --outdir=./dist", | ||
"test:ci": "vitest run", | ||
"test:watch": "vitest" | ||
}, | ||
"devDependencies": { | ||
"@cloudflare/workers-tsconfig": "workspace:*", | ||
"@cloudflare/workers-types": "^4.20240222.0", | ||
"@types/pg": "^8.11.2", | ||
"pg": "8.11.3", | ||
"pg-cloudflare": "^1.1.1", | ||
"undici": "^5.28.3", | ||
"wrangler": "workspace:*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// node:assert/strict is currently an unenv alias to node:assert | ||
// this is not very common, but happens and we need to support it | ||
import assert from "node:assert/strict"; | ||
import { Client } from "pg"; | ||
|
||
assert(true, "the world is broken"); | ||
|
||
const buffer1 = Buffer.of(1); | ||
assert(buffer1.toJSON().data[0] === 1, "Buffer is broken"); | ||
|
||
const buffer2 = global.Buffer.of(1); | ||
assert(buffer2.toJSON().data[0] === 1, "global.Buffer is broken"); | ||
|
||
const buffer3 = globalThis.Buffer.of(1); | ||
assert(buffer3.toJSON().data[0] === 1, "globalThis.Buffer is broken"); | ||
|
||
/** | ||
* Welcome to Cloudflare Workers! This is your first worker. | ||
* | ||
* - Run `npm run dev` in your terminal to start a development server | ||
* - Open a browser tab at http://localhost:8787/ to see your worker in action | ||
* - Run `npm run deploy` to publish your worker | ||
* | ||
* Learn more at https://developers.cloudflare.com/workers/ | ||
*/ | ||
|
||
export default { | ||
async fetch( | ||
request: Request, | ||
env: Env, | ||
ctx: ExecutionContext | ||
): Promise<Response> { | ||
const client = new Client({ | ||
user: env.DB_USERNAME, | ||
password: env.DB_PASSWORD, | ||
host: env.DB_HOSTNAME, | ||
port: Number(env.DB_PORT), | ||
database: env.DB_NAME, | ||
}); | ||
await client.connect(); | ||
const result = await client.query(`SELECT * FROM rnc_database`); | ||
assert(true); | ||
|
||
// Return the first row as JSON | ||
const resp = new Response(JSON.stringify(result.rows[0]), { | ||
headers: { "Content-Type": "application/json" }, | ||
}); | ||
|
||
// Clean up the client | ||
ctx.waitUntil(client.end()); | ||
return resp; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { resolve } from "node:path"; | ||
import { fetch } from "undici"; | ||
import { describe, it } from "vitest"; | ||
import { runWranglerDev } from "../../shared/src/run-wrangler-long-lived"; | ||
|
||
describe("nodejs compat", () => { | ||
it("should work when running code requiring polyfills", async ({ | ||
expect, | ||
}) => { | ||
const { ip, port, stop } = await runWranglerDev( | ||
resolve(__dirname, "../src"), | ||
["--port=0", "--inspector-port=0"] | ||
); | ||
try { | ||
const response = await fetch(`http://${ip}:${port}`); | ||
const result = (await response.json()) as { id: string }; | ||
expect(result.id).toEqual("1"); | ||
} finally { | ||
await stop(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"extends": "@cloudflare/workers-tsconfig/tsconfig.json", | ||
"compilerOptions": { | ||
"types": ["node"] | ||
}, | ||
"include": ["**/*.ts", "../../../node-types.d.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"compilerOptions": { | ||
"module": "esnext", | ||
"target": "esnext", | ||
"lib": ["esnext"], | ||
"strict": true, | ||
"isolatedModules": true, | ||
"noEmit": true, | ||
"types": [ | ||
"@cloudflare/workers-types/experimental", | ||
"./worker-configuration.d.ts" | ||
], | ||
"allowJs": true, | ||
"allowSyntheticDefaultImports": true | ||
}, | ||
"include": ["src"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"$schema": "http://turbo.build/schema.json", | ||
"extends": ["//"], | ||
"pipeline": { | ||
"build": { | ||
"outputs": ["dist/**"] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { defineProject, mergeConfig } from "vitest/config"; | ||
import configShared from "../../vitest.shared"; | ||
|
||
export default mergeConfig( | ||
configShared, | ||
defineProject({ | ||
test: {}, | ||
}) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Generated by Wrangler on Tue Mar 05 2024 16:04:07 GMT+0000 (Greenwich Mean Time) | ||
// by running `wrangler types` | ||
|
||
interface Env { | ||
DB_HOSTNAME: "hh-pgsql-public.ebi.ac.uk"; | ||
DB_PORT: "5432"; | ||
DB_NAME: "pfmegrnargs"; | ||
DB_USERNAME: "reader"; | ||
DB_PASSWORD: "NWDMCE5xdipIjRrp"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name = "nodejs-hybrid-app" | ||
main = "src/index.ts" | ||
compatibility_date = "2024-06-03" | ||
compatibility_flags = ["experimental:nodejs_compat_v2"] | ||
|
||
[vars] | ||
DB_HOSTNAME = "hh-pgsql-public.ebi.ac.uk" | ||
DB_PORT = "5432" | ||
DB_NAME = "pfmegrnargs" | ||
DB_USERNAME = "reader" | ||
DB_PASSWORD = "NWDMCE5xdipIjRrp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.