diff --git a/.changeset/pretty-geese-drum.md b/.changeset/pretty-geese-drum.md new file mode 100644 index 000000000000..3384033cb97d --- /dev/null +++ b/.changeset/pretty-geese-drum.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/adapter-cloudflare-workers': minor +'@sveltejs/adapter-cloudflare': minor +--- + +feat: Add Node.js compatibility diff --git a/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md b/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md index 61f8321f495d..f0f11e7c682e 100644 --- a/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md +++ b/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md @@ -77,6 +77,13 @@ export default { }; ``` +If you would like to enable [Node.js compatibility](https://developers.cloudflare.com/workers/runtime-apis/nodejs/#enable-nodejs-from-the-cloudflare-dashboard), you can add "nodejs_compat" flag to `wrangler.toml`: + +```toml +/// file: wrangler.toml +compatibility_flags = [ "nodejs_compat" ] +``` + ## Bindings The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#parameters) object contains your project's [bindings](https://developers.cloudflare.com/workers/platform/environment-variables/), which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform` property, along with `context` and `caches`, meaning that you can access it in hooks and endpoints: diff --git a/packages/adapter-cloudflare-workers/index.d.ts b/packages/adapter-cloudflare-workers/index.d.ts index d5ef5b24e7b5..5bfd868e0604 100644 --- a/packages/adapter-cloudflare-workers/index.d.ts +++ b/packages/adapter-cloudflare-workers/index.d.ts @@ -1,4 +1,8 @@ import { Adapter } from '@sveltejs/kit'; import './ambient.js'; -export default function plugin(options?: { config?: string }): Adapter; +export default function plugin(options?: AdapterOptions): Adapter; + +export interface AdapterOptions { + config?: string; +} diff --git a/packages/adapter-cloudflare-workers/index.js b/packages/adapter-cloudflare-workers/index.js index edc1f52fc2a3..c3bbb78126ea 100644 --- a/packages/adapter-cloudflare-workers/index.js +++ b/packages/adapter-cloudflare-workers/index.js @@ -11,6 +11,7 @@ import { fileURLToPath } from 'node:url'; * site: { * bucket: string; * } + * compatibility_flags?: string[]; * }} WranglerConfig */ @@ -20,7 +21,7 @@ export default function ({ config = 'wrangler.toml' } = {}) { name: '@sveltejs/adapter-cloudflare-workers', async adapt(builder) { - const { main, site } = validate_config(builder, config); + const { main, site, compatibility_flags } = validate_config(builder, config); const files = fileURLToPath(new URL('./files', import.meta.url).href); const tmp = builder.getBuildDirectory('cloudflare-workers-tmp'); @@ -61,6 +62,23 @@ export default function ({ config = 'wrangler.toml' } = {}) { })};\n\nexport const prerendered = new Map(${JSON.stringify(prerendered_entries)});\n` ); + const external = ['__STATIC_CONTENT_MANIFEST', 'cloudflare:*']; + if (compatibility_flags && compatibility_flags.includes('nodejs_compat')) { + external.push( + 'node:assert', + 'node:async_hooks', + 'node:buffer', + 'node:crypto', + 'node:diagnostics_channel', + 'node:events', + 'node:path', + 'node:process', + 'node:stream', + 'node:string_decoder', + 'node:util' + ); + } + await esbuild.build({ platform: 'browser', conditions: ['worker', 'browser'], @@ -69,7 +87,7 @@ export default function ({ config = 'wrangler.toml' } = {}) { entryPoints: [`${tmp}/entry.js`], outfile: main, bundle: true, - external: ['__STATIC_CONTENT_MANIFEST', 'cloudflare:*'], + external, format: 'esm', loader: { '.wasm': 'copy' diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 8223d52927ff..2e9bc47a2968 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -53,6 +53,21 @@ export default function (options = {}) { } }); + const external = [ + 'cloudflare:*', + 'node:assert', + 'node:async_hooks', + 'node:buffer', + 'node:crypto', + 'node:diagnostics_channel', + 'node:events', + 'node:path', + 'node:process', + 'node:stream', + 'node:string_decoder', + 'node:util' + ]; + await esbuild.build({ platform: 'browser', conditions: ['worker', 'browser'], @@ -66,7 +81,7 @@ export default function (options = {}) { loader: { '.wasm': 'copy' }, - external: ['cloudflare:*'] + external }); } };