Skip to content

Commit

Permalink
Bundle non-prod dependencies with esbuild (#6372)
Browse files Browse the repository at this point in the history
* bundle non-prod dependencies with esbuild - closes #3176

* changeset

* update README
  • Loading branch information
Rich-Harris committed Aug 29, 2022
1 parent b26329c commit ab663f1
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-trainers-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-node': patch
---

Bundle non-production dependencies with esbuild
4 changes: 3 additions & 1 deletion packages/adapter-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,14 @@ app.listen(3000, () => {

## 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
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 skip this step if your app doesn't have any dependencies). You can then start your app with

```bash
node build
```

Development dependencies will be bundled into your app using `esbuild`. To control whether a given package is bundled or externalised, place it in `devDependencies` or `dependencies` respectively in your `package.json`.

## Changelog

[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-node/CHANGELOG.md).
Expand Down
12 changes: 10 additions & 2 deletions packages/adapter-node/ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
declare module 'SERVER' {
export { Server } from '@sveltejs/kit';
declare module 'ENV' {
export function env(key: string, fallback?: any): string;
}

declare module 'HANDLER' {
export const handler: import('polka').Middleware;
}

declare module 'MANIFEST' {
import { SSRManifest } from '@sveltejs/kit';
export const manifest: SSRManifest;
}

declare module 'SERVER' {
export { Server } from '@sveltejs/kit';
}
50 changes: 36 additions & 14 deletions packages/adapter-node/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { writeFileSync } from 'fs';
import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import * as esbuild from 'esbuild';

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

Expand All @@ -19,33 +20,54 @@ export default function (opts = {}) {
name: '@sveltejs/adapter-node',

async adapt(builder) {
const tmp = builder.getBuildDirectory('adapter-node');

builder.rimraf(out);
builder.rimraf(tmp);
builder.mkdirp(tmp);

builder.log.minor('Copying assets');
builder.writeClient(`${out}/client`);
builder.writeServer(`${out}/server`);
builder.writePrerendered(`${out}/prerendered`);

if (precompress) {
builder.log.minor('Compressing assets');
await builder.compress(`${out}/client`);
await builder.compress(`${out}/prerendered`);
}

builder.log.minor('Building server');

builder.writeServer(tmp);

writeFileSync(
`${out}/manifest.js`,
`export const manifest = ${builder.generateManifest({
relativePath: './server'
})};\n`
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({ relativePath: './' })};`
);

const pkg = JSON.parse(readFileSync('package.json', 'utf8'));

await esbuild.build({
platform: 'node',
sourcemap: 'linked',
target: 'es2022',
entryPoints: [`${tmp}/index.js`, `${tmp}/manifest.js`],
outdir: `${out}/server`,
splitting: true,
format: 'esm',
bundle: true,
external: [...Object.keys(pkg.dependencies || {})]
});

builder.copy(files, out, {
replace: {
SERVER: './server/index.js',
MANIFEST: './manifest.js',
ENV: './env.js',
HANDLER: './handler.js',
MANIFEST: './server/manifest.js',
SERVER: `./server/index.js`,
ENV_PREFIX: JSON.stringify(envPrefix)
}
});

if (precompress) {
builder.log.minor('Compressing assets');
await builder.compress(`${out}/client`);
await builder.compress(`${out}/prerendered`);
}
}
};
}
3 changes: 3 additions & 0 deletions packages/adapter-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,8 @@
"sirv": "^2.0.2",
"typescript": "^4.7.4",
"uvu": "^0.5.3"
},
"dependencies": {
"esbuild": "^0.14.48"
}
}
28 changes: 22 additions & 6 deletions packages/adapter-node/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import { builtinModules } from 'module';

export default [
{
input: {
index: 'src/index.js',
handler: 'src/handler.js',
shims: 'src/shims.js'
input: 'src/index.js',
output: {
file: 'files/index.js',
format: 'esm'
},
plugins: [nodeResolve(), commonjs(), json()],
external: ['ENV', 'HANDLER', ...builtinModules]
},
{
input: 'src/env.js',
output: {
dir: 'files',
file: 'files/env.js',
format: 'esm'
},
plugins: [nodeResolve(), commonjs(), json()],
external: ['SERVER', 'MANIFEST', ...require('module').builtinModules]
external: ['HANDLER', ...builtinModules]
},
{
input: 'src/handler.js',
output: {
file: 'files/handler.js',
format: 'esm',
inlineDynamicImports: true
},
plugins: [nodeResolve(), commonjs(), json()],
external: ['ENV', 'MANIFEST', 'SERVER', ...builtinModules]
}
];
10 changes: 5 additions & 5 deletions packages/adapter-node/src/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
import { getRequest, setResponse } from '@sveltejs/kit/node';
import { Server } from 'SERVER';
import { manifest } from 'MANIFEST';
import { env } from './env.js';
import { env } from 'ENV';

/* global ENV_PREFIX */

Expand All @@ -19,7 +19,7 @@ const address_header = env('ADDRESS_HEADER', '').toLowerCase();
const protocol_header = env('PROTOCOL_HEADER', '').toLowerCase();
const host_header = env('HOST_HEADER', 'host').toLowerCase();

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const dir = path.dirname(fileURLToPath(import.meta.url));

/**
* @param {string} path
Expand Down Expand Up @@ -132,9 +132,9 @@ function get_origin(headers) {

export const handler = sequence(
[
serve(path.join(__dirname, '/client'), true),
serve(path.join(__dirname, '/static')),
serve(path.join(__dirname, '/prerendered')),
serve(path.join(dir, 'client'), true),
serve(path.join(dir, 'static')),
serve(path.join(dir, 'prerendered')),
ssr
].filter(Boolean)
);
4 changes: 2 additions & 2 deletions packages/adapter-node/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { handler } from './handler.js';
import { env } from './env.js';
import { handler } from 'HANDLER';
import { env } from 'ENV';
import polka from 'polka';

export const path = env('SOCKET_PATH', false);
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export interface Builder {
/**
* @param {string} directory Path to the directory containing the files to be compressed
*/
compress(directory: string): void;
compress(directory: string): Promise<void>;
}

export interface Config {
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ab663f1

Please sign in to comment.