diff --git a/.changeset/true-places-make.md b/.changeset/true-places-make.md new file mode 100644 index 000000000000..6920f7c4acd6 --- /dev/null +++ b/.changeset/true-places-make.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-cloudflare': major +--- + +breaking: require `nodejs_als` compatibility flag diff --git a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md index 1d5ae3974745..63aa28e0447f 100644 --- a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md +++ b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md @@ -89,6 +89,7 @@ When building for Cloudflare Workers, this adapter expects to find a [Wrangler c "name": "", "main": ".svelte-kit/cloudflare/_worker.js", "compatibility_date": "2025-01-01", + "compatibility_flags": ["nodejs_als"], "assets": { "binding": "ASSETS", "directory": ".svelte-kit/cloudflare", @@ -102,6 +103,8 @@ Please follow the [framework guide](https://developers.cloudflare.com/workers/fr ## Cloudflare Pages +Ensure that you have enabled the `nodejs_als` compatibility flag in your dashboard, or via your Wrangler configuration. + ### Deployment Please follow the [Get Started Guide](https://developers.cloudflare.com/pages/get-started/) for Cloudflare Pages to begin. @@ -120,6 +123,19 @@ You may wish to refer to [Cloudflare's documentation for deploying a SvelteKit s Functions contained in the [`/functions` directory](https://developers.cloudflare.com/pages/functions/routing/) at the project's root will _not_ be included in the deployment. Instead, functions should be implemented as [server endpoints](routing#server) in your SvelteKit app, which is compiled to a [single `_worker.js` file](https://developers.cloudflare.com/pages/functions/advanced-mode/). +## Node compatibility + +SvelteKit uses the [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage) API internally. You need to enable the `nodejs_als` [compatibility flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/), either via the Cloudflare dashboard (if using Pages) or your Wrangler configuration, or your app may break in production. + +```jsonc +/// file: wrangler.jsonc +{ + "compatibility_flags": ["nodejs_als"] +} +``` + +If you app makes use of other Node.js APIs such as `node:path`, enable support via the `nodejs_compat` compatibility flag instead. + ## Runtime APIs The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#parameters) object contains your project's [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform` property, along with [`ctx`](https://developers.cloudflare.com/workers/runtime-apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/cache/), and [`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), meaning that you can access it in hooks and endpoints: @@ -167,17 +183,6 @@ However, they will have no effect on responses dynamically rendered by SvelteKit ## Troubleshooting -### Node.js compatibility - -If you would like to enable [Node.js compatibility](https://developers.cloudflare.com/workers/runtime-apis/nodejs/), you can add the `nodejs_compat` compatibility flag to your Wrangler configuration file: - -```jsonc -/// file: wrangler.jsonc -{ - "compatibility_flags": ["nodejs_compat"] -} -``` - ### Worker size limits When deploying your application, the server generated by SvelteKit is bundled into a single file. Wrangler will fail to publish your worker if it exceeds [the size limits](https://developers.cloudflare.com/workers/platform/limits/#worker-size) after minification. You're unlikely to hit this limit usually, but some large libraries can cause this to happen. In that case, you can try to reduce the size of your worker by only importing such libraries on the client side. See [the FAQ](./faq#How-do-I-use-a-client-side-library-accessing-document-or-window) for more information. diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index fdbdf9a769ed..ebc438c718ad 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -301,6 +301,22 @@ function validate_wrangler_config(config_file = undefined) { validate_worker_settings(wrangler_config); } + const flags = wrangler_config?.compatibility_flags ?? []; + + if (flags.includes('nodejs_compat') && flags.includes('nodejs_als')) { + const file = config_file + ? path.relative(process.cwd(), config_file) + : 'your wrangler configuration'; + + throw new Error( + `\u001B\u001B[31m` + + `\nPlease add the "nodejs_als" compatibility flag to ${file}, as SvelteKit uses the AsyncLocalStorage API and your app may break in production without it.\n\n` + + `Alternatively, if you are using Node APIs in your app, you should add the "nodejs_compat" flag.\n\n` + + `For more information on compatibility flags see https://svelte.dev/docs/kit/adapter-cloudflare#Node-compatibility.\n` + + `\u001B[39m\u001B` + ); + } + return wrangler_config; } diff --git a/packages/adapter-cloudflare/test/apps/pages/wrangler.jsonc b/packages/adapter-cloudflare/test/apps/pages/wrangler.jsonc new file mode 100644 index 000000000000..4f9e4671c786 --- /dev/null +++ b/packages/adapter-cloudflare/test/apps/pages/wrangler.jsonc @@ -0,0 +1,3 @@ +{ + "compatibility_flags": ["nodejs_als"] +} diff --git a/packages/adapter-cloudflare/test/apps/workers/wrangler.jsonc b/packages/adapter-cloudflare/test/apps/workers/wrangler.jsonc new file mode 100644 index 000000000000..4f9e4671c786 --- /dev/null +++ b/packages/adapter-cloudflare/test/apps/workers/wrangler.jsonc @@ -0,0 +1,3 @@ +{ + "compatibility_flags": ["nodejs_als"] +}