From e69957978782e1fed82d5cf0f6d07b7af73de442 Mon Sep 17 00:00:00 2001 From: GrygrFlzr Date: Mon, 19 Jul 2021 03:28:59 +0700 Subject: [PATCH] feat(adapters): expose esbuild configuration (#1914) --- .changeset/dull-numbers-hunt.md | 8 ++++ packages/adapter-cloudflare-workers/README.md | 33 ++++++++++++++++- packages/adapter-cloudflare-workers/index.js | 17 +++++++-- packages/adapter-netlify/README.md | 31 ++++++++++++++++ packages/adapter-netlify/index.js | 15 +++++++- packages/adapter-node/README.md | 37 +++++++++++++++++++ packages/adapter-node/index.js | 21 ++++++++--- packages/adapter-vercel/README.md | 31 ++++++++++++++++ packages/adapter-vercel/index.js | 15 +++++++- 9 files changed, 194 insertions(+), 14 deletions(-) create mode 100644 .changeset/dull-numbers-hunt.md diff --git a/.changeset/dull-numbers-hunt.md b/.changeset/dull-numbers-hunt.md new file mode 100644 index 000000000000..b8b34803ef1c --- /dev/null +++ b/.changeset/dull-numbers-hunt.md @@ -0,0 +1,8 @@ +--- +'@sveltejs/adapter-cloudflare-workers': patch +'@sveltejs/adapter-netlify': patch +'@sveltejs/adapter-node': patch +'@sveltejs/adapter-vercel': patch +--- + +feat(adapters): expose esbuild configuration diff --git a/packages/adapter-cloudflare-workers/README.md b/packages/adapter-cloudflare-workers/README.md index a121b1ec70dc..f1b3a6c3b741 100644 --- a/packages/adapter-cloudflare-workers/README.md +++ b/packages/adapter-cloudflare-workers/README.md @@ -4,7 +4,7 @@ SvelteKit adapter that creates a Cloudflare Workers site using a function for dy This is very experimental; the adapter API isn't at all fleshed out, and things will definitely change. -## Configuration +## Basic Configuration This adapter expects to find a [wrangler.toml](https://developers.cloudflare.com/workers/platform/sites/configuration) file in the project root. It will determine where to write static assets and the worker based on the `site.bucket` and `site.entry-point` settings. @@ -26,6 +26,37 @@ It's recommended that you add the `build` and `workers-site` folders (or whichev More info on configuring a cloudflare worker site can be found [here](https://developers.cloudflare.com/workers/platform/sites/start-from-existing) +## Advanced Configuration + +### esbuild + +As an escape hatch, you may optionally specify a function which will receive the final esbuild options generated by this adapter and returns a modified esbuild configuration. The result of this function will be passed as-is to esbuild. The function can be async. + +For example, you may wish to add a plugin: + +```js +adapterCfw({ + esbuild(defaultOptions) { + return { + ...defaultOptions, + plugins: [] + }; + } +}); +``` + +The default options for this version are as follows: + +```js +{ + entryPoints: ['.svelte-kit/cloudflare-workers/entry.js'], + outfile: `${entrypoint}/index.js`, + bundle: true, + target: 'es2020', + platform: 'browser' +} +``` + ## Changelog [The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-cloudflare-workers/CHANGELOG.md). diff --git a/packages/adapter-cloudflare-workers/index.js b/packages/adapter-cloudflare-workers/index.js index 856d162d3f27..a10711110ebb 100644 --- a/packages/adapter-cloudflare-workers/index.js +++ b/packages/adapter-cloudflare-workers/index.js @@ -4,7 +4,16 @@ import esbuild from 'esbuild'; import toml from '@iarna/toml'; import { fileURLToPath } from 'url'; -export default function () { +/** + * @typedef {import('esbuild').BuildOptions} BuildOptions + */ + +/** + * @param {{ + * esbuild?: (defaultOptions: BuildOptions) => Promise | BuildOptions; + * }} options + **/ +export default function (options = { esbuild: (opts) => opts }) { /** @type {import('@sveltejs/kit').Adapter} */ const adapter = { name: '@sveltejs/adapter-cloudflare-workers', @@ -29,14 +38,16 @@ export default function () { utils.log.minor('Generating worker...'); utils.copy(`${files}/entry.js`, '.svelte-kit/cloudflare-workers/entry.js'); - await esbuild.build({ + const buildOptions = await options.esbuild({ entryPoints: ['.svelte-kit/cloudflare-workers/entry.js'], outfile: `${entrypoint}/index.js`, bundle: true, target: 'es2020', - platform: 'node' // TODO would be great if we could generate ESM and use type = "javascript" + platform: 'browser' // TODO would be great if we could generate ESM and use type = "javascript" }); + await esbuild.build(buildOptions); + fs.writeFileSync(`${entrypoint}/package.json`, JSON.stringify({ main: 'index.js' })); utils.log.info('Prerendering static pages...'); diff --git a/packages/adapter-netlify/README.md b/packages/adapter-netlify/README.md index 15a5e05710cc..e44ff45839ee 100644 --- a/packages/adapter-netlify/README.md +++ b/packages/adapter-netlify/README.md @@ -53,6 +53,37 @@ During compilation a required "catch all" redirect rule is automatically appende 2. Netlify's build bot parses your HTML files at deploy time, which means your form must be [prerendered](https://kit.svelte.dev/docs#ssr-and-javascript-prerender) as HTML. You can either add `export const prerender = true` to your `contact.svelte` to prerender just that page or set the `kit.prerender.force: true` option to prerender all pages. 3. If your Netlify form has a [custom success message](https://docs.netlify.com/forms/setup/#success-messages) like `
` then ensure the corresponding `/routes/success.svelte` exists and is prerendered. +## Advanced Configuration + +### esbuild + +As an escape hatch, you may optionally specify a function which will receive the final esbuild options generated by this adapter and returns a modified esbuild configuration. The result of this function will be passed as-is to esbuild. The function can be async. + +For example, you may wish to add a plugin: + +```js +adapterNetlify({ + esbuild(defaultOptions) { + return { + ...defaultOptions, + plugins: [] + }; + } +}); +``` + +The default options for this version are as follows: + +```js +{ + entryPoints: ['.svelte-kit/netlify/entry.js'], + outfile: `pathToFunctionsFolder/render/index.js`, + bundle: true, + inject: ['pathTo/shims.js'], + platform: 'node' +} +``` + ## Changelog [The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-netlify/CHANGELOG.md). diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js index fe2f48a6f64c..3b310ac2ac05 100644 --- a/packages/adapter-netlify/index.js +++ b/packages/adapter-netlify/index.js @@ -4,7 +4,16 @@ import { fileURLToPath } from 'url'; import esbuild from 'esbuild'; import toml from '@iarna/toml'; -export default function () { +/** + * @typedef {import('esbuild').BuildOptions} BuildOptions + */ + +/** + * @param {{ + * esbuild?: (defaultOptions: BuildOptions) => Promise | BuildOptions; + * }} options + **/ +export default function (options = { esbuild: (opts) => opts }) { /** @type {import('@sveltejs/kit').Adapter} */ const adapter = { name: '@sveltejs/adapter-netlify', @@ -20,7 +29,7 @@ export default function () { utils.log.minor('Generating serverless function...'); utils.copy(join(files, 'entry.js'), '.svelte-kit/netlify/entry.js'); - await esbuild.build({ + const buildOptions = await options.esbuild({ entryPoints: ['.svelte-kit/netlify/entry.js'], outfile: join(functions, 'render/index.js'), bundle: true, @@ -28,6 +37,8 @@ export default function () { platform: 'node' }); + await esbuild.build(buildOptions); + writeFileSync(join(functions, 'package.json'), JSON.stringify({ type: 'commonjs' })); utils.log.info('Prerendering static pages...'); diff --git a/packages/adapter-node/README.md b/packages/adapter-node/README.md index 2f09dc2646e0..1b90a76740f0 100644 --- a/packages/adapter-node/README.md +++ b/packages/adapter-node/README.md @@ -45,6 +45,43 @@ HOST=127.0.0.1 PORT=4000 node build You can specify different environment variables if necessary using the `env` option. +## Advanced Configuration + +### esbuild + +As an escape hatch, you may optionally specify a function which will receive the final esbuild options generated by this adapter and returns a modified esbuild configuration. The result of this function will be passed as-is to esbuild. The function can be async. + +For example, you may wish to add a plugin: + +```js +adapterNode({ + esbuild(defaultOptions) { + return { + ...defaultOptions, + plugins: [] + }; + } +}); +``` + +The default options for this version are as follows: + +```js +{ + entryPoints: ['.svelte-kit/node/index.js'], + outfile: 'pathTo/index.js', + bundle: true, + external: allProductionDependencies, // from package.json + format: 'esm', + platform: 'node', + target: 'node12', + inject: ['pathTo/shims.js'], + define: { + esbuild_app_dir: `"${config.kit.appDir}"` + } +} +``` + ## Changelog [The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-node/CHANGELOG.md). diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 5640e6804986..d5573751746d 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -16,6 +16,10 @@ import zlib from 'zlib'; const pipe = promisify(pipeline); +/** + * @typedef {import('esbuild').BuildOptions} BuildOptions + */ + /** * @param {{ * out?: string; @@ -24,13 +28,17 @@ const pipe = promisify(pipeline); * host?: string; * port?: string; * }; + * esbuild?: (defaultOptions: BuildOptions) => Promise | BuildOptions; * }} options */ -export default function ({ - out = 'build', - precompress, - env: { host: host_env = 'HOST', port: port_env = 'PORT' } = {} -} = {}) { +export default function ( + { + out = 'build', + precompress, + env: { host: host_env = 'HOST', port: port_env = 'PORT' } = {}, + esbuild: esbuildConfig + } = { esbuild: (opts) => opts } +) { /** @type {import('@sveltejs/kit').Adapter} */ const adapter = { name: '@sveltejs/adapter-node', @@ -55,7 +63,7 @@ export default function ({ host_env )}] || '0.0.0.0';\nexport const port = process.env[${JSON.stringify(port_env)}] || 3000;` ); - await esbuild.build({ + const buildOptions = await esbuildConfig({ entryPoints: ['.svelte-kit/node/index.js'], outfile: join(out, 'index.js'), bundle: true, @@ -68,6 +76,7 @@ export default function ({ esbuild_app_dir: '"' + config.kit.appDir + '"' } }); + await esbuild.build(buildOptions); utils.log.minor('Prerendering static pages'); await utils.prerender({ diff --git a/packages/adapter-vercel/README.md b/packages/adapter-vercel/README.md index 9fba0c62666f..fd980fb0d390 100644 --- a/packages/adapter-vercel/README.md +++ b/packages/adapter-vercel/README.md @@ -19,6 +19,37 @@ export default { }; ``` +## Advanced Configuration + +### esbuild + +As an escape hatch, you may optionally specify a function which will receive the final esbuild options generated by this adapter and returns a modified esbuild configuration. The result of this function will be passed as-is to esbuild. The function can be async. + +For example, you may wish to add a plugin: + +```js +adapterVercel({ + esbuild(defaultOptions) { + return { + ...defaultOptions, + plugins: [] + }; + } +}); +``` + +The default options for this version are as follows: + +```js +{ + entryPoints: ['.svelte-kit/vercel/entry.js'], + outfile: `pathToLambdaFolder/index.js`, + bundle: true, + inject: ['pathTo/shims.js'], + platform: 'node' +} +``` + ## Changelog [The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-vercel/CHANGELOG.md). diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index aef613d2f895..e8faed339854 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -3,7 +3,16 @@ import { join } from 'path'; import { fileURLToPath } from 'url'; import esbuild from 'esbuild'; -export default function () { +/** + * @typedef {import('esbuild').BuildOptions} BuildOptions + */ + +/** + * @param {{ + * esbuild?: (defaultOptions: BuildOptions) => Promise | BuildOptions; + * }} options + **/ +export default function (options = { esbuild: (opts) => opts }) { /** @type {import('@sveltejs/kit').Adapter} */ const adapter = { name: '@sveltejs/adapter-vercel', @@ -27,7 +36,7 @@ export default function () { utils.log.minor('Generating serverless function...'); utils.copy(join(files, 'entry.js'), '.svelte-kit/vercel/entry.js'); - await esbuild.build({ + const buildOptions = await options.esbuild({ entryPoints: ['.svelte-kit/vercel/entry.js'], outfile: join(dirs.lambda, 'index.js'), bundle: true, @@ -35,6 +44,8 @@ export default function () { platform: 'node' }); + await esbuild.build(buildOptions); + writeFileSync(join(dirs.lambda, 'package.json'), JSON.stringify({ type: 'commonjs' })); utils.log.minor('Prerendering static pages...');