vite 2.6.0-beta.0 → 2.6.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vite might be problematic. Click here for more details.
- package/CHANGELOG.md +66 -0
- package/LICENSE.md +161 -3011
- package/bin/vite.js +2 -1
- package/dist/node/chunks/{dep-91aa74e8.js → dep-1e0a75a8.js} +58 -32
- package/dist/node/chunks/dep-1e0a75a8.js.map +1 -0
- package/dist/node/chunks/{dep-e36486f6.js → dep-ac1b4bf9.js} +1 -1
- package/dist/node/chunks/dep-ac1b4bf9.js.map +1 -0
- package/dist/node/chunks/{dep-c7e510f9.js → dep-ba6b30a0.js} +27538 -4953
- package/dist/node/chunks/dep-ba6b30a0.js.map +1 -0
- package/dist/node/chunks/{dep-11213a75.js → dep-c4cf6e92.js} +19 -6
- package/dist/node/chunks/dep-c4cf6e92.js.map +1 -0
- package/dist/node/chunks/{dep-eb6ef720.js → dep-d574094c.js} +18 -5
- package/dist/node/chunks/dep-d574094c.js.map +1 -0
- package/dist/node/chunks/{dep-0d2f9464.js → dep-e39b05d6.js} +18 -5
- package/dist/node/chunks/dep-e39b05d6.js.map +1 -0
- package/dist/node/cli.js +60 -23992
- package/dist/node/cli.js.map +1 -1
- package/dist/node/index.d.ts +26 -8
- package/dist/node/index.js +18 -15
- package/dist/node/index.js.map +1 -1
- package/dist/node/terser.js +102 -55
- package/package.json +28 -13
- package/types/package.json +3 -0
- package/api-extractor.json +0 -54
- package/dist/node/chunks/dep-0d2f9464.js.map +0 -1
- package/dist/node/chunks/dep-11213a75.js.map +0 -1
- package/dist/node/chunks/dep-91aa74e8.js.map +0 -1
- package/dist/node/chunks/dep-c7e510f9.js.map +0 -1
- package/dist/node/chunks/dep-e36486f6.js.map +0 -1
- package/dist/node/chunks/dep-eb6ef720.js.map +0 -1
- package/dist/node/terser.js.map +0 -1
- package/rollup.config.js +0 -389
- package/scripts/patchTypes.js +0 -70
- package/src/node/__tests__/asset.spec.ts +0 -156
- package/src/node/__tests__/build.spec.ts +0 -67
- package/src/node/__tests__/config.spec.ts +0 -166
- package/src/node/__tests__/packages/name/package.json +0 -3
- package/src/node/__tests__/packages/noname/package.json +0 -1
- package/src/node/__tests__/plugins/css.spec.ts +0 -116
- package/src/node/__tests__/scan.spec.ts +0 -118
- package/src/node/__tests__/utils.spec.ts +0 -40
- package/src/node/build.ts +0 -783
- package/src/node/cli.ts +0 -239
- package/src/node/config.ts +0 -1033
- package/src/node/constants.ts +0 -87
- package/src/node/importGlob.ts +0 -173
- package/src/node/index.ts +0 -88
- package/src/node/logger.ts +0 -167
- package/src/node/optimizer/esbuildDepPlugin.ts +0 -216
- package/src/node/optimizer/index.ts +0 -410
- package/src/node/optimizer/registerMissing.ts +0 -102
- package/src/node/optimizer/scan.ts +0 -457
- package/src/node/plugin.ts +0 -138
- package/src/node/plugins/asset.ts +0 -365
- package/src/node/plugins/assetImportMetaUrl.ts +0 -99
- package/src/node/plugins/clientInjections.ts +0 -72
- package/src/node/plugins/css.ts +0 -1279
- package/src/node/plugins/dataUri.ts +0 -64
- package/src/node/plugins/define.ts +0 -107
- package/src/node/plugins/esbuild.ts +0 -280
- package/src/node/plugins/html.ts +0 -673
- package/src/node/plugins/importAnalysis.ts +0 -614
- package/src/node/plugins/importAnalysisBuild.ts +0 -334
- package/src/node/plugins/index.ts +0 -69
- package/src/node/plugins/json.ts +0 -75
- package/src/node/plugins/loadFallback.ts +0 -19
- package/src/node/plugins/manifest.ts +0 -123
- package/src/node/plugins/modulePreloadPolyfill.ts +0 -100
- package/src/node/plugins/preAlias.ts +0 -22
- package/src/node/plugins/reporter.ts +0 -244
- package/src/node/plugins/resolve.ts +0 -925
- package/src/node/plugins/terser.ts +0 -40
- package/src/node/plugins/wasm.ts +0 -72
- package/src/node/plugins/worker.ts +0 -117
- package/src/node/preview.ts +0 -82
- package/src/node/server/__tests__/fixtures/none/nested/package.json +0 -3
- package/src/node/server/__tests__/fixtures/pnpm/nested/package.json +0 -3
- package/src/node/server/__tests__/fixtures/pnpm/package.json +0 -3
- package/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml +0 -0
- package/src/node/server/__tests__/fixtures/yarn/nested/package.json +0 -3
- package/src/node/server/__tests__/fixtures/yarn/package.json +0 -6
- package/src/node/server/__tests__/search-root.spec.ts +0 -31
- package/src/node/server/hmr.ts +0 -489
- package/src/node/server/http.ts +0 -198
- package/src/node/server/index.ts +0 -705
- package/src/node/server/middlewares/base.ts +0 -52
- package/src/node/server/middlewares/error.ts +0 -98
- package/src/node/server/middlewares/indexHtml.ts +0 -170
- package/src/node/server/middlewares/proxy.ts +0 -124
- package/src/node/server/middlewares/spaFallback.ts +0 -32
- package/src/node/server/middlewares/static.ts +0 -153
- package/src/node/server/middlewares/time.ts +0 -18
- package/src/node/server/middlewares/transform.ts +0 -196
- package/src/node/server/moduleGraph.ts +0 -200
- package/src/node/server/openBrowser.ts +0 -101
- package/src/node/server/pluginContainer.ts +0 -546
- package/src/node/server/searchRoot.ts +0 -70
- package/src/node/server/send.ts +0 -54
- package/src/node/server/sourcemap.ts +0 -54
- package/src/node/server/transformRequest.ts +0 -168
- package/src/node/server/ws.ts +0 -131
- package/src/node/ssr/__tests__/ssrTransform.spec.ts +0 -309
- package/src/node/ssr/ssrExternal.ts +0 -161
- package/src/node/ssr/ssrManifestPlugin.ts +0 -53
- package/src/node/ssr/ssrModuleLoader.ts +0 -214
- package/src/node/ssr/ssrStacktrace.ts +0 -75
- package/src/node/ssr/ssrTransform.ts +0 -452
- package/src/node/tsconfig.json +0 -14
- package/src/node/utils.ts +0 -565
- package/tsconfig.base.json +0 -11
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { parse as parseUrl } from 'url'
|
|
2
|
-
import { ViteDevServer } from '..'
|
|
3
|
-
import { Connect } from 'types/connect'
|
|
4
|
-
|
|
5
|
-
// this middleware is only active when (config.base !== '/')
|
|
6
|
-
|
|
7
|
-
export function baseMiddleware({
|
|
8
|
-
config
|
|
9
|
-
}: ViteDevServer): Connect.NextHandleFunction {
|
|
10
|
-
const base = config.base
|
|
11
|
-
|
|
12
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
13
|
-
return function viteBaseMiddleware(req, res, next) {
|
|
14
|
-
const url = req.url!
|
|
15
|
-
const parsed = parseUrl(url)
|
|
16
|
-
const path = parsed.pathname || '/'
|
|
17
|
-
|
|
18
|
-
if (path.startsWith(base)) {
|
|
19
|
-
// rewrite url to remove base.. this ensures that other middleware does
|
|
20
|
-
// not need to consider base being prepended or not
|
|
21
|
-
req.url = url.replace(base, '/')
|
|
22
|
-
return next()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// skip redirect and error fallback on middleware mode, #4057
|
|
26
|
-
if (config.server.middlewareMode) {
|
|
27
|
-
return next()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (path === '/' || path === '/index.html') {
|
|
31
|
-
// redirect root visit to based url
|
|
32
|
-
res.writeHead(302, {
|
|
33
|
-
Location: base
|
|
34
|
-
})
|
|
35
|
-
res.end()
|
|
36
|
-
return
|
|
37
|
-
} else if (req.headers.accept?.includes('text/html')) {
|
|
38
|
-
// non-based page visit
|
|
39
|
-
const redirectPath = base + url.slice(1)
|
|
40
|
-
res.writeHead(404, {
|
|
41
|
-
'Content-Type': 'text/html'
|
|
42
|
-
})
|
|
43
|
-
res.end(
|
|
44
|
-
`The server is configured with a public base URL of ${base} - ` +
|
|
45
|
-
`did you mean to visit <a href="${redirectPath}">${redirectPath}</a> instead?`
|
|
46
|
-
)
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
next()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import { RollupError } from 'rollup'
|
|
3
|
-
import { ViteDevServer } from '../..'
|
|
4
|
-
import { Connect } from 'types/connect'
|
|
5
|
-
import { pad } from '../../utils'
|
|
6
|
-
import strip from 'strip-ansi'
|
|
7
|
-
import { ErrorPayload } from 'types/hmrPayload'
|
|
8
|
-
|
|
9
|
-
export function prepareError(err: Error | RollupError): ErrorPayload['err'] {
|
|
10
|
-
// only copy the information we need and avoid serializing unnecessary
|
|
11
|
-
// properties, since some errors may attach full objects (e.g. PostCSS)
|
|
12
|
-
return {
|
|
13
|
-
message: strip(err.message),
|
|
14
|
-
stack: strip(cleanStack(err.stack || '')),
|
|
15
|
-
id: (err as RollupError).id,
|
|
16
|
-
frame: strip((err as RollupError).frame || ''),
|
|
17
|
-
plugin: (err as RollupError).plugin,
|
|
18
|
-
pluginCode: (err as RollupError).pluginCode,
|
|
19
|
-
loc: (err as RollupError).loc
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function buildErrorMessage(
|
|
24
|
-
err: RollupError,
|
|
25
|
-
args: string[] = [],
|
|
26
|
-
includeStack = true
|
|
27
|
-
): string {
|
|
28
|
-
if (err.plugin) args.push(` Plugin: ${chalk.magenta(err.plugin)}`)
|
|
29
|
-
if (err.id) args.push(` File: ${chalk.cyan(err.id)}`)
|
|
30
|
-
if (err.frame) args.push(chalk.yellow(pad(err.frame)))
|
|
31
|
-
if (includeStack && err.stack) args.push(pad(cleanStack(err.stack)))
|
|
32
|
-
return args.join('\n')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function cleanStack(stack: string) {
|
|
36
|
-
return stack
|
|
37
|
-
.split(/\n/g)
|
|
38
|
-
.filter((l) => /^\s*at/.test(l))
|
|
39
|
-
.join('\n')
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function errorMiddleware(
|
|
43
|
-
server: ViteDevServer,
|
|
44
|
-
allowNext = false
|
|
45
|
-
): Connect.ErrorHandleFunction {
|
|
46
|
-
// note the 4 args must be kept for connect to treat this as error middleware
|
|
47
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
48
|
-
return function viteErrorMiddleware(err: RollupError, _req, res, next) {
|
|
49
|
-
const msg = buildErrorMessage(err, [
|
|
50
|
-
chalk.red(`Internal server error: ${err.message}`)
|
|
51
|
-
])
|
|
52
|
-
|
|
53
|
-
server.config.logger.error(msg, {
|
|
54
|
-
clear: true,
|
|
55
|
-
timestamp: true,
|
|
56
|
-
error: err
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
server.ws.send({
|
|
60
|
-
type: 'error',
|
|
61
|
-
err: prepareError(err)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
if (allowNext) {
|
|
65
|
-
next()
|
|
66
|
-
} else {
|
|
67
|
-
if (err instanceof AccessRestrictedError) {
|
|
68
|
-
res.statusCode = 403
|
|
69
|
-
res.write(renderErrorHTML(err.message))
|
|
70
|
-
res.end()
|
|
71
|
-
}
|
|
72
|
-
res.statusCode = 500
|
|
73
|
-
res.end()
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export class AccessRestrictedError extends Error {
|
|
79
|
-
constructor(msg: string) {
|
|
80
|
-
super(msg)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function renderErrorHTML(msg: string): string {
|
|
85
|
-
// to have syntax highlighting and autocompletion in IDE
|
|
86
|
-
const html = String.raw
|
|
87
|
-
return html`
|
|
88
|
-
<body>
|
|
89
|
-
<h1>403 Restricted</h1>
|
|
90
|
-
<p>${msg.replace(/\n/g, '<br/>')}</p>
|
|
91
|
-
<style>
|
|
92
|
-
body {
|
|
93
|
-
padding: 1em 2em;
|
|
94
|
-
}
|
|
95
|
-
</style>
|
|
96
|
-
</body>
|
|
97
|
-
`
|
|
98
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import MagicString from 'magic-string'
|
|
4
|
-
import { AttributeNode, NodeTypes } from '@vue/compiler-dom'
|
|
5
|
-
import { Connect } from 'types/connect'
|
|
6
|
-
import {
|
|
7
|
-
applyHtmlTransforms,
|
|
8
|
-
getScriptInfo,
|
|
9
|
-
IndexHtmlTransformHook,
|
|
10
|
-
resolveHtmlTransforms,
|
|
11
|
-
traverseHtml
|
|
12
|
-
} from '../../plugins/html'
|
|
13
|
-
import { ResolvedConfig, ViteDevServer } from '../..'
|
|
14
|
-
import { send } from '../send'
|
|
15
|
-
import { CLIENT_PUBLIC_PATH, FS_PREFIX } from '../../constants'
|
|
16
|
-
import { cleanUrl, fsPathFromId } from '../../utils'
|
|
17
|
-
import { assetAttrsConfig } from '../../plugins/html'
|
|
18
|
-
|
|
19
|
-
export function createDevHtmlTransformFn(
|
|
20
|
-
server: ViteDevServer
|
|
21
|
-
): (url: string, html: string, originalUrl: string) => Promise<string> {
|
|
22
|
-
const [preHooks, postHooks] = resolveHtmlTransforms(server.config.plugins)
|
|
23
|
-
|
|
24
|
-
return (url: string, html: string, originalUrl: string): Promise<string> => {
|
|
25
|
-
return applyHtmlTransforms(html, [...preHooks, devHtmlHook, ...postHooks], {
|
|
26
|
-
path: url,
|
|
27
|
-
filename: getHtmlFilename(url, server),
|
|
28
|
-
server,
|
|
29
|
-
originalUrl
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getHtmlFilename(url: string, server: ViteDevServer) {
|
|
35
|
-
if (url.startsWith(FS_PREFIX)) {
|
|
36
|
-
return fsPathFromId(url)
|
|
37
|
-
} else {
|
|
38
|
-
return path.join(server.config.root, url.slice(1))
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const startsWithSingleSlashRE = /^\/(?!\/)/
|
|
43
|
-
const processNodeUrl = (
|
|
44
|
-
node: AttributeNode,
|
|
45
|
-
s: MagicString,
|
|
46
|
-
config: ResolvedConfig,
|
|
47
|
-
htmlPath: string,
|
|
48
|
-
originalUrl?: string
|
|
49
|
-
) => {
|
|
50
|
-
const url = node.value?.content || ''
|
|
51
|
-
if (startsWithSingleSlashRE.test(url)) {
|
|
52
|
-
// prefix with base
|
|
53
|
-
s.overwrite(
|
|
54
|
-
node.value!.loc.start.offset,
|
|
55
|
-
node.value!.loc.end.offset,
|
|
56
|
-
`"${config.base + url.slice(1)}"`
|
|
57
|
-
)
|
|
58
|
-
} else if (
|
|
59
|
-
url.startsWith('.') &&
|
|
60
|
-
originalUrl &&
|
|
61
|
-
originalUrl !== '/' &&
|
|
62
|
-
htmlPath === '/index.html'
|
|
63
|
-
) {
|
|
64
|
-
// #3230 if some request url (localhost:3000/a/b) return to fallback html, the relative assets
|
|
65
|
-
// path will add `/a/` prefix, it will caused 404.
|
|
66
|
-
// rewrite before `./index.js` -> `localhost:3000/a/index.js`.
|
|
67
|
-
// rewrite after `../index.js` -> `localhost:3000/index.js`.
|
|
68
|
-
s.overwrite(
|
|
69
|
-
node.value!.loc.start.offset,
|
|
70
|
-
node.value!.loc.end.offset,
|
|
71
|
-
`"${path.posix.join(
|
|
72
|
-
path.posix.relative(originalUrl, '/'),
|
|
73
|
-
url.slice(1)
|
|
74
|
-
)}"`
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
const devHtmlHook: IndexHtmlTransformHook = async (
|
|
79
|
-
html,
|
|
80
|
-
{ path: htmlPath, server, originalUrl }
|
|
81
|
-
) => {
|
|
82
|
-
// TODO: solve this design issue
|
|
83
|
-
// Optional chain expressions can return undefined by design
|
|
84
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
|
85
|
-
const config = server?.config!
|
|
86
|
-
const base = config.base || '/'
|
|
87
|
-
|
|
88
|
-
const s = new MagicString(html)
|
|
89
|
-
let scriptModuleIndex = -1
|
|
90
|
-
|
|
91
|
-
await traverseHtml(html, htmlPath, (node) => {
|
|
92
|
-
if (node.type !== NodeTypes.ELEMENT) {
|
|
93
|
-
return
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// script tags
|
|
97
|
-
if (node.tag === 'script') {
|
|
98
|
-
const { src, isModule } = getScriptInfo(node)
|
|
99
|
-
if (isModule) {
|
|
100
|
-
scriptModuleIndex++
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (src) {
|
|
104
|
-
processNodeUrl(src, s, config, htmlPath, originalUrl)
|
|
105
|
-
} else if (isModule) {
|
|
106
|
-
// inline js module. convert to src="proxy"
|
|
107
|
-
s.overwrite(
|
|
108
|
-
node.loc.start.offset,
|
|
109
|
-
node.loc.end.offset,
|
|
110
|
-
`<script type="module" src="${
|
|
111
|
-
config.base + htmlPath.slice(1)
|
|
112
|
-
}?html-proxy&index=${scriptModuleIndex}.js"></script>`
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// elements with [href/src] attrs
|
|
118
|
-
const assetAttrs = assetAttrsConfig[node.tag]
|
|
119
|
-
if (assetAttrs) {
|
|
120
|
-
for (const p of node.props) {
|
|
121
|
-
if (
|
|
122
|
-
p.type === NodeTypes.ATTRIBUTE &&
|
|
123
|
-
p.value &&
|
|
124
|
-
assetAttrs.includes(p.name)
|
|
125
|
-
) {
|
|
126
|
-
processNodeUrl(p, s, config, htmlPath, originalUrl)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
html = s.toString()
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
html,
|
|
136
|
-
tags: [
|
|
137
|
-
{
|
|
138
|
-
tag: 'script',
|
|
139
|
-
attrs: {
|
|
140
|
-
type: 'module',
|
|
141
|
-
src: path.posix.join(base, CLIENT_PUBLIC_PATH)
|
|
142
|
-
},
|
|
143
|
-
injectTo: 'head-prepend'
|
|
144
|
-
}
|
|
145
|
-
]
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function indexHtmlMiddleware(
|
|
150
|
-
server: ViteDevServer
|
|
151
|
-
): Connect.NextHandleFunction {
|
|
152
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
153
|
-
return async function viteIndexHtmlMiddleware(req, res, next) {
|
|
154
|
-
const url = req.url && cleanUrl(req.url)
|
|
155
|
-
// spa-fallback always redirects to /index.html
|
|
156
|
-
if (url?.endsWith('.html') && req.headers['sec-fetch-dest'] !== 'script') {
|
|
157
|
-
const filename = getHtmlFilename(url, server)
|
|
158
|
-
if (fs.existsSync(filename)) {
|
|
159
|
-
try {
|
|
160
|
-
let html = fs.readFileSync(filename, 'utf-8')
|
|
161
|
-
html = await server.transformIndexHtml(url, html, req.originalUrl)
|
|
162
|
-
return send(req, res, html, 'html')
|
|
163
|
-
} catch (e) {
|
|
164
|
-
return next(e)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
next()
|
|
169
|
-
}
|
|
170
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import * as http from 'http'
|
|
2
|
-
import { createDebugger, isObject } from '../../utils'
|
|
3
|
-
import httpProxy from 'http-proxy'
|
|
4
|
-
import { HMR_HEADER } from '../ws'
|
|
5
|
-
import { Connect } from 'types/connect'
|
|
6
|
-
import { HttpProxy } from 'types/http-proxy'
|
|
7
|
-
import chalk from 'chalk'
|
|
8
|
-
import { ResolvedConfig } from '../..'
|
|
9
|
-
|
|
10
|
-
const debug = createDebugger('vite:proxy')
|
|
11
|
-
|
|
12
|
-
export interface ProxyOptions extends HttpProxy.ServerOptions {
|
|
13
|
-
/**
|
|
14
|
-
* rewrite path
|
|
15
|
-
*/
|
|
16
|
-
rewrite?: (path: string) => string
|
|
17
|
-
/**
|
|
18
|
-
* configure the proxy server (e.g. listen to events)
|
|
19
|
-
*/
|
|
20
|
-
configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void
|
|
21
|
-
/**
|
|
22
|
-
* webpack-dev-server style bypass function
|
|
23
|
-
*/
|
|
24
|
-
bypass?: (
|
|
25
|
-
req: http.IncomingMessage,
|
|
26
|
-
res: http.ServerResponse,
|
|
27
|
-
options: ProxyOptions
|
|
28
|
-
) => void | null | undefined | false | string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function proxyMiddleware(
|
|
32
|
-
httpServer: http.Server | null,
|
|
33
|
-
config: ResolvedConfig
|
|
34
|
-
): Connect.NextHandleFunction {
|
|
35
|
-
const options = config.server.proxy!
|
|
36
|
-
|
|
37
|
-
// lazy require only when proxy is used
|
|
38
|
-
const proxies: Record<string, [HttpProxy.Server, ProxyOptions]> = {}
|
|
39
|
-
|
|
40
|
-
Object.keys(options).forEach((context) => {
|
|
41
|
-
let opts = options[context]
|
|
42
|
-
if (typeof opts === 'string') {
|
|
43
|
-
opts = { target: opts, changeOrigin: true } as ProxyOptions
|
|
44
|
-
}
|
|
45
|
-
const proxy = httpProxy.createProxyServer(opts) as HttpProxy.Server
|
|
46
|
-
|
|
47
|
-
proxy.on('error', (err) => {
|
|
48
|
-
config.logger.error(`${chalk.red(`http proxy error:`)}\n${err.stack}`, {
|
|
49
|
-
timestamp: true,
|
|
50
|
-
error: err
|
|
51
|
-
})
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
if (opts.configure) {
|
|
55
|
-
opts.configure(proxy, opts)
|
|
56
|
-
}
|
|
57
|
-
// clone before saving because http-proxy mutates the options
|
|
58
|
-
proxies[context] = [proxy, { ...opts }]
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
if (httpServer) {
|
|
62
|
-
httpServer.on('upgrade', (req, socket, head) => {
|
|
63
|
-
const url = req.url!
|
|
64
|
-
for (const context in proxies) {
|
|
65
|
-
if (doesProxyContextMatchUrl(context, url)) {
|
|
66
|
-
const [proxy, opts] = proxies[context]
|
|
67
|
-
if (
|
|
68
|
-
(opts.ws || opts.target?.toString().startsWith('ws:')) &&
|
|
69
|
-
req.headers['sec-websocket-protocol'] !== HMR_HEADER
|
|
70
|
-
) {
|
|
71
|
-
if (opts.rewrite) {
|
|
72
|
-
req.url = opts.rewrite(url)
|
|
73
|
-
}
|
|
74
|
-
debug(`${req.url} -> ws ${opts.target}`)
|
|
75
|
-
proxy.ws(req, socket, head)
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
84
|
-
return function viteProxyMiddleware(req, res, next) {
|
|
85
|
-
const url = req.url!
|
|
86
|
-
for (const context in proxies) {
|
|
87
|
-
if (doesProxyContextMatchUrl(context, url)) {
|
|
88
|
-
const [proxy, opts] = proxies[context]
|
|
89
|
-
const options: HttpProxy.ServerOptions = {}
|
|
90
|
-
|
|
91
|
-
if (opts.bypass) {
|
|
92
|
-
const bypassResult = opts.bypass(req, res, opts)
|
|
93
|
-
if (typeof bypassResult === 'string') {
|
|
94
|
-
req.url = bypassResult
|
|
95
|
-
debug(`bypass: ${req.url} -> ${bypassResult}`)
|
|
96
|
-
return next()
|
|
97
|
-
} else if (isObject(bypassResult)) {
|
|
98
|
-
Object.assign(options, bypassResult)
|
|
99
|
-
debug(`bypass: ${req.url} use modified options: %O`, options)
|
|
100
|
-
return next()
|
|
101
|
-
} else if (bypassResult === false) {
|
|
102
|
-
debug(`bypass: ${req.url} -> 404`)
|
|
103
|
-
return res.end(404)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
debug(`${req.url} -> ${opts.target || opts.forward}`)
|
|
108
|
-
if (opts.rewrite) {
|
|
109
|
-
req.url = opts.rewrite(req.url!)
|
|
110
|
-
}
|
|
111
|
-
proxy.web(req, res, options)
|
|
112
|
-
return
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
next()
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function doesProxyContextMatchUrl(context: string, url: string): boolean {
|
|
120
|
-
return (
|
|
121
|
-
(context.startsWith('^') && new RegExp(context).test(url)) ||
|
|
122
|
-
url.startsWith(context)
|
|
123
|
-
)
|
|
124
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import history from 'connect-history-api-fallback'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import { Connect } from 'types/connect'
|
|
5
|
-
import { createDebugger } from '../../utils'
|
|
6
|
-
|
|
7
|
-
export function spaFallbackMiddleware(
|
|
8
|
-
root: string
|
|
9
|
-
): Connect.NextHandleFunction {
|
|
10
|
-
const historySpaFallbackMiddleware = history({
|
|
11
|
-
logger: createDebugger('vite:spa-fallback'),
|
|
12
|
-
// support /dir/ without explicit index.html
|
|
13
|
-
rewrites: [
|
|
14
|
-
{
|
|
15
|
-
from: /\/$/,
|
|
16
|
-
to({ parsedUrl }: any) {
|
|
17
|
-
const rewritten = parsedUrl.pathname + 'index.html'
|
|
18
|
-
if (fs.existsSync(path.join(root, rewritten))) {
|
|
19
|
-
return rewritten
|
|
20
|
-
} else {
|
|
21
|
-
return `/index.html`
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
29
|
-
return function viteSpaFallbackMiddleware(req, res, next) {
|
|
30
|
-
return historySpaFallbackMiddleware(req, res, next)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import sirv, { Options } from 'sirv'
|
|
3
|
-
import { Connect } from 'types/connect'
|
|
4
|
-
import { normalizePath, ResolvedConfig, ViteDevServer } from '../..'
|
|
5
|
-
import { FS_PREFIX } from '../../constants'
|
|
6
|
-
import {
|
|
7
|
-
cleanUrl,
|
|
8
|
-
ensureLeadingSlash,
|
|
9
|
-
fsPathFromId,
|
|
10
|
-
isImportRequest,
|
|
11
|
-
isInternalRequest,
|
|
12
|
-
isWindows,
|
|
13
|
-
slash
|
|
14
|
-
} from '../../utils'
|
|
15
|
-
import { AccessRestrictedError } from './error'
|
|
16
|
-
|
|
17
|
-
const sirvOptions: Options = {
|
|
18
|
-
dev: true,
|
|
19
|
-
etag: true,
|
|
20
|
-
extensions: [],
|
|
21
|
-
setHeaders(res, pathname) {
|
|
22
|
-
// Matches js, jsx, ts, tsx.
|
|
23
|
-
// The reason this is done, is that the .ts file extension is reserved
|
|
24
|
-
// for the MIME type video/mp2t. In almost all cases, we can expect
|
|
25
|
-
// these files to be TypeScript files, and for Vite to serve them with
|
|
26
|
-
// this Content-Type.
|
|
27
|
-
if (/\.[tj]sx?$/.test(pathname)) {
|
|
28
|
-
res.setHeader('Content-Type', 'application/javascript')
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function servePublicMiddleware(dir: string): Connect.NextHandleFunction {
|
|
34
|
-
const serve = sirv(dir, sirvOptions)
|
|
35
|
-
|
|
36
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
37
|
-
return function viteServePublicMiddleware(req, res, next) {
|
|
38
|
-
// skip import request and internal requests `/@fs/ /@vite-client` etc...
|
|
39
|
-
if (isImportRequest(req.url!) || isInternalRequest(req.url!)) {
|
|
40
|
-
return next()
|
|
41
|
-
}
|
|
42
|
-
serve(req, res, next)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function serveStaticMiddleware(
|
|
47
|
-
dir: string,
|
|
48
|
-
config: ResolvedConfig
|
|
49
|
-
): Connect.NextHandleFunction {
|
|
50
|
-
const serve = sirv(dir, sirvOptions)
|
|
51
|
-
|
|
52
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
53
|
-
return function viteServeStaticMiddleware(req, res, next) {
|
|
54
|
-
// only serve the file if it's not an html request
|
|
55
|
-
// so that html requests can fallthrough to our html middleware for
|
|
56
|
-
// special processing
|
|
57
|
-
// also skip internal requests `/@fs/ /@vite-client` etc...
|
|
58
|
-
if (
|
|
59
|
-
path.extname(cleanUrl(req.url!)) === '.html' ||
|
|
60
|
-
isInternalRequest(req.url!)
|
|
61
|
-
) {
|
|
62
|
-
return next()
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const url = decodeURI(req.url!)
|
|
66
|
-
|
|
67
|
-
// apply aliases to static requests as well
|
|
68
|
-
let redirected: string | undefined
|
|
69
|
-
for (const { find, replacement } of config.resolve.alias) {
|
|
70
|
-
const matches =
|
|
71
|
-
typeof find === 'string' ? url.startsWith(find) : find.test(url)
|
|
72
|
-
if (matches) {
|
|
73
|
-
redirected = url.replace(find, replacement)
|
|
74
|
-
break
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (redirected) {
|
|
78
|
-
// dir is pre-normalized to posix style
|
|
79
|
-
if (redirected.startsWith(dir)) {
|
|
80
|
-
redirected = redirected.slice(dir.length)
|
|
81
|
-
}
|
|
82
|
-
req.url = redirected
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
serve(req, res, next)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function serveRawFsMiddleware(
|
|
90
|
-
server: ViteDevServer
|
|
91
|
-
): Connect.NextHandleFunction {
|
|
92
|
-
const serveFromRoot = sirv('/', sirvOptions)
|
|
93
|
-
|
|
94
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
95
|
-
return function viteServeRawFsMiddleware(req, res, next) {
|
|
96
|
-
let url = req.url!
|
|
97
|
-
// In some cases (e.g. linked monorepos) files outside of root will
|
|
98
|
-
// reference assets that are also out of served root. In such cases
|
|
99
|
-
// the paths are rewritten to `/@fs/` prefixed paths and must be served by
|
|
100
|
-
// searching based from fs root.
|
|
101
|
-
if (url.startsWith(FS_PREFIX)) {
|
|
102
|
-
// restrict files outside of `fs.allow`
|
|
103
|
-
ensureServingAccess(slash(path.resolve(fsPathFromId(url))), server)
|
|
104
|
-
url = url.slice(FS_PREFIX.length)
|
|
105
|
-
if (isWindows) url = url.replace(/^[A-Z]:/i, '')
|
|
106
|
-
|
|
107
|
-
req.url = url
|
|
108
|
-
serveFromRoot(req, res, next)
|
|
109
|
-
} else {
|
|
110
|
-
next()
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function isFileServingAllowed(
|
|
116
|
-
url: string,
|
|
117
|
-
server: ViteDevServer
|
|
118
|
-
): boolean {
|
|
119
|
-
// explicitly disabled
|
|
120
|
-
if (server.config.server.fs.strict === false) return true
|
|
121
|
-
|
|
122
|
-
const file = ensureLeadingSlash(normalizePath(cleanUrl(url)))
|
|
123
|
-
|
|
124
|
-
if (server.moduleGraph.safeModulesPath.has(file)) return true
|
|
125
|
-
|
|
126
|
-
if (server.config.server.fs.allow.some((i) => file.startsWith(i + '/')))
|
|
127
|
-
return true
|
|
128
|
-
|
|
129
|
-
if (!server.config.server.fs.strict) {
|
|
130
|
-
server.config.logger.warnOnce(`Unrestricted file system access to "${url}"`)
|
|
131
|
-
server.config.logger.warnOnce(
|
|
132
|
-
`For security concerns, accessing files outside of serving allow list will ` +
|
|
133
|
-
`be restricted by default in the future version of Vite. ` +
|
|
134
|
-
`Refer to https://vitejs.dev/config/#server-fs-allow for more details.`
|
|
135
|
-
)
|
|
136
|
-
return true
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return false
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export function ensureServingAccess(url: string, server: ViteDevServer): void {
|
|
143
|
-
if (!isFileServingAllowed(url, server)) {
|
|
144
|
-
const allow = server.config.server.fs.allow
|
|
145
|
-
throw new AccessRestrictedError(
|
|
146
|
-
`The request url "${url}" is outside of Vite serving allow list:
|
|
147
|
-
|
|
148
|
-
${allow.map((i) => `- ${i}`).join('\n')}
|
|
149
|
-
|
|
150
|
-
Refer to docs https://vitejs.dev/config/#server-fs-allow for configurations and more details.`
|
|
151
|
-
)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Connect } from 'types/connect'
|
|
2
|
-
import { createDebugger, prettifyUrl, timeFrom } from '../../utils'
|
|
3
|
-
|
|
4
|
-
const logTime = createDebugger('vite:time')
|
|
5
|
-
|
|
6
|
-
export function timeMiddleware(root: string): Connect.NextHandleFunction {
|
|
7
|
-
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
|
|
8
|
-
return function viteTimeMiddleware(req, res, next) {
|
|
9
|
-
const start = Date.now()
|
|
10
|
-
const end = res.end
|
|
11
|
-
res.end = (...args: any[]) => {
|
|
12
|
-
logTime(`${timeFrom(start)} ${prettifyUrl(req.url!, root)}`)
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
return end.call(res, ...args)
|
|
15
|
-
}
|
|
16
|
-
next()
|
|
17
|
-
}
|
|
18
|
-
}
|