diff --git a/.changeset/popular-cats-own.md b/.changeset/popular-cats-own.md new file mode 100644 index 000000000000..cbe8cb043dbb --- /dev/null +++ b/.changeset/popular-cats-own.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/adapter-cloudflare-workers': minor +'@sveltejs/adapter-cloudflare': minor +--- + +feat: adds an `external` option to specify packages that should not be bundled as part of the build such as those provided by Node.js diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b077e088fb94..011aadf3a3bf 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,4 +7,4 @@ - [ ] Run the tests with `pnpm test` and lint the project with `pnpm lint` and `pnpm check` ### Changesets -- [ ] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. Changesets that add features should be `minor` and those that fix bugs should be `patch`. Please prefix changeset messages with `feat:`, `fix:`, or `chore:`. +- [ ] Run `pnpm changeset` for user-visible changes and follow the prompts. Changeset messages should generally be prefixed with `feat:` or `fix:`. PRs can also be prefixed with `chore:` or `docs:`, which typically won't require a changeset as they're not user-visible. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b66bf4733426..c6f97dc1c35a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -114,7 +114,7 @@ git config core.hookspath .githooks ### Generating changelogs -For changes to be reflected in package changelogs, run `pnpm changeset` and follow the prompts. +Run `pnpm changeset` for user-visible changes and follow the prompts. Changeset messages should generally be prefixed with `feat:` or `fix:`. PRs can also be prefixed with `chore:` or `docs:`, which typically won't require a changeset as they're not user-visible. ## Releases 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 92ceff556129..74d46be21b2b 100644 --- a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md +++ b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md @@ -28,7 +28,8 @@ export default { routes: { include: ['/*'], exclude: [''] - } + }, + external: [ 'fs' ] }) } }; @@ -36,6 +37,10 @@ export default { ## Options +The adapter accepts two options: `routes` and `external`. + +### `routes` + The `routes` option allows you to customise the [`_routes.json`](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) file generated by `adapter-cloudflare`. - `include` defines routes that will invoke a function, and defaults to `['/*']` @@ -47,6 +52,10 @@ The `routes` option allows you to customise the [`_routes.json`](https://develop You can have up to 100 `include` and `exclude` rules combined. Generally you can omit the `routes` options, but if (for example) your `` paths exceed that limit, you may find it helpful to manually create an `exclude` list that includes `'/articles/*'` instead of the auto-generated `['/articles/foo', '/articles/bar', '/articles/baz', ...]`. +### `external` + +`external` is equivalent to the respective [_external_ option of esbuild](https://esbuild.github.io/api/#external). You can use it to mark a file or package as external to exclude it from your build. Typically, this can be used for packages that do import _NodeJS_ modules such as `fs`. + ## Deployment Please follow the [Get Started Guide](https://developers.cloudflare.com/pages/get-started) for Cloudflare Pages to begin. 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 b35a2597b828..2a3d6d07126b 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 @@ -61,9 +61,9 @@ Then, you can build your app and deploy it: wrangler publish ``` -## Custom config +## Adapter configuration -If you would like to use a config file other than `wrangler.toml`, you can do like so: +The adapter configuration accepts two options: `config` and `external`. ```js // @errors: 2307 @@ -72,11 +72,24 @@ import adapter from '@sveltejs/adapter-cloudflare-workers'; export default { kit: { - adapter: adapter({ config: '.toml' }) + adapter: adapter({ + config: '.toml', + external: [ 'fs' ] + }) } }; ``` +### Custom config + +If you would like to use a config file other than the default `wrangler.toml`, set `config` to the name of the file. The path is relative to the root of your project. + +### `external` + +`external` is equivalent to the respective [_external_ option of esbuild](https://esbuild.github.io/api/#external). You can use it to mark a file or package as external to exclude it from your build. Typically, this can be used for packages that do import _NodeJS_ modules such as `fs`. + +The values `__STATIC_CONTENT_MANIFEST` and `cloudflare:*` are always in the list of excluded packages and this can't be changed. + ## 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: @@ -120,4 +133,4 @@ When deploying to workers, the server generated by SvelteKit is bundled into a s ### Accessing the file system -You can't access the file system through methods like `fs.readFileSync` in Serverless/Edge environments. If you need to access files that way, do that during building the app through [prerendering](https://kit.svelte.dev/docs/page-options#prerender). If you have a blog for example and don't want to manage your content through a CMS, then you need to prerender the content (or prerender the endpoint from which you get it) and redeploy your blog everytime you add new content. \ No newline at end of file +You can't access the file system through methods like `fs.readFileSync` in Serverless/Edge environments. If you need to access files that way, do that during building the app through [prerendering](https://kit.svelte.dev/docs/page-options#prerender). If you have a blog for example and don't want to manage your content through a CMS, then you need to prerender the content (or prerender the endpoint from which you get it) and redeploy your blog everytime you add new content. diff --git a/packages/adapter-cloudflare-workers/index.d.ts b/packages/adapter-cloudflare-workers/index.d.ts index 8b90611b73c3..49e612a9b198 100644 --- a/packages/adapter-cloudflare-workers/index.d.ts +++ b/packages/adapter-cloudflare-workers/index.d.ts @@ -1,4 +1,17 @@ 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 { + /** + * List of packages that should not be bundled. + */ + external?: string[]; + + /** + * The name of the wrangler config file to use. + * Defaults to `wrangler.toml`. + */ + config?: string; +} diff --git a/packages/adapter-cloudflare-workers/index.js b/packages/adapter-cloudflare-workers/index.js index 6ab595989024..b2f299040040 100644 --- a/packages/adapter-cloudflare-workers/index.js +++ b/packages/adapter-cloudflare-workers/index.js @@ -15,12 +15,12 @@ import { fileURLToPath } from 'node:url'; */ /** @type {import('.').default} */ -export default function ({ config = 'wrangler.toml' } = {}) { +export default function (options = {}) { return { name: '@sveltejs/adapter-cloudflare-workers', async adapt(builder) { - const { main, site } = validate_config(builder, config); + const { main, site } = validate_config(builder, options.config ?? 'wrangler.toml'); const files = fileURLToPath(new URL('./files', import.meta.url).href); const tmp = builder.getBuildDirectory('cloudflare-workers-tmp'); @@ -62,11 +62,11 @@ export default function ({ config = 'wrangler.toml' } = {}) { entryPoints: [`${tmp}/entry.js`], outfile: main, bundle: true, - external: ['__STATIC_CONTENT_MANIFEST', 'cloudflare:*'], format: 'esm', loader: { '.wasm': 'copy' - } + }, + external: ['__STATIC_CONTENT_MANIFEST', 'cloudflare:*', ...(options.external ?? [])] }); builder.log.minor('Copying assets...'); diff --git a/packages/adapter-cloudflare/index.d.ts b/packages/adapter-cloudflare/index.d.ts index e6fb925ff102..c61d47211925 100644 --- a/packages/adapter-cloudflare/index.d.ts +++ b/packages/adapter-cloudflare/index.d.ts @@ -4,6 +4,11 @@ import './ambient.js'; export default function plugin(options?: AdapterOptions): Adapter; export interface AdapterOptions { + /** + * List of packages that should not be bundled. + */ + external?: string[]; + /** * Customize the automatically-generated `_routes.json` file * https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 46e1c2c3800b..db74c26898f4 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -58,7 +58,7 @@ export default function (options = {}) { loader: { '.wasm': 'copy' }, - external: ['cloudflare:*'] + external: ['cloudflare:*', ...(options.external ?? [])] }); } };