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.

Files changed (110) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE.md +161 -3011
  3. package/bin/vite.js +2 -1
  4. package/dist/node/chunks/{dep-91aa74e8.js → dep-1e0a75a8.js} +58 -32
  5. package/dist/node/chunks/dep-1e0a75a8.js.map +1 -0
  6. package/dist/node/chunks/{dep-e36486f6.js → dep-ac1b4bf9.js} +1 -1
  7. package/dist/node/chunks/dep-ac1b4bf9.js.map +1 -0
  8. package/dist/node/chunks/{dep-c7e510f9.js → dep-ba6b30a0.js} +27538 -4953
  9. package/dist/node/chunks/dep-ba6b30a0.js.map +1 -0
  10. package/dist/node/chunks/{dep-11213a75.js → dep-c4cf6e92.js} +19 -6
  11. package/dist/node/chunks/dep-c4cf6e92.js.map +1 -0
  12. package/dist/node/chunks/{dep-eb6ef720.js → dep-d574094c.js} +18 -5
  13. package/dist/node/chunks/dep-d574094c.js.map +1 -0
  14. package/dist/node/chunks/{dep-0d2f9464.js → dep-e39b05d6.js} +18 -5
  15. package/dist/node/chunks/dep-e39b05d6.js.map +1 -0
  16. package/dist/node/cli.js +60 -23992
  17. package/dist/node/cli.js.map +1 -1
  18. package/dist/node/index.d.ts +26 -8
  19. package/dist/node/index.js +18 -15
  20. package/dist/node/index.js.map +1 -1
  21. package/dist/node/terser.js +102 -55
  22. package/package.json +28 -13
  23. package/types/package.json +3 -0
  24. package/api-extractor.json +0 -54
  25. package/dist/node/chunks/dep-0d2f9464.js.map +0 -1
  26. package/dist/node/chunks/dep-11213a75.js.map +0 -1
  27. package/dist/node/chunks/dep-91aa74e8.js.map +0 -1
  28. package/dist/node/chunks/dep-c7e510f9.js.map +0 -1
  29. package/dist/node/chunks/dep-e36486f6.js.map +0 -1
  30. package/dist/node/chunks/dep-eb6ef720.js.map +0 -1
  31. package/dist/node/terser.js.map +0 -1
  32. package/rollup.config.js +0 -389
  33. package/scripts/patchTypes.js +0 -70
  34. package/src/node/__tests__/asset.spec.ts +0 -156
  35. package/src/node/__tests__/build.spec.ts +0 -67
  36. package/src/node/__tests__/config.spec.ts +0 -166
  37. package/src/node/__tests__/packages/name/package.json +0 -3
  38. package/src/node/__tests__/packages/noname/package.json +0 -1
  39. package/src/node/__tests__/plugins/css.spec.ts +0 -116
  40. package/src/node/__tests__/scan.spec.ts +0 -118
  41. package/src/node/__tests__/utils.spec.ts +0 -40
  42. package/src/node/build.ts +0 -783
  43. package/src/node/cli.ts +0 -239
  44. package/src/node/config.ts +0 -1033
  45. package/src/node/constants.ts +0 -87
  46. package/src/node/importGlob.ts +0 -173
  47. package/src/node/index.ts +0 -88
  48. package/src/node/logger.ts +0 -167
  49. package/src/node/optimizer/esbuildDepPlugin.ts +0 -216
  50. package/src/node/optimizer/index.ts +0 -410
  51. package/src/node/optimizer/registerMissing.ts +0 -102
  52. package/src/node/optimizer/scan.ts +0 -457
  53. package/src/node/plugin.ts +0 -138
  54. package/src/node/plugins/asset.ts +0 -365
  55. package/src/node/plugins/assetImportMetaUrl.ts +0 -99
  56. package/src/node/plugins/clientInjections.ts +0 -72
  57. package/src/node/plugins/css.ts +0 -1279
  58. package/src/node/plugins/dataUri.ts +0 -64
  59. package/src/node/plugins/define.ts +0 -107
  60. package/src/node/plugins/esbuild.ts +0 -280
  61. package/src/node/plugins/html.ts +0 -673
  62. package/src/node/plugins/importAnalysis.ts +0 -614
  63. package/src/node/plugins/importAnalysisBuild.ts +0 -334
  64. package/src/node/plugins/index.ts +0 -69
  65. package/src/node/plugins/json.ts +0 -75
  66. package/src/node/plugins/loadFallback.ts +0 -19
  67. package/src/node/plugins/manifest.ts +0 -123
  68. package/src/node/plugins/modulePreloadPolyfill.ts +0 -100
  69. package/src/node/plugins/preAlias.ts +0 -22
  70. package/src/node/plugins/reporter.ts +0 -244
  71. package/src/node/plugins/resolve.ts +0 -925
  72. package/src/node/plugins/terser.ts +0 -40
  73. package/src/node/plugins/wasm.ts +0 -72
  74. package/src/node/plugins/worker.ts +0 -117
  75. package/src/node/preview.ts +0 -82
  76. package/src/node/server/__tests__/fixtures/none/nested/package.json +0 -3
  77. package/src/node/server/__tests__/fixtures/pnpm/nested/package.json +0 -3
  78. package/src/node/server/__tests__/fixtures/pnpm/package.json +0 -3
  79. package/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml +0 -0
  80. package/src/node/server/__tests__/fixtures/yarn/nested/package.json +0 -3
  81. package/src/node/server/__tests__/fixtures/yarn/package.json +0 -6
  82. package/src/node/server/__tests__/search-root.spec.ts +0 -31
  83. package/src/node/server/hmr.ts +0 -489
  84. package/src/node/server/http.ts +0 -198
  85. package/src/node/server/index.ts +0 -705
  86. package/src/node/server/middlewares/base.ts +0 -52
  87. package/src/node/server/middlewares/error.ts +0 -98
  88. package/src/node/server/middlewares/indexHtml.ts +0 -170
  89. package/src/node/server/middlewares/proxy.ts +0 -124
  90. package/src/node/server/middlewares/spaFallback.ts +0 -32
  91. package/src/node/server/middlewares/static.ts +0 -153
  92. package/src/node/server/middlewares/time.ts +0 -18
  93. package/src/node/server/middlewares/transform.ts +0 -196
  94. package/src/node/server/moduleGraph.ts +0 -200
  95. package/src/node/server/openBrowser.ts +0 -101
  96. package/src/node/server/pluginContainer.ts +0 -546
  97. package/src/node/server/searchRoot.ts +0 -70
  98. package/src/node/server/send.ts +0 -54
  99. package/src/node/server/sourcemap.ts +0 -54
  100. package/src/node/server/transformRequest.ts +0 -168
  101. package/src/node/server/ws.ts +0 -131
  102. package/src/node/ssr/__tests__/ssrTransform.spec.ts +0 -309
  103. package/src/node/ssr/ssrExternal.ts +0 -161
  104. package/src/node/ssr/ssrManifestPlugin.ts +0 -53
  105. package/src/node/ssr/ssrModuleLoader.ts +0 -214
  106. package/src/node/ssr/ssrStacktrace.ts +0 -75
  107. package/src/node/ssr/ssrTransform.ts +0 -452
  108. package/src/node/tsconfig.json +0 -14
  109. package/src/node/utils.ts +0 -565
  110. package/tsconfig.base.json +0 -11
@@ -1,1033 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { Plugin } from './plugin'
4
- import { BuildOptions, resolveBuildOptions } from './build'
5
- import {
6
- ResolvedServerOptions,
7
- resolveServerOptions,
8
- ServerOptions
9
- } from './server'
10
- import { CSSOptions } from './plugins/css'
11
- import {
12
- arraify,
13
- createDebugger,
14
- isExternalUrl,
15
- isObject,
16
- lookupFile,
17
- normalizePath
18
- } from './utils'
19
- import { resolvePlugins } from './plugins'
20
- import chalk from 'chalk'
21
- import { ESBuildOptions } from './plugins/esbuild'
22
- import dotenv from 'dotenv'
23
- import dotenvExpand from 'dotenv-expand'
24
- import { Alias, AliasOptions } from 'types/alias'
25
- import { CLIENT_ENTRY, ENV_ENTRY, DEFAULT_ASSETS_RE } from './constants'
26
- import {
27
- InternalResolveOptions,
28
- ResolveOptions,
29
- resolvePlugin
30
- } from './plugins/resolve'
31
- import { createLogger, Logger, LogLevel } from './logger'
32
- import { DepOptimizationOptions } from './optimizer'
33
- import { createFilter } from '@rollup/pluginutils'
34
- import { ResolvedBuildOptions } from '.'
35
- import { parse as parseUrl } from 'url'
36
- import { JsonOptions } from './plugins/json'
37
- import {
38
- createPluginContainer,
39
- PluginContainer
40
- } from './server/pluginContainer'
41
- import aliasPlugin from '@rollup/plugin-alias'
42
- import { build } from 'esbuild'
43
-
44
- const debug = createDebugger('vite:config')
45
-
46
- // NOTE: every export in this file is re-exported from ./index.ts so it will
47
- // be part of the public API.
48
- export interface ConfigEnv {
49
- command: 'build' | 'serve'
50
- mode: string
51
- }
52
-
53
- export type UserConfigFn = (env: ConfigEnv) => UserConfig | Promise<UserConfig>
54
- export type UserConfigExport = UserConfig | Promise<UserConfig> | UserConfigFn
55
-
56
- /**
57
- * Type helper to make it easier to use vite.config.ts
58
- * accepts a direct {@link UserConfig} object, or a function that returns it.
59
- * The function receives a {@link ConfigEnv} object that exposes two properties:
60
- * `command` (either `'build'` or `'serve'`), and `mode`.
61
- */
62
- export function defineConfig(config: UserConfigExport): UserConfigExport {
63
- return config
64
- }
65
-
66
- export type PluginOption = Plugin | false | null | undefined
67
-
68
- export interface UserConfig {
69
- /**
70
- * Project root directory. Can be an absolute path, or a path relative from
71
- * the location of the config file itself.
72
- * @default process.cwd()
73
- */
74
- root?: string
75
- /**
76
- * Base public path when served in development or production.
77
- * @default '/'
78
- */
79
- base?: string
80
- /**
81
- * Directory to serve as plain static assets. Files in this directory are
82
- * served and copied to build dist dir as-is without transform. The value
83
- * can be either an absolute file system path or a path relative to <root>.
84
- *
85
- * Set to `false` or an empty string to disable copied static assets to build dist dir.
86
- * @default 'public'
87
- */
88
- publicDir?: string | false
89
- /**
90
- * Directory to save cache files. Files in this directory are pre-bundled
91
- * deps or some other cache files that generated by vite, which can improve
92
- * the performance. You can use `--force` flag or manually delete the directory
93
- * to regenerate the cache files. The value can be either an absolute file
94
- * system path or a path relative to <root>.
95
- * @default 'node_modules/.vite'
96
- */
97
- cacheDir?: string
98
- /**
99
- * Explicitly set a mode to run in. This will override the default mode for
100
- * each command, and can be overridden by the command line --mode option.
101
- */
102
- mode?: string
103
- /**
104
- * Define global variable replacements.
105
- * Entries will be defined on `window` during dev and replaced during build.
106
- */
107
- define?: Record<string, any>
108
- /**
109
- * Array of vite plugins to use.
110
- */
111
- plugins?: (PluginOption | PluginOption[])[]
112
- /**
113
- * Configure resolver
114
- */
115
- resolve?: ResolveOptions & { alias?: AliasOptions }
116
- /**
117
- * CSS related options (preprocessors and CSS modules)
118
- */
119
- css?: CSSOptions
120
- /**
121
- * JSON loading options
122
- */
123
- json?: JsonOptions
124
- /**
125
- * Transform options to pass to esbuild.
126
- * Or set to `false` to disable esbuild.
127
- */
128
- esbuild?: ESBuildOptions | false
129
- /**
130
- * Specify additional picomatch patterns to be treated as static assets.
131
- */
132
- assetsInclude?: string | RegExp | (string | RegExp)[]
133
- /**
134
- * Server specific options, e.g. host, port, https...
135
- */
136
- server?: ServerOptions
137
- /**
138
- * Build specific options
139
- */
140
- build?: BuildOptions
141
- /**
142
- * Dep optimization options
143
- */
144
- optimizeDeps?: DepOptimizationOptions
145
- /**
146
- * SSR specific options
147
- * @alpha
148
- */
149
- ssr?: SSROptions
150
- /**
151
- * Log level.
152
- * Default: 'info'
153
- */
154
- logLevel?: LogLevel
155
- /**
156
- * Custom logger.
157
- */
158
- customLogger?: Logger
159
- /**
160
- * Default: true
161
- */
162
- clearScreen?: boolean
163
- /**
164
- * Environment files directory. Can be an absolute path, or a path relative from
165
- * the location of the config file itself.
166
- * @default root
167
- */
168
- envDir?: string
169
- /**
170
- * Env variables starts with `envPrefix` will be exposed to your client source code via import.meta.env.
171
- * @default 'VITE_'
172
- */
173
- envPrefix?: string | string[]
174
- /**
175
- * Import aliases
176
- * @deprecated use `resolve.alias` instead
177
- */
178
- alias?: AliasOptions
179
- /**
180
- * Force Vite to always resolve listed dependencies to the same copy (from
181
- * project root).
182
- * @deprecated use `resolve.dedupe` instead
183
- */
184
- dedupe?: string[]
185
- }
186
-
187
- export type SSRTarget = 'node' | 'webworker'
188
-
189
- export interface SSROptions {
190
- external?: string[]
191
- noExternal?: string | RegExp | (string | RegExp)[] | true
192
- /**
193
- * Define the target for the ssr build. The browser field in package.json
194
- * is ignored for node but used if webworker is the target
195
- * Default: 'node'
196
- */
197
- target?: SSRTarget
198
- }
199
-
200
- export interface InlineConfig extends UserConfig {
201
- configFile?: string | false
202
- envFile?: false
203
- }
204
-
205
- export type ResolvedConfig = Readonly<
206
- Omit<
207
- UserConfig,
208
- 'plugins' | 'alias' | 'dedupe' | 'assetsInclude' | 'optimizeDeps'
209
- > & {
210
- configFile: string | undefined
211
- configFileDependencies: string[]
212
- inlineConfig: InlineConfig
213
- root: string
214
- base: string
215
- publicDir: string
216
- command: 'build' | 'serve'
217
- mode: string
218
- isProduction: boolean
219
- env: Record<string, any>
220
- resolve: ResolveOptions & {
221
- alias: Alias[]
222
- }
223
- plugins: readonly Plugin[]
224
- server: ResolvedServerOptions
225
- build: ResolvedBuildOptions
226
- assetsInclude: (file: string) => boolean
227
- logger: Logger
228
- createResolver: (options?: Partial<InternalResolveOptions>) => ResolveFn
229
- optimizeDeps: Omit<DepOptimizationOptions, 'keepNames'>
230
- }
231
- >
232
-
233
- export type ResolveFn = (
234
- id: string,
235
- importer?: string,
236
- aliasOnly?: boolean,
237
- ssr?: boolean
238
- ) => Promise<string | undefined>
239
-
240
- export async function resolveConfig(
241
- inlineConfig: InlineConfig,
242
- command: 'build' | 'serve',
243
- defaultMode = 'development'
244
- ): Promise<ResolvedConfig> {
245
- let config = inlineConfig
246
- let configFileDependencies: string[] = []
247
- let mode = inlineConfig.mode || defaultMode
248
-
249
- // some dependencies e.g. @vue/compiler-* relies on NODE_ENV for getting
250
- // production-specific behavior, so set it here even though we haven't
251
- // resolve the final mode yet
252
- if (mode === 'production') {
253
- process.env.NODE_ENV = 'production'
254
- }
255
-
256
- const configEnv = {
257
- mode,
258
- command
259
- }
260
-
261
- let { configFile } = config
262
- if (configFile !== false) {
263
- const loadResult = await loadConfigFromFile(
264
- configEnv,
265
- configFile,
266
- config.root,
267
- config.logLevel
268
- )
269
- if (loadResult) {
270
- config = mergeConfig(loadResult.config, config)
271
- configFile = loadResult.path
272
- configFileDependencies = loadResult.dependencies
273
- }
274
- }
275
-
276
- // Define logger
277
- const logger = createLogger(config.logLevel, {
278
- allowClearScreen: config.clearScreen,
279
- customLogger: config.customLogger
280
- })
281
-
282
- // user config may provide an alternative mode. But --mode has a higher prority
283
- mode = inlineConfig.mode || config.mode || mode
284
- configEnv.mode = mode
285
-
286
- // resolve plugins
287
- const rawUserPlugins = (config.plugins || []).flat().filter((p) => {
288
- if (!p) {
289
- return false
290
- } else if (!p.apply) {
291
- return true
292
- } else if (typeof p.apply === 'function') {
293
- return p.apply({ ...config, mode }, configEnv)
294
- } else {
295
- return p.apply === command
296
- }
297
- }) as Plugin[]
298
- const [prePlugins, normalPlugins, postPlugins] =
299
- sortUserPlugins(rawUserPlugins)
300
-
301
- // run config hooks
302
- const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins]
303
- for (const p of userPlugins) {
304
- if (p.config) {
305
- const res = await p.config(config, configEnv)
306
- if (res) {
307
- config = mergeConfig(config, res)
308
- }
309
- }
310
- }
311
-
312
- // resolve root
313
- const resolvedRoot = normalizePath(
314
- config.root ? path.resolve(config.root) : process.cwd()
315
- )
316
-
317
- const clientAlias = [
318
- { find: /^[\/]?@vite\/env/, replacement: () => ENV_ENTRY },
319
- { find: /^[\/]?@vite\/client/, replacement: () => CLIENT_ENTRY }
320
- ]
321
-
322
- // resolve alias with internal client alias
323
- const resolvedAlias = mergeAlias(
324
- // @ts-ignore because @rollup/plugin-alias' type doesn't allow function
325
- // replacement, but its implementation does work with function values.
326
- clientAlias,
327
- config.resolve?.alias || config.alias || []
328
- )
329
-
330
- const resolveOptions: ResolvedConfig['resolve'] = {
331
- dedupe: config.dedupe,
332
- ...config.resolve,
333
- alias: resolvedAlias
334
- }
335
-
336
- // load .env files
337
- const envDir = config.envDir
338
- ? normalizePath(path.resolve(resolvedRoot, config.envDir))
339
- : resolvedRoot
340
- const userEnv =
341
- inlineConfig.envFile !== false &&
342
- loadEnv(mode, envDir, resolveEnvPrefix(config))
343
-
344
- // Note it is possible for user to have a custom mode, e.g. `staging` where
345
- // production-like behavior is expected. This is indicated by NODE_ENV=production
346
- // loaded from `.staging.env` and set by us as VITE_USER_NODE_ENV
347
- const isProduction = (process.env.VITE_USER_NODE_ENV || mode) === 'production'
348
- if (isProduction) {
349
- // in case default mode was not production and is overwritten
350
- process.env.NODE_ENV = 'production'
351
- }
352
-
353
- // resolve public base url
354
- const BASE_URL = resolveBaseUrl(config.base, command === 'build', logger)
355
- const resolvedBuildOptions = resolveBuildOptions(config.build)
356
-
357
- // resolve cache directory
358
- const pkgPath = lookupFile(
359
- resolvedRoot,
360
- [`package.json`],
361
- true /* pathOnly */
362
- )
363
- const cacheDir = config.cacheDir
364
- ? path.resolve(resolvedRoot, config.cacheDir)
365
- : pkgPath && path.join(path.dirname(pkgPath), `node_modules/.vite`)
366
-
367
- const assetsFilter = config.assetsInclude
368
- ? createFilter(config.assetsInclude)
369
- : () => false
370
-
371
- // create an internal resolver to be used in special scenarios, e.g.
372
- // optimizer & handling css @imports
373
- const createResolver: ResolvedConfig['createResolver'] = (options) => {
374
- let aliasContainer: PluginContainer | undefined
375
- let resolverContainer: PluginContainer | undefined
376
- return async (id, importer, aliasOnly, ssr) => {
377
- let container: PluginContainer
378
- if (aliasOnly) {
379
- container =
380
- aliasContainer ||
381
- (aliasContainer = await createPluginContainer({
382
- ...resolved,
383
- plugins: [aliasPlugin({ entries: resolved.resolve.alias })]
384
- }))
385
- } else {
386
- container =
387
- resolverContainer ||
388
- (resolverContainer = await createPluginContainer({
389
- ...resolved,
390
- plugins: [
391
- aliasPlugin({ entries: resolved.resolve.alias }),
392
- resolvePlugin({
393
- ...resolved.resolve,
394
- root: resolvedRoot,
395
- isProduction,
396
- isBuild: command === 'build',
397
- ssrConfig: resolved.ssr,
398
- asSrc: true,
399
- preferRelative: false,
400
- tryIndex: true,
401
- ...options
402
- })
403
- ]
404
- }))
405
- }
406
- return (await container.resolveId(id, importer, undefined, ssr))?.id
407
- }
408
- }
409
-
410
- const { publicDir } = config
411
- const resolvedPublicDir =
412
- publicDir !== false && publicDir !== ''
413
- ? path.resolve(
414
- resolvedRoot,
415
- typeof publicDir === 'string' ? publicDir : 'public'
416
- )
417
- : ''
418
-
419
- const resolved: ResolvedConfig = {
420
- ...config,
421
- configFile: configFile ? normalizePath(configFile) : undefined,
422
- configFileDependencies,
423
- inlineConfig,
424
- root: resolvedRoot,
425
- base: BASE_URL,
426
- resolve: resolveOptions,
427
- publicDir: resolvedPublicDir,
428
- cacheDir,
429
- command,
430
- mode,
431
- isProduction,
432
- plugins: userPlugins,
433
- server: resolveServerOptions(resolvedRoot, config.server),
434
- build: resolvedBuildOptions,
435
- env: {
436
- ...userEnv,
437
- BASE_URL,
438
- MODE: mode,
439
- DEV: !isProduction,
440
- PROD: isProduction
441
- },
442
- assetsInclude(file: string) {
443
- return DEFAULT_ASSETS_RE.test(file) || assetsFilter(file)
444
- },
445
- logger,
446
- createResolver,
447
- optimizeDeps: {
448
- ...config.optimizeDeps,
449
- esbuildOptions: {
450
- keepNames: config.optimizeDeps?.keepNames,
451
- preserveSymlinks: config.resolve?.preserveSymlinks,
452
- ...config.optimizeDeps?.esbuildOptions
453
- }
454
- }
455
- }
456
-
457
- ;(resolved.plugins as Plugin[]) = await resolvePlugins(
458
- resolved,
459
- prePlugins,
460
- normalPlugins,
461
- postPlugins
462
- )
463
-
464
- // call configResolved hooks
465
- await Promise.all(userPlugins.map((p) => p.configResolved?.(resolved)))
466
-
467
- if (process.env.DEBUG) {
468
- debug(`using resolved config: %O`, {
469
- ...resolved,
470
- plugins: resolved.plugins.map((p) => p.name)
471
- })
472
- }
473
-
474
- // TODO Deprecation warnings - remove when out of beta
475
-
476
- const logDeprecationWarning = (
477
- deprecatedOption: string,
478
- hint: string,
479
- error?: Error
480
- ) => {
481
- logger.warn(
482
- chalk.yellow.bold(
483
- `(!) "${deprecatedOption}" option is deprecated. ${hint}${
484
- error ? `\n${error.stack}` : ''
485
- }`
486
- )
487
- )
488
- }
489
-
490
- if (config.build?.base) {
491
- logDeprecationWarning(
492
- 'build.base',
493
- '"base" is now a root-level config option.'
494
- )
495
- config.base = config.build.base
496
- }
497
- Object.defineProperty(resolvedBuildOptions, 'base', {
498
- enumerable: false,
499
- get() {
500
- logDeprecationWarning(
501
- 'build.base',
502
- '"base" is now a root-level config option.',
503
- new Error()
504
- )
505
- return resolved.base
506
- }
507
- })
508
-
509
- if (config.alias) {
510
- logDeprecationWarning('alias', 'Use "resolve.alias" instead.')
511
- }
512
- Object.defineProperty(resolved, 'alias', {
513
- enumerable: false,
514
- get() {
515
- logDeprecationWarning(
516
- 'alias',
517
- 'Use "resolve.alias" instead.',
518
- new Error()
519
- )
520
- return resolved.resolve.alias
521
- }
522
- })
523
-
524
- if (config.dedupe) {
525
- logDeprecationWarning('dedupe', 'Use "resolve.dedupe" instead.')
526
- }
527
- Object.defineProperty(resolved, 'dedupe', {
528
- enumerable: false,
529
- get() {
530
- logDeprecationWarning(
531
- 'dedupe',
532
- 'Use "resolve.dedupe" instead.',
533
- new Error()
534
- )
535
- return resolved.resolve.dedupe
536
- }
537
- })
538
-
539
- if (config.optimizeDeps?.keepNames) {
540
- logDeprecationWarning(
541
- 'optimizeDeps.keepNames',
542
- 'Use "optimizeDeps.esbuildOptions.keepNames" instead.'
543
- )
544
- }
545
- Object.defineProperty(resolved.optimizeDeps, 'keepNames', {
546
- enumerable: false,
547
- get() {
548
- logDeprecationWarning(
549
- 'optimizeDeps.keepNames',
550
- 'Use "optimizeDeps.esbuildOptions.keepNames" instead.',
551
- new Error()
552
- )
553
- return resolved.optimizeDeps.esbuildOptions?.keepNames
554
- }
555
- })
556
-
557
- if (config.build?.polyfillDynamicImport) {
558
- logDeprecationWarning(
559
- 'build.polyfillDynamicImport',
560
- '"polyfillDynamicImport" has been removed. Please use @vitejs/plugin-legacy if your target browsers do not support dynamic imports.'
561
- )
562
- }
563
-
564
- Object.defineProperty(resolvedBuildOptions, 'polyfillDynamicImport', {
565
- enumerable: false,
566
- get() {
567
- logDeprecationWarning(
568
- 'build.polyfillDynamicImport',
569
- '"polyfillDynamicImport" has been removed. Please use @vitejs/plugin-legacy if your target browsers do not support dynamic imports.',
570
- new Error()
571
- )
572
- return false
573
- }
574
- })
575
-
576
- if (config.build?.cleanCssOptions) {
577
- logDeprecationWarning(
578
- 'build.cleanCssOptions',
579
- 'Vite now uses esbuild for CSS minification.'
580
- )
581
- }
582
-
583
- return resolved
584
- }
585
-
586
- /**
587
- * Resolve base. Note that some users use Vite to build for non-web targets like
588
- * electron or expects to deploy
589
- */
590
- function resolveBaseUrl(
591
- base: UserConfig['base'] = '/',
592
- isBuild: boolean,
593
- logger: Logger
594
- ): string {
595
- // #1669 special treatment for empty for same dir relative base
596
- if (base === '' || base === './') {
597
- return isBuild ? base : '/'
598
- }
599
- if (base.startsWith('.')) {
600
- logger.warn(
601
- chalk.yellow.bold(
602
- `(!) invalid "base" option: ${base}. The value can only be an absolute ` +
603
- `URL, ./, or an empty string.`
604
- )
605
- )
606
- base = '/'
607
- }
608
-
609
- // external URL
610
- if (isExternalUrl(base)) {
611
- if (!isBuild) {
612
- // get base from full url during dev
613
- const parsed = parseUrl(base)
614
- base = parsed.pathname || '/'
615
- }
616
- } else {
617
- // ensure leading slash
618
- if (!base.startsWith('/')) {
619
- logger.warn(
620
- chalk.yellow.bold(`(!) "base" option should start with a slash.`)
621
- )
622
- base = '/' + base
623
- }
624
- }
625
-
626
- // ensure ending slash
627
- if (!base.endsWith('/')) {
628
- logger.warn(chalk.yellow.bold(`(!) "base" option should end with a slash.`))
629
- base += '/'
630
- }
631
-
632
- return base
633
- }
634
-
635
- function mergeConfigRecursively(
636
- a: Record<string, any>,
637
- b: Record<string, any>,
638
- rootPath: string
639
- ) {
640
- const merged: Record<string, any> = { ...a }
641
- for (const key in b) {
642
- const value = b[key]
643
- if (value == null) {
644
- continue
645
- }
646
-
647
- const existing = merged[key]
648
- if (Array.isArray(existing) && Array.isArray(value)) {
649
- merged[key] = [...existing, ...value]
650
- continue
651
- }
652
- if (isObject(existing) && isObject(value)) {
653
- merged[key] = mergeConfigRecursively(
654
- existing,
655
- value,
656
- rootPath ? `${rootPath}.${key}` : key
657
- )
658
- continue
659
- }
660
-
661
- // fields that require special handling
662
- if (existing != null) {
663
- if (key === 'alias' && (rootPath === 'resolve' || rootPath === '')) {
664
- merged[key] = mergeAlias(existing, value)
665
- continue
666
- } else if (key === 'assetsInclude' && rootPath === '') {
667
- merged[key] = [].concat(existing, value)
668
- continue
669
- } else if (key === 'noExternal' && existing === true) {
670
- continue
671
- }
672
- }
673
-
674
- merged[key] = value
675
- }
676
- return merged
677
- }
678
-
679
- export function mergeConfig(
680
- a: Record<string, any>,
681
- b: Record<string, any>,
682
- isRoot = true
683
- ): Record<string, any> {
684
- return mergeConfigRecursively(a, b, isRoot ? '' : '.')
685
- }
686
-
687
- function mergeAlias(a: AliasOptions = [], b: AliasOptions = []): Alias[] {
688
- return [...normalizeAlias(a), ...normalizeAlias(b)]
689
- }
690
-
691
- function normalizeAlias(o: AliasOptions): Alias[] {
692
- return Array.isArray(o)
693
- ? o.map(normalizeSingleAlias)
694
- : Object.keys(o).map((find) =>
695
- normalizeSingleAlias({
696
- find,
697
- replacement: (o as any)[find]
698
- })
699
- )
700
- }
701
-
702
- // https://github.com/vitejs/vite/issues/1363
703
- // work around https://github.com/rollup/plugins/issues/759
704
- function normalizeSingleAlias({ find, replacement }: Alias): Alias {
705
- if (
706
- typeof find === 'string' &&
707
- find.endsWith('/') &&
708
- replacement.endsWith('/')
709
- ) {
710
- find = find.slice(0, find.length - 1)
711
- replacement = replacement.slice(0, replacement.length - 1)
712
- }
713
- return { find, replacement }
714
- }
715
-
716
- export function sortUserPlugins(
717
- plugins: (Plugin | Plugin[])[] | undefined
718
- ): [Plugin[], Plugin[], Plugin[]] {
719
- const prePlugins: Plugin[] = []
720
- const postPlugins: Plugin[] = []
721
- const normalPlugins: Plugin[] = []
722
-
723
- if (plugins) {
724
- plugins.flat().forEach((p) => {
725
- if (p.enforce === 'pre') prePlugins.push(p)
726
- else if (p.enforce === 'post') postPlugins.push(p)
727
- else normalPlugins.push(p)
728
- })
729
- }
730
-
731
- return [prePlugins, normalPlugins, postPlugins]
732
- }
733
-
734
- export async function loadConfigFromFile(
735
- configEnv: ConfigEnv,
736
- configFile?: string,
737
- configRoot: string = process.cwd(),
738
- logLevel?: LogLevel
739
- ): Promise<{
740
- path: string
741
- config: UserConfig
742
- dependencies: string[]
743
- } | null> {
744
- const start = Date.now()
745
-
746
- let resolvedPath: string | undefined
747
- let isTS = false
748
- let isMjs = false
749
- let dependencies: string[] = []
750
-
751
- // check package.json for type: "module" and set `isMjs` to true
752
- try {
753
- const pkg = lookupFile(configRoot, ['package.json'])
754
- if (pkg && JSON.parse(pkg).type === 'module') {
755
- isMjs = true
756
- }
757
- } catch (e) {}
758
-
759
- if (configFile) {
760
- // explicit config path is always resolved from cwd
761
- resolvedPath = path.resolve(configFile)
762
- isTS = configFile.endsWith('.ts')
763
- } else {
764
- // implicit config file loaded from inline root (if present)
765
- // otherwise from cwd
766
- const jsconfigFile = path.resolve(configRoot, 'vite.config.js')
767
- if (fs.existsSync(jsconfigFile)) {
768
- resolvedPath = jsconfigFile
769
- }
770
-
771
- if (!resolvedPath) {
772
- const mjsconfigFile = path.resolve(configRoot, 'vite.config.mjs')
773
- if (fs.existsSync(mjsconfigFile)) {
774
- resolvedPath = mjsconfigFile
775
- isMjs = true
776
- }
777
- }
778
-
779
- if (!resolvedPath) {
780
- const tsconfigFile = path.resolve(configRoot, 'vite.config.ts')
781
- if (fs.existsSync(tsconfigFile)) {
782
- resolvedPath = tsconfigFile
783
- isTS = true
784
- }
785
- }
786
- }
787
-
788
- if (!resolvedPath) {
789
- debug('no config file found.')
790
- return null
791
- }
792
-
793
- try {
794
- let userConfig: UserConfigExport | undefined
795
-
796
- if (isMjs) {
797
- const fileUrl = require('url').pathToFileURL(resolvedPath)
798
- if (isTS) {
799
- // before we can register loaders without requiring users to run node
800
- // with --experimental-loader themselves, we have to do a hack here:
801
- // bundle the config file w/ ts transforms first, write it to disk,
802
- // load it with native Node ESM, then delete the file.
803
- const bundled = await bundleConfigFile(resolvedPath, true)
804
- dependencies = bundled.dependencies
805
- fs.writeFileSync(resolvedPath + '.js', bundled.code)
806
- userConfig = (await eval(`import(fileUrl + '.js?t=${Date.now()}')`))
807
- .default
808
- fs.unlinkSync(resolvedPath + '.js')
809
- debug(
810
- `TS + native esm config loaded in ${Date.now() - start}ms`,
811
- fileUrl
812
- )
813
- } else {
814
- // using eval to avoid this from being compiled away by TS/Rollup
815
- // append a query so that we force reload fresh config in case of
816
- // server restart
817
- userConfig = (await eval(`import(fileUrl + '?t=${Date.now()}')`))
818
- .default
819
- debug(`native esm config loaded in ${Date.now() - start}ms`, fileUrl)
820
- }
821
- }
822
-
823
- if (!userConfig && !isTS && !isMjs) {
824
- // 1. try to directly require the module (assuming commonjs)
825
- try {
826
- // clear cache in case of server restart
827
- delete require.cache[require.resolve(resolvedPath)]
828
- userConfig = require(resolvedPath)
829
- debug(`cjs config loaded in ${Date.now() - start}ms`)
830
- } catch (e) {
831
- const ignored = new RegExp(
832
- [
833
- `Cannot use import statement`,
834
- `Must use import to load ES Module`,
835
- // #1635, #2050 some Node 12.x versions don't have esm detection
836
- // so it throws normal syntax errors when encountering esm syntax
837
- `Unexpected token`,
838
- `Unexpected identifier`
839
- ].join('|')
840
- )
841
- if (!ignored.test(e.message)) {
842
- throw e
843
- }
844
- }
845
- }
846
-
847
- if (!userConfig) {
848
- // 2. if we reach here, the file is ts or using es import syntax, or
849
- // the user has type: "module" in their package.json (#917)
850
- // transpile es import syntax to require syntax using rollup.
851
- // lazy require rollup (it's actually in dependencies)
852
- const bundled = await bundleConfigFile(resolvedPath)
853
- dependencies = bundled.dependencies
854
- userConfig = await loadConfigFromBundledFile(resolvedPath, bundled.code)
855
- debug(`bundled config file loaded in ${Date.now() - start}ms`)
856
- }
857
-
858
- const config = await (typeof userConfig === 'function'
859
- ? userConfig(configEnv)
860
- : userConfig)
861
- if (!isObject(config)) {
862
- throw new Error(`config must export or return an object.`)
863
- }
864
- return {
865
- path: normalizePath(resolvedPath),
866
- config,
867
- dependencies
868
- }
869
- } catch (e) {
870
- createLogger(logLevel).error(
871
- chalk.red(`failed to load config from ${resolvedPath}`),
872
- { error: e }
873
- )
874
- throw e
875
- }
876
- }
877
-
878
- async function bundleConfigFile(
879
- fileName: string,
880
- mjs = false
881
- ): Promise<{ code: string; dependencies: string[] }> {
882
- const result = await build({
883
- absWorkingDir: process.cwd(),
884
- entryPoints: [fileName],
885
- outfile: 'out.js',
886
- write: false,
887
- platform: 'node',
888
- bundle: true,
889
- format: mjs ? 'esm' : 'cjs',
890
- sourcemap: 'inline',
891
- metafile: true,
892
- plugins: [
893
- {
894
- name: 'externalize-deps',
895
- setup(build) {
896
- build.onResolve({ filter: /.*/ }, (args) => {
897
- const id = args.path
898
- if (id[0] !== '.' && !path.isAbsolute(id)) {
899
- return {
900
- external: true
901
- }
902
- }
903
- })
904
- }
905
- },
906
- {
907
- name: 'replace-import-meta',
908
- setup(build) {
909
- build.onLoad({ filter: /\.[jt]s$/ }, async (args) => {
910
- const contents = await fs.promises.readFile(args.path, 'utf8')
911
- return {
912
- loader: args.path.endsWith('.ts') ? 'ts' : 'js',
913
- contents: contents
914
- .replace(
915
- /\bimport\.meta\.url\b/g,
916
- JSON.stringify(`file://${args.path}`)
917
- )
918
- .replace(
919
- /\b__dirname\b/g,
920
- JSON.stringify(path.dirname(args.path))
921
- )
922
- .replace(/\b__filename\b/g, JSON.stringify(args.path))
923
- }
924
- })
925
- }
926
- }
927
- ]
928
- })
929
- const { text } = result.outputFiles[0]
930
- return {
931
- code: text,
932
- dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
933
- }
934
- }
935
-
936
- interface NodeModuleWithCompile extends NodeModule {
937
- _compile(code: string, filename: string): any
938
- }
939
-
940
- async function loadConfigFromBundledFile(
941
- fileName: string,
942
- bundledCode: string
943
- ): Promise<UserConfig> {
944
- const extension = path.extname(fileName)
945
- const defaultLoader = require.extensions[extension]!
946
- require.extensions[extension] = (module: NodeModule, filename: string) => {
947
- if (filename === fileName) {
948
- ;(module as NodeModuleWithCompile)._compile(bundledCode, filename)
949
- } else {
950
- defaultLoader(module, filename)
951
- }
952
- }
953
- // clear cache in case of server restart
954
- delete require.cache[require.resolve(fileName)]
955
- const raw = require(fileName)
956
- const config = raw.__esModule ? raw.default : raw
957
- require.extensions[extension] = defaultLoader
958
- return config
959
- }
960
-
961
- export function loadEnv(
962
- mode: string,
963
- envDir: string,
964
- prefixes: string | string[] = 'VITE_'
965
- ): Record<string, string> {
966
- if (mode === 'local') {
967
- throw new Error(
968
- `"local" cannot be used as a mode name because it conflicts with ` +
969
- `the .local postfix for .env files.`
970
- )
971
- }
972
- prefixes = arraify(prefixes)
973
- const env: Record<string, string> = {}
974
- const envFiles = [
975
- /** mode local file */ `.env.${mode}.local`,
976
- /** mode file */ `.env.${mode}`,
977
- /** local file */ `.env.local`,
978
- /** default file */ `.env`
979
- ]
980
-
981
- // check if there are actual env variables starting with VITE_*
982
- // these are typically provided inline and should be prioritized
983
- for (const key in process.env) {
984
- if (
985
- prefixes.some((prefix) => key.startsWith(prefix)) &&
986
- env[key] === undefined
987
- ) {
988
- env[key] = process.env[key] as string
989
- }
990
- }
991
-
992
- for (const file of envFiles) {
993
- const path = lookupFile(envDir, [file], true)
994
- if (path) {
995
- const parsed = dotenv.parse(fs.readFileSync(path), {
996
- debug: !!process.env.DEBUG || undefined
997
- })
998
-
999
- // let environment variables use each other
1000
- dotenvExpand({
1001
- parsed,
1002
- // prevent process.env mutation
1003
- ignoreProcessEnv: true
1004
- } as any)
1005
-
1006
- // only keys that start with prefix are exposed to client
1007
- for (const [key, value] of Object.entries(parsed)) {
1008
- if (
1009
- prefixes.some((prefix) => key.startsWith(prefix)) &&
1010
- env[key] === undefined
1011
- ) {
1012
- env[key] = value
1013
- } else if (key === 'NODE_ENV') {
1014
- // NODE_ENV override in .env file
1015
- process.env.VITE_USER_NODE_ENV = value
1016
- }
1017
- }
1018
- }
1019
- }
1020
- return env
1021
- }
1022
-
1023
- export function resolveEnvPrefix({
1024
- envPrefix = 'VITE_'
1025
- }: UserConfig): string[] {
1026
- envPrefix = arraify(envPrefix)
1027
- if (envPrefix.some((prefix) => prefix === '')) {
1028
- throw new Error(
1029
- `envPrefix option contains value '', which could lead unexpected exposure of sensitive information.`
1030
- )
1031
- }
1032
- return envPrefix
1033
- }