Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] use the Vite server options in dev mode #2232

Merged
merged 3 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/spotty-ties-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

[feat] use the Vite server options in dev mode
85 changes: 53 additions & 32 deletions packages/kit/src/core/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { print_config_conflicts } from '../config/index.js';
import { create_app } from '../create_app/index.js';
import create_manifest_data from '../create_manifest_data/index.js';
import { getRawBody } from '../node/index.js';
import { get_server } from '../server/index.js';
import { SVELTE_KIT, SVELTE_KIT_ASSETS } from '../constants.js';
import { copy_assets, resolve_entry } from '../utils.js';

Expand Down Expand Up @@ -106,14 +105,17 @@ class Watcher extends EventEmitter {
}
};

/** @type {(req: import("http").IncomingMessage, res: import("http").ServerResponse) => void} */
let handler = (req, res) => {};

this.server = await get_server(this.https, vite_config, (req, res) => handler(req, res));

// don't warn on overriding defaults
const [modified_vite_config] = deep_merge(default_config, vite_config);

const kit_plugin = await create_plugin(this.config, this.dir, this.cwd, () => {
if (!this.manifest) {
throw new Error('Manifest is not available');
}

return this.manifest;
});

/** @type {[any, string[]]} */
const [merged_config, conflicts] = deep_merge(modified_vite_config, {
configFile: false,
Expand All @@ -138,33 +140,22 @@ class Watcher extends EventEmitter {
compilerOptions: {
hydratable: !!this.config.kit.hydrate
}
})
}),
kit_plugin
],
publicDir: this.config.kit.files.assets,
server: {
middlewareMode: true,
hmr: {
...(this.https ? { server: this.server, port: this.port } : {})
}
host: this.host,
https: this.https
},
base: this.config.kit.paths.assets.startsWith('/') ? `${this.config.kit.paths.assets}/` : '/'
});

print_config_conflicts(conflicts, 'kit.vite.');

this.vite = await vite.createServer(merged_config);

const get_manifest = () => {
if (!this.manifest) {
throw new Error('Manifest is not available');
}

return this.manifest;
};

handler = await create_handler(this.vite, this.config, this.dir, this.cwd, get_manifest);

this.server.listen(this.port, this.host || '0.0.0.0');
remove_html_middlewares(this.vite.middlewares);
await this.vite.listen(this.port);
}

update() {
Expand Down Expand Up @@ -211,15 +202,14 @@ class Watcher extends EventEmitter {
}

close() {
if (!this.vite || !this.server || !this.cheapwatch) {
if (!this.vite || !this.cheapwatch) {
throw new Error('Cannot close server before it is initialized');
}

if (this.closed) return;
this.closed = true;

this.vite.close();
this.server.close();
this.cheapwatch.close();
}
}
Expand Down Expand Up @@ -248,13 +238,12 @@ function get_params(array) {
}

/**
* @param {vite.ViteDevServer} vite
* @param {import('types/config').ValidatedConfig} config
* @param {string} dir
* @param {string} cwd
* @param {() => import('types/internal').SSRManifest} get_manifest
*/
async function create_handler(vite, config, dir, cwd, get_manifest) {
async function create_plugin(config, dir, cwd, get_manifest) {
/**
* @type {amp_validator.Validator?}
*/
Expand All @@ -274,11 +263,14 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {
};

/**
* @param {import('http').IncomingMessage} req
* @param {import('http').ServerResponse} res
* @param {vite.ViteDevServer} vite
*/
return (req, res) => {
vite.middlewares(req, res, async () => {
function create_kit_middleware(vite) {
/**
* Use a named function for debugging
* @type {import('connect').NextHandleFunction}
*/
return async function svelteKitMiddleware(req, res) {
try {
if (!req.url || !req.method) throw new Error('Incomplete request');
if (req.url === '/favicon.ico') return not_found(res);
Expand Down Expand Up @@ -490,7 +482,19 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {
res.statusCode = 500;
res.end(e.stack);
}
});
};
}

return {
name: 'vite-plugin-svelte-kit',
/**
* @param {import('vite').ViteDevServer} vite
*/
configureServer(vite) {
return () => {
vite.middlewares.use(create_kit_middleware(vite));
};
}
};
}

Expand All @@ -499,3 +503,20 @@ function not_found(res) {
res.statusCode = 404;
res.end('Not found');
}

/**
* @param {import('connect').Server} server
*/
function remove_html_middlewares(server) {
const html_middlewares = [
'viteIndexHtmlMiddleware',
'vite404Middleware',
'viteSpaFallbackMiddleware'
];
for (let i = server.stack.length - 1; i > 0; i--) {
// @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged
if (html_middlewares.includes(server.stack[i].handle.name)) {
server.stack.splice(i, 1);
}
}
}
37 changes: 34 additions & 3 deletions packages/kit/src/core/preview/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import fs from 'fs';
import { pathToFileURL } from 'url';
import http from 'http';
import https from 'https';
import { join, resolve } from 'path';
import sirv from 'sirv';
import { pathToFileURL } from 'url';
import { getRawBody } from '../node/index.js';
import { join, resolve } from 'path';
import { get_server } from '../server/index.js';
import { __fetch_polyfill } from '../../install-fetch.js';
import { SVELTE_KIT, SVELTE_KIT_ASSETS } from '../constants.js';

Expand Down Expand Up @@ -128,3 +129,33 @@ export async function preview({

return Promise.resolve(server);
}

/**
* @param {boolean} use_https
* @param {import('vite').UserConfig} user_config
* @param {(req: http.IncomingMessage, res: http.ServerResponse) => void} handler
* @returns {Promise<import('net').Server>}
*/
async function get_server(use_https, user_config, handler) {
/** @type {https.ServerOptions} */
const https_options = {};

if (use_https) {
const secure_opts = user_config.server
? /** @type {import('tls').SecureContextOptions} */ (user_config.server.https)
: {};

if (secure_opts.key && secure_opts.cert) {
https_options.key = secure_opts.key.toString();
https_options.cert = secure_opts.cert.toString();
} else {
https_options.key = https_options.cert = (await import('./cert')).createCertificate();
}
}

return Promise.resolve(
use_https
? https.createServer(/** @type {https.ServerOptions} */ (https_options), handler)
: http.createServer(handler)
);
}
32 changes: 0 additions & 32 deletions packages/kit/src/core/server/index.js

This file was deleted.