From e5e8cd26bab5733f417c5787d1e2519b550f34cd Mon Sep 17 00:00:00 2001 From: stygian-desolator <73412177+stygian-desolator@users.noreply.github.com> Date: Mon, 8 Nov 2021 08:51:54 +0800 Subject: [PATCH] feat(server): support headers configurable --- packages/playground/cli/vite.config.js | 5 +++- .../vite/src/node/__tests__/config.spec.ts | 3 +++ packages/vite/src/node/http.ts | 8 ++++-- packages/vite/src/node/index.ts | 1 + packages/vite/src/node/preview.ts | 3 ++- .../src/node/server/middlewares/indexHtml.ts | 2 +- .../src/node/server/middlewares/transform.ts | 13 ++++++---- packages/vite/src/node/server/send.ts | 26 ++++++++++++++++--- 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/packages/playground/cli/vite.config.js b/packages/playground/cli/vite.config.js index 014aa6d378934b..f7b25d32ecc312 100644 --- a/packages/playground/cli/vite.config.js +++ b/packages/playground/cli/vite.config.js @@ -2,7 +2,10 @@ const { defineConfig } = require('vite') module.exports = defineConfig({ server: { - host: 'localhost' + host: 'localhost', + headers: { + 'Cache-Control': 'no-store' + } }, build: { //speed up build diff --git a/packages/vite/src/node/__tests__/config.spec.ts b/packages/vite/src/node/__tests__/config.spec.ts index b4f55eae089c78..d85dd0f22bbfb7 100644 --- a/packages/vite/src/node/__tests__/config.spec.ts +++ b/packages/vite/src/node/__tests__/config.spec.ts @@ -172,6 +172,9 @@ describe('preview config', () => { host: true, open: true, https: true, + headers: { + 'Cache-Control': 'no-store' + }, proxy: { '/foo': 'http://localhost:4567' }, cors: false }) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 406a8f100481bf..2d1df9e7cd592f 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -1,6 +1,6 @@ import fs, { promises as fsp } from 'fs' import path from 'path' -import { Server as HttpServer } from 'http' +import { OutgoingHttpHeaders as HttpServerHeaders, Server as HttpServer } from 'http' import { ServerOptions as HttpsServerOptions } from 'https' import { isObject } from './utils' import { ProxyOptions } from './server/middlewares/proxy' @@ -61,7 +61,11 @@ export interface CommonServerOptions { * Set to `true` to allow all methods from any origin, or configure separately * using an object. */ - cors?: CorsOptions | boolean + cors?: CorsOptions | boolean, + /** + * Specify server response headers. + */ + headers?: HttpServerHeaders } /** diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index 5b92990f83a221..8bd088b68eb6f2 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -66,6 +66,7 @@ export type { ResolveOptions, InternalResolveOptions } from './plugins/resolve' export type { WebSocketServer } from './server/ws' export type { PluginContainer } from './server/pluginContainer' export type { ModuleGraph, ModuleNode, ResolvedUrl } from './server/moduleGraph' +export type { SendOptions } from './server/send'; export type { ProxyOptions } from './server/middlewares/proxy' export type { TransformOptions, diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index 20a37b9abbee0b..57948dca326b0b 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -36,7 +36,8 @@ export function resolvePreviewOptions( https: preview?.https ?? server.https, open: preview?.open ?? server.open, proxy: preview?.proxy ?? server.proxy, - cors: preview?.cors ?? server.cors + cors: preview?.cors ?? server.cors, + headers: preview?.headers ?? server.headers } } diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index a5f46ab31f4e00..7521097994e39d 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -180,7 +180,7 @@ export function indexHtmlMiddleware( try { let html = fs.readFileSync(filename, 'utf-8') html = await server.transformIndexHtml(url, html, req.originalUrl) - return send(req, res, html, 'html') + return send(req, res, html, 'html', { headers: server.config.server.headers }) } catch (e) { return next(e) } diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index a68308f391e363..626e46e6d6f65b 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -108,7 +108,7 @@ export function transformMiddleware( const map = (await moduleGraph.getModuleByUrl(originalUrl)) ?.transformResult?.map if (map) { - return send(req, res, JSON.stringify(map), 'json') + return send(req, res, JSON.stringify(map), 'json', { headers: server.config.server.headers }) } else { return next() } @@ -180,10 +180,13 @@ export function transformMiddleware( res, result.code, type, - result.etag, - // allow browser to cache npm deps! - isDep ? 'max-age=31536000,immutable' : 'no-cache', - result.map + { + etag: result.etag, + // allow browser to cache npm deps! + cacheControl: isDep ? 'max-age=31536000,immutable' : 'no-cache', + headers: server.config.server.headers, + map: result.map + } ) } } diff --git a/packages/vite/src/node/server/send.ts b/packages/vite/src/node/server/send.ts index 777e91abf9438c..5350dbd3bfcc92 100644 --- a/packages/vite/src/node/server/send.ts +++ b/packages/vite/src/node/server/send.ts @@ -1,4 +1,4 @@ -import { IncomingMessage, ServerResponse } from 'http' +import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from 'http' import getEtag from 'etag' import { SourceMap } from 'rollup' @@ -11,15 +11,27 @@ const alias: Record = { json: 'application/json' } +export interface SendOptions { + etag?: string, + cacheControl?: string, + headers?: OutgoingHttpHeaders, + map?: SourceMap | null +} + export function send( req: IncomingMessage, res: ServerResponse, content: string | Buffer, type: string, - etag = getEtag(content, { weak: true }), - cacheControl = 'no-cache', - map?: SourceMap | null + options: SendOptions ): void { + const { + etag = getEtag(content, { weak: true }), + cacheControl = 'no-cache', + headers, + map + } = options + if (res.writableEnded) { return } @@ -33,6 +45,12 @@ export function send( res.setHeader('Cache-Control', cacheControl) res.setHeader('Etag', etag) + if (headers) { + for (const name in headers) { + res.setHeader(name, headers[name]!) + } + } + // inject source map reference if (map && map.mappings) { if (isDebug) {