Skip to content

Commit

Permalink
wip: migrate from connect to polka
Browse files Browse the repository at this point in the history
Migrates from connect to polka, a much lighter and faster middleware
server/router.

Marked as WIP until we figure out what to do about fallback middleware.
  • Loading branch information
43081j committed Jul 29, 2024
1 parent 952bae3 commit a573156
Show file tree
Hide file tree
Showing 20 changed files with 397 additions and 486 deletions.
344 changes: 72 additions & 272 deletions packages/vite/LICENSE.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
"artichokie": "^0.2.1",
"cac": "^6.7.14",
"chokidar": "^3.6.0",
"connect": "^3.7.0",
"polka": "^0.5.2",
"convert-source-map": "^2.0.0",
"cors": "^2.8.5",
"cross-spawn": "^7.0.3",
Expand Down
30 changes: 15 additions & 15 deletions packages/vite/src/node/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import fsp from 'node:fs/promises'
import path from 'node:path'
import type { OutgoingHttpHeaders as HttpServerHeaders } from 'node:http'
import type { ServerOptions as HttpsServerOptions } from 'node:https'
import type { Connect } from 'dep-types/connect'
import colors from 'picocolors'
import type { Polka } from 'dep-types/polka'
import type { ProxyOptions } from './server/middlewares/proxy'
import type { Logger } from './logger'
import type { HttpServer } from './server'
Expand Down Expand Up @@ -89,31 +89,26 @@ export type CorsOrigin = boolean | string | RegExp | (string | RegExp)[]

export async function resolveHttpServer(
{ proxy }: CommonServerOptions,
app: Connect.Server,
httpsOptions?: HttpsServerOptions,
): Promise<HttpServer> {
if (!httpsOptions) {
const { createServer } = await import('node:http')
return createServer(app)
return createServer()
}

// #484 fallback to http1 when proxy is needed.
if (proxy) {
const { createServer } = await import('node:https')
return createServer(httpsOptions, app)
return createServer(httpsOptions)
} else {
const { createSecureServer } = await import('node:http2')
return createSecureServer(
{
// Manually increase the session memory to prevent 502 ENHANCE_YOUR_CALM
// errors on large numbers of requests
maxSessionMemory: 1000,
...httpsOptions,
allowHTTP1: true,
},
// @ts-expect-error TODO: is this correct?
app,
)
return createSecureServer({
// Manually increase the session memory to prevent 502 ENHANCE_YOUR_CALM
// errors on large numbers of requests
maxSessionMemory: 1000,
...httpsOptions,
allowHTTP1: true,
})
}
}

Expand All @@ -140,6 +135,7 @@ async function readFileIfExists(value?: string | Buffer | any[]) {

export async function httpServerStart(
httpServer: HttpServer,
middlewares: Polka.Polka | undefined,
serverOptions: {
port: number
strictPort: boolean | undefined
Expand Down Expand Up @@ -167,6 +163,10 @@ export async function httpServerStart(

httpServer.on('error', onError)

if (middlewares) {
httpServer.on('request', middlewares.handler)
}

httpServer.listen(port, host, () => {
httpServer.removeListener('error', onError)
resolve(port)
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export type {
ResolverObject,
Alias,
} from 'dep-types/alias'
export type { Connect } from 'dep-types/connect'
export type { Polka } from 'dep-types/polka'
export type { WebSocket, WebSocketAlias } from 'dep-types/ws'
export type { HttpProxy } from 'dep-types/http-proxy'
export type {
Expand Down
11 changes: 5 additions & 6 deletions packages/vite/src/node/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import fs from 'node:fs'
import path from 'node:path'
import sirv from 'sirv'
import compression from '@polka/compression'
import connect from 'connect'
import type { Connect } from 'dep-types/connect'
import polka from 'polka'
import type { Polka } from 'dep-types/polka'
import corsMiddleware from 'cors'
import { DEFAULT_PREVIEW_PORT } from './constants'
import type {
Expand Down Expand Up @@ -78,7 +78,7 @@ export interface PreviewServer {
*
* https://github.com/senchalabs/connect#use-middleware
*/
middlewares: Connect.Server
middlewares: Polka.Polka
/**
* native Node http server instance
*/
Expand Down Expand Up @@ -132,12 +132,11 @@ export async function preview(
)
}

const app = connect() as Connect.Server
const httpServer = await resolveHttpServer(
config.preview,
app,
await resolveHttpsConfig(config.preview?.https),
)
const app = polka({ server: httpServer })
setClientErrorHandler(httpServer, config.logger)

const options = config.preview
Expand Down Expand Up @@ -242,7 +241,7 @@ export async function preview(
const hostname = await resolveHostname(options.host)
const port = options.port ?? DEFAULT_PREVIEW_PORT

await httpServerStart(httpServer, {
await httpServerStart(httpServer, app, {
port,
strictPort: options.strictPort,
host: hostname.host,
Expand Down
17 changes: 9 additions & 8 deletions packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { get as httpsGet } from 'node:https'
import type * as http from 'node:http'
import { performance } from 'node:perf_hooks'
import type { Http2SecureServer } from 'node:http2'
import connect from 'connect'
import polka from 'polka'
import corsMiddleware from 'cors'
import colors from 'picocolors'
import chokidar from 'chokidar'
import type { FSWatcher, WatchOptions } from 'dep-types/chokidar'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import launchEditorMiddleware from 'launch-editor-middleware'
import type { SourceMap } from 'rollup'
import picomatch from 'picomatch'
Expand Down Expand Up @@ -236,7 +236,7 @@ export interface ViteDevServer {
*
* https://github.com/senchalabs/connect#use-middleware
*/
middlewares: Connect.Server
middlewares: Polka.Polka
/**
* native Node http server instance
* will be null in middleware mode
Expand Down Expand Up @@ -460,10 +460,10 @@ export async function _createServer(
emptyOutDir,
)

const middlewares = connect() as Connect.Server
const httpServer = middlewareMode
? null
: await resolveHttpServer(serverConfig, middlewares, httpsOptions)
: await resolveHttpServer(serverConfig, httpsOptions)
const middlewares = polka({ server: httpServer }) as Polka.Polka

const ws = createWebSocketServer(httpServer, config, httpsOptions)
const hot = createHMRBroadcaster()
Expand Down Expand Up @@ -920,7 +920,7 @@ export async function _createServer(
}

// error handler
middlewares.use(errorMiddleware(server, !!middlewareMode))
middlewares.onError = errorMiddleware(server, !!middlewareMode)

// httpServer.listen can be called multiple times
// when port when using next port number
Expand Down Expand Up @@ -978,6 +978,7 @@ async function startServer(
}

const options = server.config.server
const middlewares = server.middlewares
const hostname = await resolveHostname(options.host)
const configPort = inlinePort ?? options.port
// When using non strict port for the dev server, the running port can be different from the config one.
Expand All @@ -989,7 +990,7 @@ async function startServer(
: configPort) ?? DEFAULT_DEV_PORT
server._configServerPort = configPort

const serverPort = await httpServerStart(httpServer, {
const serverPort = await httpServerStart(httpServer, middlewares, {
port,
strictPort: options.strictPort,
host: hostname.host,
Expand Down Expand Up @@ -1151,7 +1152,7 @@ async function restartServer(server: ViteDevServer) {

// Keep the same connect instance so app.use(vite.middlewares) works
// after a restart in middlewareMode (.route is always '/')
middlewares.stack = newServer.middlewares.stack
middlewares.wares = newServer.middlewares.wares
server.middlewares = middlewares

// Rebind internal server variable so functions reference the user server
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import { joinUrlSegments, stripBase } from '../../utils'
import { cleanUrl, withTrailingSlash } from '../../../shared/utils'

Expand All @@ -7,7 +7,7 @@ import { cleanUrl, withTrailingSlash } from '../../../shared/utils'
export function baseMiddleware(
rawBase: string,
middlewareMode: boolean,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteBaseMiddleware(req, res, next) {
const url = req.url!
Expand Down
6 changes: 3 additions & 3 deletions packages/vite/src/node/server/middlewares/error.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path'
import colors from 'picocolors'
import type { RollupError } from 'rollup'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import strip from 'strip-ansi'
import type { ErrorPayload } from 'types/hmrPayload'
import { pad } from '../../utils'
Expand Down Expand Up @@ -62,7 +62,7 @@ export function logError(server: ViteDevServer, err: RollupError): void {
export function errorMiddleware(
server: ViteDevServer,
allowNext = false,
): Connect.ErrorHandleFunction {
): Polka.ErrorHandler {
// note the 4 args must be kept for connect to treat this as error middleware
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteErrorMiddleware(err: RollupError, _req, res, next) {
Expand Down Expand Up @@ -104,5 +104,5 @@ export function errorMiddleware(
</html>
`)
}
}
} as Polka.ErrorHandler
}
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/htmlFallback.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'node:path'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import { createDebugger } from '../../utils'
import type { FsUtils } from '../../fsUtils'
import { commonFsUtils } from '../../fsUtils'
Expand All @@ -11,7 +11,7 @@ export function htmlFallbackMiddleware(
root: string,
spaFallback: boolean,
fsUtils: FsUtils = commonFsUtils,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteHtmlFallbackMiddleware(req, res, next) {
if (
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/indexHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fsp from 'node:fs/promises'
import path from 'node:path'
import MagicString from 'magic-string'
import type { SourceMapInput } from 'rollup'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import type { DefaultTreeAdapterMap, Token } from 'parse5'
import type { IndexHtmlTransformHook } from '../../plugins/html'
import {
Expand Down Expand Up @@ -407,7 +407,7 @@ const devHtmlHook: IndexHtmlTransformHook = async (
export function indexHtmlMiddleware(
root: string,
server: ViteDevServer | PreviewServer,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
const isDev = isDevServer(server)
const fsUtils = getFsUtils(server.config)

Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/notFound.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'

export function notFoundMiddleware(): Connect.NextHandleFunction {
export function notFoundMiddleware(): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function vite404Middleware(_, res) {
res.statusCode = 404
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type * as http from 'node:http'
import type * as net from 'node:net'
import httpProxy from 'http-proxy'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import type { HttpProxy } from 'dep-types/http-proxy'
import colors from 'picocolors'
import { createDebugger } from '../../utils'
Expand Down Expand Up @@ -71,7 +71,7 @@ export function proxyMiddleware(
httpServer: HttpServer | null,
options: NonNullable<CommonServerOptions['proxy']>,
config: ResolvedConfig,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
// lazy require only when proxy is used
const proxies: Record<string, [HttpProxy.Server, ProxyOptions]> = {}

Expand Down
10 changes: 5 additions & 5 deletions packages/vite/src/node/server/middlewares/static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from 'node:path'
import type { OutgoingHttpHeaders, ServerResponse } from 'node:http'
import type { Options } from 'sirv'
import sirv from 'sirv'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import escapeHtml from 'escape-html'
import type { ViteDevServer } from '../..'
import { FS_PREFIX } from '../../constants'
Expand Down Expand Up @@ -57,7 +57,7 @@ const sirvOptions = ({
export function servePublicMiddleware(
server: ViteDevServer,
publicFiles?: Set<string>,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
const dir = server.config.publicDir
const serve = sirv(
dir,
Expand Down Expand Up @@ -96,7 +96,7 @@ export function servePublicMiddleware(

export function serveStaticMiddleware(
server: ViteDevServer,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
const dir = server.config.root
const serve = sirv(
dir,
Expand Down Expand Up @@ -165,7 +165,7 @@ export function serveStaticMiddleware(

export function serveRawFsMiddleware(
server: ViteDevServer,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
const serveFromRoot = sirv(
'/',
sirvOptions({ getHeaders: () => server.config.server.headers }),
Expand Down Expand Up @@ -233,7 +233,7 @@ function ensureServingAccess(
url: string,
server: ViteDevServer,
res: ServerResponse,
next: Connect.NextFunction,
next: Polka.Next,
): boolean {
if (isFileServingAllowed(url, server)) {
return true
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/server/middlewares/time.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { performance } from 'node:perf_hooks'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import { createDebugger, prettifyUrl, timeFrom } from '../../utils'

const logTime = createDebugger('vite:time')

export function timeMiddleware(root: string): Connect.NextHandleFunction {
export function timeMiddleware(root: string): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteTimeMiddleware(req, res, next) {
const start = performance.now()
Expand Down
6 changes: 3 additions & 3 deletions packages/vite/src/node/server/middlewares/transform.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path'
import fsp from 'node:fs/promises'
import type { Connect } from 'dep-types/connect'
import type { Polka } from 'dep-types/polka'
import colors from 'picocolors'
import type { ExistingRawSourceMap } from 'rollup'
import type { ViteDevServer } from '..'
Expand Down Expand Up @@ -45,7 +45,7 @@ const knownIgnoreList = new Set(['/', '/favicon.ico'])
*/
export function cachedTransformMiddleware(
server: ViteDevServer,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteCachedTransformMiddleware(req, res, next) {
// check if we can return 304 early
Expand All @@ -71,7 +71,7 @@ export function cachedTransformMiddleware(

export function transformMiddleware(
server: ViteDevServer,
): Connect.NextHandleFunction {
): Polka.RequestHandler {
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`

// check if public dir is inside root dir
Expand Down
Loading

0 comments on commit a573156

Please sign in to comment.