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,365 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import { parse as parseUrl } from 'url'
|
|
3
|
-
import fs, { promises as fsp } from 'fs'
|
|
4
|
-
import mime from 'mime/lite'
|
|
5
|
-
import { Plugin } from '../plugin'
|
|
6
|
-
import { ResolvedConfig } from '../config'
|
|
7
|
-
import { cleanUrl } from '../utils'
|
|
8
|
-
import { FS_PREFIX } from '../constants'
|
|
9
|
-
import { OutputOptions, PluginContext, RenderedChunk } from 'rollup'
|
|
10
|
-
import MagicString from 'magic-string'
|
|
11
|
-
import { createHash } from 'crypto'
|
|
12
|
-
import { normalizePath } from '../utils'
|
|
13
|
-
|
|
14
|
-
export const assetUrlRE = /__VITE_ASSET__([a-z\d]{8})__(?:\$_(.*?)__)?/g
|
|
15
|
-
|
|
16
|
-
// urls in JS must be quoted as strings, so when replacing them we need
|
|
17
|
-
// a different regex
|
|
18
|
-
const assetUrlQuotedRE = /"__VITE_ASSET__([a-z\d]{8})__(?:\$_(.*?)__)?"/g
|
|
19
|
-
|
|
20
|
-
const rawRE = /(\?|&)raw(?:&|$)/
|
|
21
|
-
const urlRE = /(\?|&)url(?:&|$)/
|
|
22
|
-
|
|
23
|
-
export const chunkToEmittedAssetsMap = new WeakMap<RenderedChunk, Set<string>>()
|
|
24
|
-
|
|
25
|
-
const assetCache = new WeakMap<ResolvedConfig, Map<string, string>>()
|
|
26
|
-
|
|
27
|
-
const assetHashToFilenameMap = new WeakMap<
|
|
28
|
-
ResolvedConfig,
|
|
29
|
-
Map<string, string>
|
|
30
|
-
>()
|
|
31
|
-
// save hashes of the files that has been emitted in build watch
|
|
32
|
-
const emittedHashMap = new WeakMap<ResolvedConfig, Set<string>>()
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Also supports loading plain strings with import text from './foo.txt?raw'
|
|
36
|
-
*/
|
|
37
|
-
export function assetPlugin(config: ResolvedConfig): Plugin {
|
|
38
|
-
// assetHashToFilenameMap initialization in buildStart causes getAssetFilename to return undefined
|
|
39
|
-
assetHashToFilenameMap.set(config, new Map())
|
|
40
|
-
return {
|
|
41
|
-
name: 'vite:asset',
|
|
42
|
-
|
|
43
|
-
buildStart() {
|
|
44
|
-
assetCache.set(config, new Map())
|
|
45
|
-
emittedHashMap.set(config, new Set())
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
resolveId(id) {
|
|
49
|
-
if (!config.assetsInclude(cleanUrl(id))) {
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
// imports to absolute urls pointing to files in /public
|
|
53
|
-
// will fail to resolve in the main resolver. handle them here.
|
|
54
|
-
const publicFile = checkPublicFile(id, config)
|
|
55
|
-
if (publicFile) {
|
|
56
|
-
return id
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
async load(id) {
|
|
61
|
-
if (id.startsWith('\0')) {
|
|
62
|
-
// Rollup convention, this id should be handled by the
|
|
63
|
-
// plugin that marked it with \0
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// raw requests, read from disk
|
|
68
|
-
if (rawRE.test(id)) {
|
|
69
|
-
const file = checkPublicFile(id, config) || cleanUrl(id)
|
|
70
|
-
// raw query, read file and return as string
|
|
71
|
-
return `export default ${JSON.stringify(
|
|
72
|
-
await fsp.readFile(file, 'utf-8')
|
|
73
|
-
)}`
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!config.assetsInclude(cleanUrl(id)) && !urlRE.test(id)) {
|
|
77
|
-
return
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
id = id.replace(urlRE, '$1').replace(/[\?&]$/, '')
|
|
81
|
-
const url = await fileToUrl(id, config, this)
|
|
82
|
-
return `export default ${JSON.stringify(url)}`
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
renderChunk(code, chunk) {
|
|
86
|
-
let match: RegExpExecArray | null
|
|
87
|
-
let s: MagicString | undefined
|
|
88
|
-
while ((match = assetUrlQuotedRE.exec(code))) {
|
|
89
|
-
s = s || (s = new MagicString(code))
|
|
90
|
-
const [full, hash, postfix = ''] = match
|
|
91
|
-
// some internal plugins may still need to emit chunks (e.g. worker) so
|
|
92
|
-
// fallback to this.getFileName for that.
|
|
93
|
-
const file = getAssetFilename(hash, config) || this.getFileName(hash)
|
|
94
|
-
registerAssetToChunk(chunk, file)
|
|
95
|
-
const outputFilepath = config.base + file + postfix
|
|
96
|
-
s.overwrite(
|
|
97
|
-
match.index,
|
|
98
|
-
match.index + full.length,
|
|
99
|
-
JSON.stringify(outputFilepath)
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
if (s) {
|
|
103
|
-
return {
|
|
104
|
-
code: s.toString(),
|
|
105
|
-
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
return null
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
generateBundle(_, bundle) {
|
|
113
|
-
// do not emit assets for SSR build
|
|
114
|
-
if (config.command === 'build' && config.build.ssr) {
|
|
115
|
-
for (const file in bundle) {
|
|
116
|
-
if (
|
|
117
|
-
bundle[file].type === 'asset' &&
|
|
118
|
-
!file.includes('ssr-manifest.json')
|
|
119
|
-
) {
|
|
120
|
-
delete bundle[file]
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function registerAssetToChunk(chunk: RenderedChunk, file: string): void {
|
|
129
|
-
let emitted = chunkToEmittedAssetsMap.get(chunk)
|
|
130
|
-
if (!emitted) {
|
|
131
|
-
emitted = new Set()
|
|
132
|
-
chunkToEmittedAssetsMap.set(chunk, emitted)
|
|
133
|
-
}
|
|
134
|
-
emitted.add(cleanUrl(file))
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function checkPublicFile(
|
|
138
|
-
url: string,
|
|
139
|
-
{ publicDir }: ResolvedConfig
|
|
140
|
-
): string | undefined {
|
|
141
|
-
// note if the file is in /public, the resolver would have returned it
|
|
142
|
-
// as-is so it's not going to be a fully resolved path.
|
|
143
|
-
if (!publicDir || !url.startsWith('/')) {
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
const publicFile = path.join(publicDir, cleanUrl(url))
|
|
147
|
-
if (fs.existsSync(publicFile)) {
|
|
148
|
-
return publicFile
|
|
149
|
-
} else {
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export function fileToUrl(
|
|
155
|
-
id: string,
|
|
156
|
-
config: ResolvedConfig,
|
|
157
|
-
ctx: PluginContext
|
|
158
|
-
): string | Promise<string> {
|
|
159
|
-
if (config.command === 'serve') {
|
|
160
|
-
return fileToDevUrl(id, config)
|
|
161
|
-
} else {
|
|
162
|
-
return fileToBuiltUrl(id, config, ctx)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function fileToDevUrl(id: string, config: ResolvedConfig) {
|
|
167
|
-
let rtn: string
|
|
168
|
-
if (checkPublicFile(id, config)) {
|
|
169
|
-
// in public dir, keep the url as-is
|
|
170
|
-
rtn = id
|
|
171
|
-
} else if (id.startsWith(config.root)) {
|
|
172
|
-
// in project root, infer short public path
|
|
173
|
-
rtn = '/' + path.posix.relative(config.root, id)
|
|
174
|
-
} else {
|
|
175
|
-
// outside of project root, use absolute fs path
|
|
176
|
-
// (this is special handled by the serve static middleware
|
|
177
|
-
rtn = path.posix.join(FS_PREFIX + id)
|
|
178
|
-
}
|
|
179
|
-
return config.base + rtn.replace(/^\//, '')
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export function getAssetFilename(
|
|
183
|
-
hash: string,
|
|
184
|
-
config: ResolvedConfig
|
|
185
|
-
): string | undefined {
|
|
186
|
-
return assetHashToFilenameMap.get(config)?.get(hash)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* converts the source filepath of the asset to the output filename based on the assetFileNames option. \
|
|
191
|
-
* this function imitates the behavior of rollup.js. \
|
|
192
|
-
* https://rollupjs.org/guide/en/#outputassetfilenames
|
|
193
|
-
*
|
|
194
|
-
* @example
|
|
195
|
-
* ```ts
|
|
196
|
-
* const content = Buffer.from('text');
|
|
197
|
-
* const fileName = assetFileNamesToFileName(
|
|
198
|
-
* 'assets/[name].[hash][extname]',
|
|
199
|
-
* '/path/to/file.txt',
|
|
200
|
-
* getAssetHash(content),
|
|
201
|
-
* content
|
|
202
|
-
* )
|
|
203
|
-
* // fileName: 'assets/file.982d9e3e.txt'
|
|
204
|
-
* ```
|
|
205
|
-
*
|
|
206
|
-
* @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'`
|
|
207
|
-
* @param file filepath of the asset
|
|
208
|
-
* @param contentHash hash of the asset. used for `'[hash]'` placeholder
|
|
209
|
-
* @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function
|
|
210
|
-
* @returns output filename
|
|
211
|
-
*/
|
|
212
|
-
export function assetFileNamesToFileName(
|
|
213
|
-
assetFileNames: Exclude<OutputOptions['assetFileNames'], undefined>,
|
|
214
|
-
file: string,
|
|
215
|
-
contentHash: string,
|
|
216
|
-
content: string | Buffer
|
|
217
|
-
): string {
|
|
218
|
-
const basename = path.basename(file)
|
|
219
|
-
|
|
220
|
-
// placeholders for `assetFileNames`
|
|
221
|
-
// `hash` is slightly different from the rollup's one
|
|
222
|
-
const extname = path.extname(basename)
|
|
223
|
-
const ext = extname.substr(1)
|
|
224
|
-
const name = basename.slice(0, -extname.length)
|
|
225
|
-
const hash = contentHash
|
|
226
|
-
|
|
227
|
-
if (typeof assetFileNames === 'function') {
|
|
228
|
-
assetFileNames = assetFileNames({
|
|
229
|
-
name: file,
|
|
230
|
-
source: content,
|
|
231
|
-
type: 'asset'
|
|
232
|
-
})
|
|
233
|
-
if (typeof assetFileNames !== 'string') {
|
|
234
|
-
throw new TypeError('assetFileNames must return a string')
|
|
235
|
-
}
|
|
236
|
-
} else if (typeof assetFileNames !== 'string') {
|
|
237
|
-
throw new TypeError('assetFileNames must be a string or a function')
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const fileName = assetFileNames.replace(
|
|
241
|
-
/\[\w+\]/g,
|
|
242
|
-
(placeholder: string): string => {
|
|
243
|
-
switch (placeholder) {
|
|
244
|
-
case '[ext]':
|
|
245
|
-
return ext
|
|
246
|
-
|
|
247
|
-
case '[extname]':
|
|
248
|
-
return extname
|
|
249
|
-
|
|
250
|
-
case '[hash]':
|
|
251
|
-
return hash
|
|
252
|
-
|
|
253
|
-
case '[name]':
|
|
254
|
-
return name
|
|
255
|
-
}
|
|
256
|
-
throw new Error(
|
|
257
|
-
`invalid placeholder ${placeholder} in assetFileNames "${assetFileNames}"`
|
|
258
|
-
)
|
|
259
|
-
}
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
return fileName
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Register an asset to be emitted as part of the bundle (if necessary)
|
|
267
|
-
* and returns the resolved public URL
|
|
268
|
-
*/
|
|
269
|
-
async function fileToBuiltUrl(
|
|
270
|
-
id: string,
|
|
271
|
-
config: ResolvedConfig,
|
|
272
|
-
pluginContext: PluginContext,
|
|
273
|
-
skipPublicCheck = false
|
|
274
|
-
): Promise<string> {
|
|
275
|
-
if (!skipPublicCheck && checkPublicFile(id, config)) {
|
|
276
|
-
return config.base + id.slice(1)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const cache = assetCache.get(config)!
|
|
280
|
-
const cached = cache.get(id)
|
|
281
|
-
if (cached) {
|
|
282
|
-
return cached
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const file = cleanUrl(id)
|
|
286
|
-
const content = await fsp.readFile(file)
|
|
287
|
-
|
|
288
|
-
let url: string
|
|
289
|
-
if (
|
|
290
|
-
config.build.lib ||
|
|
291
|
-
(!file.endsWith('.svg') &&
|
|
292
|
-
content.length < Number(config.build.assetsInlineLimit))
|
|
293
|
-
) {
|
|
294
|
-
// base64 inlined as a string
|
|
295
|
-
url = `data:${mime.getType(file)};base64,${content.toString('base64')}`
|
|
296
|
-
} else {
|
|
297
|
-
// emit as asset
|
|
298
|
-
// rollup supports `import.meta.ROLLUP_FILE_URL_*`, but it generates code
|
|
299
|
-
// that uses runtime url sniffing and it can be verbose when targeting
|
|
300
|
-
// non-module format. It also fails to cascade the asset content change
|
|
301
|
-
// into the chunk's hash, so we have to do our own content hashing here.
|
|
302
|
-
// https://bundlers.tooling.report/hashing/asset-cascade/
|
|
303
|
-
// https://github.com/rollup/rollup/issues/3415
|
|
304
|
-
const map = assetHashToFilenameMap.get(config)!
|
|
305
|
-
const contentHash = getAssetHash(content)
|
|
306
|
-
const { search, hash } = parseUrl(id)
|
|
307
|
-
const postfix = (search || '') + (hash || '')
|
|
308
|
-
const output = config.build?.rollupOptions?.output
|
|
309
|
-
const assetFileNames =
|
|
310
|
-
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
|
|
311
|
-
// defaults to '<assetsDir>/[name].[hash][extname]'
|
|
312
|
-
// slightly different from rollup's one ('assets/[name]-[hash][extname]')
|
|
313
|
-
path.posix.join(config.build.assetsDir, '[name].[hash][extname]')
|
|
314
|
-
const fileName = assetFileNamesToFileName(
|
|
315
|
-
assetFileNames,
|
|
316
|
-
file,
|
|
317
|
-
contentHash,
|
|
318
|
-
content
|
|
319
|
-
)
|
|
320
|
-
if (!map.has(contentHash)) {
|
|
321
|
-
map.set(contentHash, fileName)
|
|
322
|
-
}
|
|
323
|
-
const emittedSet = emittedHashMap.get(config)!
|
|
324
|
-
if (!emittedSet.has(contentHash)) {
|
|
325
|
-
const name = normalizePath(path.relative(config.root, file))
|
|
326
|
-
pluginContext.emitFile({
|
|
327
|
-
name,
|
|
328
|
-
fileName,
|
|
329
|
-
type: 'asset',
|
|
330
|
-
source: content
|
|
331
|
-
})
|
|
332
|
-
emittedSet.add(contentHash)
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
url = `__VITE_ASSET__${contentHash}__${postfix ? `$_${postfix}__` : ``}`
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
cache.set(id, url)
|
|
339
|
-
return url
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export function getAssetHash(content: Buffer): string {
|
|
343
|
-
return createHash('sha256').update(content).digest('hex').slice(0, 8)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
export async function urlToBuiltUrl(
|
|
347
|
-
url: string,
|
|
348
|
-
importer: string,
|
|
349
|
-
config: ResolvedConfig,
|
|
350
|
-
pluginContext: PluginContext
|
|
351
|
-
): Promise<string> {
|
|
352
|
-
if (checkPublicFile(url, config)) {
|
|
353
|
-
return config.base + url.slice(1)
|
|
354
|
-
}
|
|
355
|
-
const file = url.startsWith('/')
|
|
356
|
-
? path.join(config.root, url)
|
|
357
|
-
: path.join(path.dirname(importer), url)
|
|
358
|
-
return fileToBuiltUrl(
|
|
359
|
-
file,
|
|
360
|
-
config,
|
|
361
|
-
pluginContext,
|
|
362
|
-
// skip public check since we just did it above
|
|
363
|
-
true
|
|
364
|
-
)
|
|
365
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Plugin } from '../plugin'
|
|
2
|
-
import MagicString from 'magic-string'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import { fileToUrl } from './asset'
|
|
5
|
-
import { ResolvedConfig } from '../config'
|
|
6
|
-
import { multilineCommentsRE, singlelineCommentsRE } from '../utils'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Convert `new URL('./foo.png', import.meta.url)` to its resolved built URL
|
|
10
|
-
*
|
|
11
|
-
* Supports tempalte string with dynamic segments:
|
|
12
|
-
* ```
|
|
13
|
-
* new URL(`./dir/${name}.png`, import.meta.url)
|
|
14
|
-
* // transformed to
|
|
15
|
-
* import.meta.globEager('./dir/**.png')[`./dir/${name}.png`].default
|
|
16
|
-
* ```
|
|
17
|
-
*/
|
|
18
|
-
export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
|
|
19
|
-
return {
|
|
20
|
-
name: 'vite:asset-import-meta-url',
|
|
21
|
-
async transform(code, id, ssr) {
|
|
22
|
-
if (code.includes('new URL') && code.includes(`import.meta.url`)) {
|
|
23
|
-
const importMetaUrlRE =
|
|
24
|
-
/\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\)/g
|
|
25
|
-
const noCommentsCode = code
|
|
26
|
-
.replace(multilineCommentsRE, (m) => ' '.repeat(m.length))
|
|
27
|
-
.replace(singlelineCommentsRE, (m) => ' '.repeat(m.length))
|
|
28
|
-
let s: MagicString | null = null
|
|
29
|
-
let match: RegExpExecArray | null
|
|
30
|
-
while ((match = importMetaUrlRE.exec(noCommentsCode))) {
|
|
31
|
-
const { 0: exp, 1: rawUrl, index } = match
|
|
32
|
-
|
|
33
|
-
if (ssr) {
|
|
34
|
-
this.error(
|
|
35
|
-
`\`new URL(url, import.meta.url)\` is not supported in SSR.`,
|
|
36
|
-
index
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!s) s = new MagicString(code)
|
|
41
|
-
|
|
42
|
-
// potential dynamic template string
|
|
43
|
-
if (rawUrl[0] === '`' && /\$\{/.test(rawUrl)) {
|
|
44
|
-
const ast = this.parse(rawUrl)
|
|
45
|
-
const templateLiteral = (ast as any).body[0].expression
|
|
46
|
-
if (templateLiteral.expressions.length) {
|
|
47
|
-
const pattern = buildGlobPattern(templateLiteral)
|
|
48
|
-
// Note: native import.meta.url is not supported in the baseline
|
|
49
|
-
// target so we use window.location here -
|
|
50
|
-
s.overwrite(
|
|
51
|
-
index,
|
|
52
|
-
index + exp.length,
|
|
53
|
-
`new URL(import.meta.globEagerDefault(${JSON.stringify(
|
|
54
|
-
pattern
|
|
55
|
-
)})[${rawUrl}], window.location)`
|
|
56
|
-
)
|
|
57
|
-
continue
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const url = rawUrl.slice(1, -1)
|
|
62
|
-
const file = path.resolve(path.dirname(id), url)
|
|
63
|
-
const builtUrl = await fileToUrl(file, config, this)
|
|
64
|
-
s.overwrite(
|
|
65
|
-
index,
|
|
66
|
-
index + exp.length,
|
|
67
|
-
`new URL(${JSON.stringify(builtUrl)}, window.location)`
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
if (s) {
|
|
71
|
-
return {
|
|
72
|
-
code: s.toString(),
|
|
73
|
-
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return null
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function buildGlobPattern(ast: any) {
|
|
83
|
-
let pattern = ''
|
|
84
|
-
let lastElementIndex = -1
|
|
85
|
-
for (const exp of ast.expressions) {
|
|
86
|
-
for (let i = lastElementIndex + 1; i < ast.quasis.length; i++) {
|
|
87
|
-
const el = ast.quasis[i]
|
|
88
|
-
if (el.end < exp.start) {
|
|
89
|
-
pattern += el.value.raw
|
|
90
|
-
lastElementIndex = i
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
pattern += '**'
|
|
94
|
-
}
|
|
95
|
-
for (let i = lastElementIndex + 1; i < ast.quasis.length; i++) {
|
|
96
|
-
pattern += ast.quasis[i].value.raw
|
|
97
|
-
}
|
|
98
|
-
return pattern
|
|
99
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import { Plugin } from '../plugin'
|
|
3
|
-
import { ResolvedConfig } from '../config'
|
|
4
|
-
import { CLIENT_ENTRY, ENV_ENTRY } from '../constants'
|
|
5
|
-
import { normalizePath, isObject } from '../utils'
|
|
6
|
-
|
|
7
|
-
// ids in transform are normalized to unix style
|
|
8
|
-
const normalizedClientEntry = normalizePath(CLIENT_ENTRY)
|
|
9
|
-
const normalizedEnvEntry = normalizePath(ENV_ENTRY)
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* some values used by the client needs to be dynamically injected by the server
|
|
13
|
-
* @server-only
|
|
14
|
-
*/
|
|
15
|
-
export function clientInjectionsPlugin(config: ResolvedConfig): Plugin {
|
|
16
|
-
return {
|
|
17
|
-
name: 'vite:client-inject',
|
|
18
|
-
transform(code, id) {
|
|
19
|
-
if (id === normalizedClientEntry || id === normalizedEnvEntry) {
|
|
20
|
-
let options = config.server.hmr
|
|
21
|
-
options = options && typeof options !== 'boolean' ? options : {}
|
|
22
|
-
const host = options.host || null
|
|
23
|
-
const protocol = options.protocol || null
|
|
24
|
-
const timeout = options.timeout || 30000
|
|
25
|
-
const overlay = options.overlay !== false
|
|
26
|
-
let port: number | string | undefined
|
|
27
|
-
if (isObject(config.server.hmr)) {
|
|
28
|
-
port = config.server.hmr.clientPort || config.server.hmr.port
|
|
29
|
-
}
|
|
30
|
-
if (config.server.middlewareMode) {
|
|
31
|
-
port = String(port || 24678)
|
|
32
|
-
} else {
|
|
33
|
-
port = String(port || options.port || config.server.port!)
|
|
34
|
-
}
|
|
35
|
-
let hmrBase = config.base
|
|
36
|
-
if (options.path) {
|
|
37
|
-
hmrBase = path.posix.join(hmrBase, options.path)
|
|
38
|
-
}
|
|
39
|
-
if (hmrBase !== '/') {
|
|
40
|
-
port = path.posix.normalize(`${port}${hmrBase}`)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return code
|
|
44
|
-
.replace(`__MODE__`, JSON.stringify(config.mode))
|
|
45
|
-
.replace(`__BASE__`, JSON.stringify(config.base))
|
|
46
|
-
.replace(`__DEFINES__`, serializeDefine(config.define || {}))
|
|
47
|
-
.replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol))
|
|
48
|
-
.replace(`__HMR_HOSTNAME__`, JSON.stringify(host))
|
|
49
|
-
.replace(`__HMR_PORT__`, JSON.stringify(port))
|
|
50
|
-
.replace(`__HMR_TIMEOUT__`, JSON.stringify(timeout))
|
|
51
|
-
.replace(`__HMR_ENABLE_OVERLAY__`, JSON.stringify(overlay))
|
|
52
|
-
} else if (code.includes('process.env.NODE_ENV')) {
|
|
53
|
-
// replace process.env.NODE_ENV
|
|
54
|
-
return code.replace(
|
|
55
|
-
/\bprocess\.env\.NODE_ENV\b/g,
|
|
56
|
-
JSON.stringify(config.mode)
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function serializeDefine(define: Record<string, any>): string {
|
|
64
|
-
let res = `{`
|
|
65
|
-
for (const key in define) {
|
|
66
|
-
const val = define[key]
|
|
67
|
-
res += `${JSON.stringify(key)}: ${
|
|
68
|
-
typeof val === 'string' ? `(${val})` : JSON.stringify(val)
|
|
69
|
-
}, `
|
|
70
|
-
}
|
|
71
|
-
return res + `}`
|
|
72
|
-
}
|