diff --git a/.changeset/gentle-boats-rush.md b/.changeset/gentle-boats-rush.md new file mode 100644 index 000000000000..b65ccf0a3f1b --- /dev/null +++ b/.changeset/gentle-boats-rush.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/adapter-cloudflare-workers': minor +'@sveltejs/adapter-cloudflare': minor +--- + +feat: adds an `alias` option to substitute one package for another when bundling such as those provided by Node.js 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 5fc83158606b..1138f32948b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -122,7 +122,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..e73ce89b40bb 100644 --- a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md +++ b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md @@ -23,19 +23,17 @@ import adapter from '@sveltejs/adapter-cloudflare'; export default { kit: { - adapter: adapter({ - // See below for an explanation of these options - routes: { - include: ['/*'], - exclude: [''] - } - }) + adapter: adapter() } }; ``` ## Options +The adapter accepts the options `routes`, `external` and `alias`. + +### `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 +45,64 @@ 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', ...]`. +```js +// @errors: 2307 +/// file: svelte.config.js +import adapter from '@sveltejs/adapter-cloudflare'; + +export default { + kit: { + adapter: adapter({ + // other options here … + routes: { + include: ['/*'], + exclude: [''] + } + }) + } +}; +``` + +### `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`. + +```js +// @errors: 2307 +/// file: svelte.config.js +import adapter from '@sveltejs/adapter-cloudflare'; + +export default { + kit: { + adapter: adapter({ + // other options here … + external: [ 'fs' ] + }) + } +}; +``` + +### `alias` + +`alias` is equivalent to the respective [_alias_ option of esbuild](https://esbuild.github.io/api/#alias). You can use it to substitute one package for another when bundling. + +```js +// @errors: 2307 +/// file: svelte.config.js +import adapter from '@sveltejs/adapter-cloudflare'; + +export default { + kit: { + adapter: adapter({ + // other options here … + alias: { + fs: './fs-stub.js' + } + }) + } +}; +``` + ## 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 48d1335c206e..31f782d12520 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 the options `config`, `external` and `alias`. ```js // @errors: 2307 @@ -72,11 +72,31 @@ import adapter from '@sveltejs/adapter-cloudflare-workers'; export default { kit: { - adapter: adapter({ config: '.toml' }) + adapter: adapter({ + config: '.toml', + external: [ 'fs' ], + alias: { + fs: './fs-stub.js' + } + }) } }; ``` +### 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. + +### `alias` + +`alias` is equivalent to the respective [_alias_ option of esbuild](https://esbuild.github.io/api/#alias). You can use it to substitute one package for another when bundling. + ## 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 8b90611b73c3..aa46d6d8f837 100644 --- a/packages/adapter-cloudflare-workers/index.d.ts +++ b/packages/adapter-cloudflare-workers/index.d.ts @@ -1,4 +1,22 @@ 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[]; + + /** + * Map of packages that should be replaced with a different package. + */ + alias?: { string: 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..ea24b1d6beca 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,12 @@ 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 ?? [])], + alias: options.alias }); builder.log.minor('Copying assets...'); diff --git a/packages/adapter-cloudflare/index.d.ts b/packages/adapter-cloudflare/index.d.ts index e6fb925ff102..414c7b42774b 100644 --- a/packages/adapter-cloudflare/index.d.ts +++ b/packages/adapter-cloudflare/index.d.ts @@ -4,6 +4,16 @@ import './ambient.js'; export default function plugin(options?: AdapterOptions): Adapter; export interface AdapterOptions { + /** + * List of packages that should not be bundled. + */ + external?: string[]; + + /** + * Map of packages that should be replaced with a different package. + */ + alias?: { string: 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 1dd0abd06470..c95b128dde42 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -55,10 +55,11 @@ export default function (options = {}) { allowOverwrite: true, format: 'esm', bundle: true, + alias: options.alias, loader: { '.wasm': 'copy' }, - external: ['cloudflare:*'] + external: ['cloudflare:*', ...(options.external ?? [])] }); } };