Skip to content

Commit

Permalink
[breaking] do a single bundling with Vite removing esbuild
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Nov 24, 2021
1 parent c75dcde commit 91790ff
Show file tree
Hide file tree
Showing 37 changed files with 194 additions and 316 deletions.
10 changes: 10 additions & 0 deletions .changeset/tidy-pets-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@sveltejs/adapter-cloudflare': patch
'@sveltejs/adapter-cloudflare-workers': patch
'@sveltejs/adapter-netlify': patch
'@sveltejs/adapter-node': patch
'@sveltejs/adapter-vercel': patch
'@sveltejs/kit': patch
---

[breaking] do a single bundling with Vite making esbuild optional
1 change: 1 addition & 0 deletions documentation/docs/10-adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default function (options) {
/** @type {import('@sveltejs/kit').Adapter} */
return {
name: 'adapter-package-name',
serverEntryPoint: 'adapter-package-name/entry',
async adapt({ utils, config }) {
// adapter implementation
}
Expand Down
5 changes: 5 additions & 0 deletions documentation/docs/14-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const config = {
onError: 'fail'
},
router: true,
serverEntryPoint: null,
serviceWorker: {
files: (filepath) => !/\.DS_STORE/.test(filepath)
},
Expand Down Expand Up @@ -195,6 +196,10 @@ See [Prerendering](#ssr-and-javascript-prerender). An object containing zero or

Enables or disables the client-side [router](#ssr-and-javascript-router) app-wide.

### serverEntryPoint

A file path to a custom entry point for the server. Passed to `vite.build.rollupOptions.input`. See [the Rollup docs](https://rollupjs.org/guide/en/#input) for more info.

### serviceWorker

An object containing zero or more of the following values:
Expand Down
38 changes: 38 additions & 0 deletions documentation/docs/80-adapter-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Writing an Adapter
---

We recommend [looking at the source for an adapter](https://github.com/sveltejs/kit/tree/master/packages) to a platform similar to yours and copying it as a starting point.

Adapters packages must implement the following API, which creates an `Adapter`:

```js
/** @param {AdapterSpecificOptions} options */
export default function (options) {
/** @type {import('@sveltejs/kit').Adapter} */
return {
name: 'adapter-package-name',
serverEntryPoint: 'adapter-package-name/entry',
async adapt({ utils, config }) {
// adapter implementation
}
};
}
```

The types for `Adapter` and its parameters are available in [types/config.d.ts](https://github.com/sveltejs/kit/blob/master/packages/kit/types/config.d.ts).

Within the `adapt` method, there are a number of things that an adapter should do:

- Clear out the build directory
- Output code that:
- Calls `init`
- Converts from the platform's request to a [SvelteKit request](#hooks-handle), calls `render`, and converts from a [SvelteKit response](#hooks-handle) to the platform's
- Globally shims `fetch` to work on the target platform. SvelteKit provides a `@sveltejs/kit/install-fetch` helper for platforms that can use `node-fetch`
- Bundle the output to avoid needing to install dependencies on the target platform, if desired
- Call `utils.prerender`
- Put the user's static files and the generated JS/CSS in the correct location for the target platform

If possible, we recommend putting the adapter output under the `build/` directory with any intermediate output placed under `'.svelte-kit/' + adapterName`.

> The adapter API may change before 1.0.
4 changes: 2 additions & 2 deletions examples/hn.svelte.dev/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import netlify from '@sveltejs/adapter-netlify';
import adapter from '@sveltejs/adapter-netlify';

export default {
kit: {
adapter: netlify(),
adapter: adapter(),
target: '#svelte'
}
};
5 changes: 3 additions & 2 deletions packages/adapter-cloudflare-workers/files/entry.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// TODO hardcoding the relative location makes this brittle
import { init, render } from '../output/server/app.js';
// $server-build doesn't exist until the app is built
// @ts-expect-error
import { init, render } from '$server-build';
import { getAssetFromKV, NotFoundError } from '@cloudflare/kv-asset-handler';

init();
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-cloudflare-workers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { fileURLToPath } from 'url';
export default function (options) {
return {
name: '@sveltejs/adapter-cloudflare-workers',
serverEntryPoint: '@sveltejs/adapter-cloudflare-workers/entry',

async adapt({ utils }) {
const { site } = validate_config(utils);
Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare-workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
".": {
"import": "./index.js"
},
"./entry": {
"import": "./files/entry.js"
},
"./package.json": "./package.json"
},
"main": "index.js",
Expand Down
4 changes: 3 additions & 1 deletion packages/adapter-cloudflare/files/worker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* global ASSETS */
import { init, render } from '../output/server/app.js';
// $server-build doesn't exist until the app is built
// @ts-expect-error
import { init, render } from '$server-build';

init();

Expand Down
1 change: 1 addition & 0 deletions packages/adapter-cloudflare/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as esbuild from 'esbuild';
export default function (options = {}) {
return {
name: '@sveltejs/adapter-cloudflare',
serverEntryPoint: '@sveltejs/adapter-cloudflare/entry',
async adapt({ utils, config }) {
const files = fileURLToPath(new URL('./files', import.meta.url));
const target_dir = join(process.cwd(), '.svelte-kit', 'cloudflare');
Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
".": {
"import": "./index.js"
},
"./entry": {
"import": "./files/worker.js"
},
"./package.json": "./package.json"
},
"types": "index.d.ts",
Expand Down
32 changes: 0 additions & 32 deletions packages/adapter-netlify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,38 +66,6 @@ During compilation a required "catch all" redirect rule is automatically appende
node_bundler = "esbuild"
```

## 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'],
// This is Netlify's internal functions directory, not the one for user functions.
outfile: '.netlify/functions-internal/__render.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).
6 changes: 4 additions & 2 deletions packages/adapter-netlify/files/entry.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// TODO hardcoding the relative location makes this brittle
import { init, render } from '../output/server/app.js';
import '@sveltejs/kit/install-fetch';
// $server-build doesn't exist until the app is built
// @ts-expect-error
import { init, render } from '$server-build';

init();

Expand Down
1 change: 0 additions & 1 deletion packages/adapter-netlify/files/shims.js

This file was deleted.

34 changes: 5 additions & 29 deletions packages/adapter-netlify/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { appendFileSync, existsSync, readFileSync, writeFileSync } from 'fs';
import { appendFileSync, existsSync, readFileSync } from 'fs';
import { join, resolve } from 'path';
import { fileURLToPath } from 'url';
import esbuild from 'esbuild';
import toml from '@iarna/toml';

/**
* @typedef {import('esbuild').BuildOptions} BuildOptions
*/

/** @type {import('.')} */
export default function (options) {
export default function () {
return {
name: '@sveltejs/adapter-netlify',
serverEntryPoint: '@sveltejs/adapter-netlify/entry',

async adapt({ utils }) {
// "build" is the default publish directory when Netlify detects SvelteKit
Expand All @@ -21,28 +16,9 @@ export default function (options) {

utils.rimraf(publish);

const files = fileURLToPath(new URL('./files', import.meta.url));

utils.log.minor('Generating serverless function...');
utils.copy(join(files, 'entry.js'), '.svelte-kit/netlify/entry.js');

/** @type {BuildOptions} */
const default_options = {
entryPoints: ['.svelte-kit/netlify/entry.js'],
// Any functions in ".netlify/functions-internal" are bundled in addition to user-defined Netlify functions.
// See https://github.com/netlify/build/pull/3213 for more details
outfile: '.netlify/functions-internal/__render.js',
bundle: true,
inject: [join(files, 'shims.js')],
platform: 'node'
};

const build_options =
options && options.esbuild ? await options.esbuild(default_options) : default_options;

await esbuild.build(build_options);

writeFileSync(join('.netlify', 'package.json'), JSON.stringify({ type: 'commonjs' }));
utils.copy('.svelte-kit/output/server/index.js', '.netlify/functions-internal/__render.js');
utils.copy('.svelte-kit/output/server/chunks', '.netlify/functions-internal/chunks');

utils.log.minor('Prerendering static pages...');
await utils.prerender({
Expand Down
6 changes: 4 additions & 2 deletions packages/adapter-netlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
".": {
"import": "./index.js"
},
"./entry": {
"import": "./files/entry.js"
},
"./package.json": "./package.json"
},
"main": "index.js",
Expand All @@ -26,8 +29,7 @@
"check-format": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore"
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"esbuild": "^0.13.4"
"@iarna/toml": "^2.2.5"
},
"devDependencies": {
"@sveltejs/kit": "workspace:*"
Expand Down
68 changes: 7 additions & 61 deletions packages/adapter-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,13 @@ export default {
adapter: adapter({
// default options are shown
out: 'build',
precompress: false,
env: {
host: 'HOST',
port: 'PORT'
}
precompress: false
})
}
};
```

## Options

### entryPoint

The server entry point. Allows you to provide a [custom server implementation](#middleware). Defaults to the provided reference server.
## Build Options

### out

Expand All @@ -39,32 +31,23 @@ The directory to build the server to. It defaults to `build` — i.e. `node buil

Enables precompressing using gzip and brotli for assets and prerendered pages. It defaults to `false`.

### env
## Runtime Options

### Environment variables

By default, the server will accept connections on `0.0.0.0` using port 3000. These can be customised with the `PORT` and `HOST` environment variables:

```
HOST=127.0.0.1 PORT=4000 node build
```

You can specify different environment variables if necessary using the `env` option:

```js
env: {
host: 'MY_HOST_VARIABLE',
port: 'MY_PORT_VARIABLE'
}
```

```
MY_HOST_VARIABLE=127.0.0.1 MY_PORT_VARIABLE=4000 node build
```
You can also specify `SOCKET_PATH` if you'd like to use a Unix domain socket or Windows named pipe.

## Middleware

The adapter exports a middleware `(req, res, next) => {}` that's compatible with [Express](https://github.com/expressjs/expressjs.com) / [Connect](https://github.com/senchalabs/connect) / [Polka](https://github.com/lukeed/polka). Additionally, it also exports a reference server implementation using this middleware with a plain Node HTTP server.

But you can use your favorite server framework to combine it with other middleware and server logic. You can import `kitMiddleware`, your ready-to-use SvelteKit middleware from the `build` directory. You can use [the `entryPoint` option](#entryPoint) to bundle your custom server entry point.
But you can use your favorite server framework to combine it with other middleware and server logic. You can import `kitMiddleware`, your ready-to-use SvelteKit middleware from the `build` directory. You can use [the `serverEntryPoint` option](https://kit.svelte.dev/docs#configuration-serverentrypoint) to bundle your custom server entry point.

```js
// src/server.js
Expand Down Expand Up @@ -94,43 +77,6 @@ app.listen(3000);

For using middleware in dev mode, [see the FAQ](https://kit.svelte.dev/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-middleware).

## 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: 'node14',
inject: ['pathTo/shims.js'],
define: {
esbuild_app_dir: `"${config.kit.appDir}"`
}
}
```

## Deploying

You will need the output directory (`build` by default), the project's `package.json`, and the production dependencies in `node_modules` to run the application. Production dependencies can be generated with `npm ci --prod`, you can also skip this step if your app doesn't have any dependencies. You can then start your app with
Expand Down
Loading

0 comments on commit 91790ff

Please sign in to comment.