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,925 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { Plugin } from '../plugin'
4
- import chalk from 'chalk'
5
- import {
6
- FS_PREFIX,
7
- SPECIAL_QUERY_RE,
8
- DEFAULT_EXTENSIONS,
9
- DEFAULT_MAIN_FIELDS,
10
- OPTIMIZABLE_ENTRY_RE
11
- } from '../constants'
12
- import {
13
- isBuiltin,
14
- bareImportRE,
15
- createDebugger,
16
- deepImportRE,
17
- injectQuery,
18
- isExternalUrl,
19
- isObject,
20
- normalizePath,
21
- fsPathFromId,
22
- ensureVolumeInPath,
23
- resolveFrom,
24
- isDataUrl,
25
- cleanUrl,
26
- slash,
27
- nestedResolveFrom
28
- } from '../utils'
29
- import { ViteDevServer, SSROptions } from '..'
30
- import { createFilter } from '@rollup/pluginutils'
31
- import { PartialResolvedId } from 'rollup'
32
- import { resolve as _resolveExports } from 'resolve.exports'
33
-
34
- // special id for paths marked with browser: false
35
- // https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module
36
- export const browserExternalId = '__vite-browser-external'
37
-
38
- const isDebug = process.env.DEBUG
39
- const debug = createDebugger('vite:resolve-details', {
40
- onlyWhenFocused: true
41
- })
42
-
43
- export interface ResolveOptions {
44
- mainFields?: string[]
45
- conditions?: string[]
46
- extensions?: string[]
47
- dedupe?: string[]
48
- preserveSymlinks?: boolean
49
- }
50
-
51
- export interface InternalResolveOptions extends ResolveOptions {
52
- root: string
53
- isBuild: boolean
54
- isProduction: boolean
55
- ssrConfig?: SSROptions
56
- /**
57
- * src code mode also attempts the following:
58
- * - resolving /xxx as URLs
59
- * - resolving bare imports from optimized deps
60
- */
61
- asSrc?: boolean
62
- tryIndex?: boolean
63
- tryPrefix?: string
64
- skipPackageJson?: boolean
65
- preferRelative?: boolean
66
- isRequire?: boolean
67
- }
68
-
69
- export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin {
70
- const {
71
- root,
72
- isProduction,
73
- asSrc,
74
- ssrConfig,
75
- preferRelative = false
76
- } = baseOptions
77
- const requireOptions: InternalResolveOptions = {
78
- ...baseOptions,
79
- isRequire: true
80
- }
81
- let server: ViteDevServer | undefined
82
-
83
- const { target: ssrTarget, noExternal: ssrNoExternal } = ssrConfig ?? {}
84
-
85
- return {
86
- name: 'vite:resolve',
87
-
88
- configureServer(_server) {
89
- server = _server
90
- },
91
-
92
- resolveId(id, importer, resolveOpts, ssr) {
93
- if (id.startsWith(browserExternalId)) {
94
- return id
95
- }
96
-
97
- // fast path for commonjs proxy modules
98
- if (/\?commonjs/.test(id) || id === 'commonjsHelpers.js') {
99
- return
100
- }
101
-
102
- const targetWeb = !ssr || ssrTarget === 'webworker'
103
-
104
- // this is passed by @rollup/plugin-commonjs
105
- const isRequire =
106
- resolveOpts &&
107
- resolveOpts.custom &&
108
- resolveOpts.custom['node-resolve'] &&
109
- resolveOpts.custom['node-resolve'].isRequire
110
-
111
- const options = isRequire ? requireOptions : baseOptions
112
-
113
- const preserveSymlinks = !!server?.config.resolve.preserveSymlinks
114
-
115
- let res: string | PartialResolvedId | undefined
116
-
117
- // explicit fs paths that starts with /@fs/*
118
- if (asSrc && id.startsWith(FS_PREFIX)) {
119
- const fsPath = fsPathFromId(id)
120
- res = tryFsResolve(fsPath, options, preserveSymlinks)
121
- isDebug && debug(`[@fs] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
122
- // always return here even if res doesn't exist since /@fs/ is explicit
123
- // if the file doesn't exist it should be a 404
124
- return res || fsPath
125
- }
126
-
127
- // URL
128
- // /foo -> /fs-root/foo
129
- if (asSrc && id.startsWith('/')) {
130
- const fsPath = path.resolve(root, id.slice(1))
131
- if ((res = tryFsResolve(fsPath, options, preserveSymlinks))) {
132
- isDebug && debug(`[url] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
133
- return res
134
- }
135
- }
136
-
137
- // relative
138
- if (id.startsWith('.') || (preferRelative && /^\w/.test(id))) {
139
- const basedir = importer ? path.dirname(importer) : process.cwd()
140
- const fsPath = path.resolve(basedir, id)
141
- // handle browser field mapping for relative imports
142
-
143
- const normalizedFsPath = normalizePath(fsPath)
144
- const pathFromBasedir = normalizedFsPath.slice(basedir.length)
145
- if (pathFromBasedir.startsWith('/node_modules/')) {
146
- // normalize direct imports from node_modules to bare imports, so the
147
- // hashing logic is shared and we avoid duplicated modules #2503
148
- const bareImport = pathFromBasedir.slice('/node_modules/'.length)
149
- if (
150
- (res = tryNodeResolve(
151
- bareImport,
152
- importer,
153
- options,
154
- targetWeb,
155
- server,
156
- ssr
157
- )) &&
158
- res.id.startsWith(normalizedFsPath)
159
- ) {
160
- return res
161
- }
162
- }
163
-
164
- if (
165
- targetWeb &&
166
- (res = tryResolveBrowserMapping(
167
- fsPath,
168
- importer,
169
- options,
170
- true,
171
- preserveSymlinks
172
- ))
173
- ) {
174
- return res
175
- }
176
-
177
- if ((res = tryFsResolve(fsPath, options, preserveSymlinks))) {
178
- isDebug && debug(`[relative] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
179
- const pkg = importer != null && idToPkgMap.get(importer)
180
- if (pkg) {
181
- idToPkgMap.set(res, pkg)
182
- return {
183
- id: res,
184
- moduleSideEffects: pkg.hasSideEffects(res)
185
- }
186
- }
187
- return res
188
- }
189
- }
190
-
191
- // absolute fs paths
192
- if (
193
- path.isAbsolute(id) &&
194
- (res = tryFsResolve(id, options, preserveSymlinks))
195
- ) {
196
- isDebug && debug(`[fs] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
197
- return res
198
- }
199
-
200
- // external
201
- if (isExternalUrl(id)) {
202
- return {
203
- id,
204
- external: true
205
- }
206
- }
207
-
208
- // data uri: pass through (this only happens during build and will be
209
- // handled by dedicated plugin)
210
- if (isDataUrl(id)) {
211
- return null
212
- }
213
-
214
- // bare package imports, perform node resolve
215
- if (bareImportRE.test(id)) {
216
- if (
217
- asSrc &&
218
- server &&
219
- !ssr &&
220
- (res = tryOptimizedResolve(id, server, importer))
221
- ) {
222
- return res
223
- }
224
-
225
- if (
226
- targetWeb &&
227
- (res = tryResolveBrowserMapping(
228
- id,
229
- importer,
230
- options,
231
- false,
232
- preserveSymlinks
233
- ))
234
- ) {
235
- return res
236
- }
237
-
238
- if (
239
- (res = tryNodeResolve(id, importer, options, targetWeb, server, ssr))
240
- ) {
241
- return res
242
- }
243
-
244
- // node built-ins.
245
- // externalize if building for SSR, otherwise redirect to empty module
246
- if (isBuiltin(id)) {
247
- if (ssr) {
248
- if (ssrNoExternal === true) {
249
- let message = `Cannot bundle Node.js built-in "${id}"`
250
- if (importer) {
251
- message += ` imported from "${path.relative(
252
- process.cwd(),
253
- importer
254
- )}"`
255
- }
256
- message += `. Consider disabling ssr.noExternal or remove the built-in dependency.`
257
- this.error(message)
258
- }
259
-
260
- return {
261
- id,
262
- external: true
263
- }
264
- } else {
265
- if (!asSrc) {
266
- debug(
267
- `externalized node built-in "${id}" to empty module. ` +
268
- `(imported by: ${chalk.white.dim(importer)})`
269
- )
270
- }
271
- return isProduction
272
- ? browserExternalId
273
- : `${browserExternalId}:${id}`
274
- }
275
- }
276
- }
277
-
278
- isDebug && debug(`[fallthrough] ${chalk.dim(id)}`)
279
- },
280
-
281
- load(id) {
282
- if (id.startsWith(browserExternalId)) {
283
- return isProduction
284
- ? `export default {}`
285
- : `export default new Proxy({}, {
286
- get() {
287
- throw new Error('Module "${id.slice(
288
- browserExternalId.length + 1
289
- )}" has been externalized for browser compatibility and cannot be accessed in client code.')
290
- }
291
- })`
292
- }
293
- }
294
- }
295
- }
296
-
297
- function tryFsResolve(
298
- fsPath: string,
299
- options: InternalResolveOptions,
300
- preserveSymlinks: boolean,
301
- tryIndex = true,
302
- targetWeb = true
303
- ): string | undefined {
304
- let file = fsPath
305
- let postfix = ''
306
-
307
- let postfixIndex = fsPath.indexOf('?')
308
- if (postfixIndex < 0) {
309
- postfixIndex = fsPath.indexOf('#')
310
- }
311
- if (postfixIndex > 0) {
312
- file = fsPath.slice(0, postfixIndex)
313
- postfix = fsPath.slice(postfixIndex)
314
- }
315
-
316
- let res: string | undefined
317
- if (
318
- (res = tryResolveFile(
319
- file,
320
- postfix,
321
- options,
322
- false,
323
- targetWeb,
324
- preserveSymlinks,
325
- options.tryPrefix,
326
- options.skipPackageJson
327
- ))
328
- ) {
329
- return res
330
- }
331
-
332
- for (const ext of options.extensions || DEFAULT_EXTENSIONS) {
333
- if (
334
- (res = tryResolveFile(
335
- file + ext,
336
- postfix,
337
- options,
338
- false,
339
- targetWeb,
340
- preserveSymlinks,
341
- options.tryPrefix,
342
- options.skipPackageJson
343
- ))
344
- ) {
345
- return res
346
- }
347
- }
348
-
349
- if (
350
- (res = tryResolveFile(
351
- file,
352
- postfix,
353
- options,
354
- tryIndex,
355
- targetWeb,
356
- preserveSymlinks,
357
- options.tryPrefix,
358
- options.skipPackageJson
359
- ))
360
- ) {
361
- return res
362
- }
363
- }
364
-
365
- function tryResolveFile(
366
- file: string,
367
- postfix: string,
368
- options: InternalResolveOptions,
369
- tryIndex: boolean,
370
- targetWeb: boolean,
371
- preserveSymlinks: boolean,
372
- tryPrefix?: string,
373
- skipPackageJson?: boolean
374
- ): string | undefined {
375
- let isReadable = false
376
- try {
377
- // #2051 if we don't have read permission on a directory, existsSync() still
378
- // works and will result in massively slow subsequent checks (which are
379
- // unnecessary in the first place)
380
- fs.accessSync(file, fs.constants.R_OK)
381
- isReadable = true
382
- } catch (e) {}
383
- if (isReadable) {
384
- if (!fs.statSync(file).isDirectory()) {
385
- return normalizePath(ensureVolumeInPath(file)) + postfix
386
- } else if (tryIndex) {
387
- if (!skipPackageJson) {
388
- const pkgPath = file + '/package.json'
389
- if (fs.existsSync(pkgPath)) {
390
- // path points to a node package
391
- const pkg = loadPackageData(pkgPath)
392
- const resolved = resolvePackageEntry(
393
- file,
394
- pkg,
395
- options,
396
- targetWeb,
397
- preserveSymlinks
398
- )
399
- return resolved ? getRealPath(resolved, preserveSymlinks) : resolved
400
- }
401
- }
402
- const index = tryFsResolve(file + '/index', options, preserveSymlinks)
403
- if (index) return index + postfix
404
- }
405
- }
406
- if (tryPrefix) {
407
- const prefixed = `${path.dirname(file)}/${tryPrefix}${path.basename(file)}`
408
- return tryResolveFile(
409
- prefixed,
410
- postfix,
411
- options,
412
- tryIndex,
413
- targetWeb,
414
- preserveSymlinks
415
- )
416
- }
417
- }
418
-
419
- export const idToPkgMap = new Map<string, PackageData>()
420
-
421
- export function tryNodeResolve(
422
- id: string,
423
- importer: string | undefined,
424
- options: InternalResolveOptions,
425
- targetWeb: boolean,
426
- server?: ViteDevServer,
427
- ssr?: boolean
428
- ): PartialResolvedId | undefined {
429
- const { root, dedupe, isBuild } = options
430
-
431
- // split id by last '>' for nested selected packages, for example:
432
- // 'foo > bar > baz' => 'foo > bar' & 'baz'
433
- // 'foo' => '' & 'foo'
434
- const lastArrowIndex = id.lastIndexOf('>')
435
- const nestedRoot = id.substring(0, lastArrowIndex).trim()
436
- const nestedPath = id.substring(lastArrowIndex + 1).trim()
437
-
438
- // check for deep import, e.g. "my-lib/foo"
439
- const deepMatch = nestedPath.match(deepImportRE)
440
-
441
- const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : nestedPath
442
-
443
- let basedir: string
444
- if (dedupe && dedupe.includes(pkgId)) {
445
- basedir = root
446
- } else if (
447
- importer &&
448
- path.isAbsolute(importer) &&
449
- fs.existsSync(cleanUrl(importer))
450
- ) {
451
- basedir = path.dirname(importer)
452
- } else {
453
- basedir = root
454
- }
455
-
456
- const preserveSymlinks = !!server?.config.resolve.preserveSymlinks
457
-
458
- // nested node module, step-by-step resolve to the basedir of the nestedPath
459
- if (nestedRoot) {
460
- basedir = nestedResolveFrom(nestedRoot, basedir, preserveSymlinks)
461
- }
462
-
463
- const pkg = resolvePackageData(pkgId, basedir, preserveSymlinks)
464
-
465
- if (!pkg) {
466
- return
467
- }
468
-
469
- let resolved = deepMatch
470
- ? resolveDeepImport(
471
- '.' + id.slice(pkgId.length),
472
- pkg,
473
- options,
474
- targetWeb,
475
- preserveSymlinks
476
- )
477
- : resolvePackageEntry(id, pkg, options, targetWeb, preserveSymlinks)
478
- if (!resolved) {
479
- return
480
- }
481
-
482
- resolved = getRealPath(resolved, preserveSymlinks)
483
-
484
- // link id to pkg for browser field mapping check
485
- idToPkgMap.set(resolved, pkg)
486
- if (isBuild) {
487
- // Resolve package side effects for build so that rollup can better
488
- // perform tree-shaking
489
- return {
490
- id: resolved,
491
- moduleSideEffects: pkg.hasSideEffects(resolved)
492
- }
493
- } else {
494
- if (
495
- !resolved.includes('node_modules') || // linked
496
- !server || // build
497
- server._isRunningOptimizer || // optimizing
498
- !server._optimizeDepsMetadata
499
- ) {
500
- return { id: resolved }
501
- }
502
- // if we reach here, it's a valid dep import that hasn't been optimized.
503
- const isJsType = OPTIMIZABLE_ENTRY_RE.test(resolved)
504
- const exclude = server.config.optimizeDeps?.exclude
505
- if (
506
- !isJsType ||
507
- importer?.includes('node_modules') ||
508
- exclude?.includes(pkgId) ||
509
- exclude?.includes(id) ||
510
- SPECIAL_QUERY_RE.test(resolved)
511
- ) {
512
- // excluded from optimization
513
- // Inject a version query to npm deps so that the browser
514
- // can cache it without re-validation, but only do so for known js types.
515
- // otherwise we may introduce duplicated modules for externalized files
516
- // from pre-bundled deps.
517
- const versionHash = server._optimizeDepsMetadata?.browserHash
518
- if (versionHash && isJsType) {
519
- resolved = injectQuery(resolved, `v=${versionHash}`)
520
- }
521
- } else {
522
- // this is a missing import.
523
- // queue optimize-deps re-run.
524
- server._registerMissingImport?.(id, resolved, ssr)
525
- }
526
- return { id: resolved }
527
- }
528
- }
529
-
530
- export function tryOptimizedResolve(
531
- id: string,
532
- server: ViteDevServer,
533
- importer?: string
534
- ): string | undefined {
535
- const cacheDir = server.config.cacheDir
536
- const depData = server._optimizeDepsMetadata
537
-
538
- if (!cacheDir || !depData) return
539
-
540
- const getOptimizedUrl = (optimizedData: typeof depData.optimized[string]) => {
541
- return (
542
- optimizedData.file +
543
- `?v=${depData.browserHash}${
544
- optimizedData.needsInterop ? `&es-interop` : ``
545
- }`
546
- )
547
- }
548
-
549
- // check if id has been optimized
550
- const isOptimized = depData.optimized[id]
551
- if (isOptimized) {
552
- return getOptimizedUrl(isOptimized)
553
- }
554
-
555
- if (!importer) return
556
-
557
- // further check if id is imported by nested dependency
558
- let resolvedSrc: string | undefined
559
-
560
- for (const [pkgPath, optimizedData] of Object.entries(depData.optimized)) {
561
- // check for scenarios, e.g.
562
- // pkgPath => "my-lib > foo"
563
- // id => "foo"
564
- // this narrows the need to do a full resolve
565
- if (!pkgPath.endsWith(id)) continue
566
-
567
- // lazily initialize resolvedSrc
568
- if (resolvedSrc == null) {
569
- try {
570
- // this may throw errors if unable to resolve, e.g. aliased id
571
- resolvedSrc = normalizePath(resolveFrom(id, path.dirname(importer)))
572
- } catch {
573
- // this is best-effort only so swallow errors
574
- break
575
- }
576
- }
577
-
578
- // match by src to correctly identify if id belongs to nested dependency
579
- if (optimizedData.src === resolvedSrc) {
580
- return getOptimizedUrl(optimizedData)
581
- }
582
- }
583
- }
584
-
585
- export interface PackageData {
586
- dir: string
587
- hasSideEffects: (id: string) => boolean
588
- webResolvedImports: Record<string, string | undefined>
589
- nodeResolvedImports: Record<string, string | undefined>
590
- setResolvedCache: (key: string, entry: string, targetWeb: boolean) => void
591
- getResolvedCache: (key: string, targetWeb: boolean) => string | undefined
592
- data: {
593
- [field: string]: any
594
- version: string
595
- main: string
596
- module: string
597
- browser: string | Record<string, string | false>
598
- exports: string | Record<string, any> | string[]
599
- dependencies: Record<string, string>
600
- }
601
- }
602
-
603
- const packageCache = new Map<string, PackageData>()
604
-
605
- export function resolvePackageData(
606
- id: string,
607
- basedir: string,
608
- preserveSymlinks = false
609
- ): PackageData | undefined {
610
- const cacheKey = id + basedir
611
- if (packageCache.has(cacheKey)) {
612
- return packageCache.get(cacheKey)
613
- }
614
- try {
615
- const pkgPath = resolveFrom(`${id}/package.json`, basedir, preserveSymlinks)
616
- return loadPackageData(pkgPath, cacheKey)
617
- } catch (e) {
618
- isDebug && debug(`${chalk.red(`[failed loading package.json]`)} ${id}`)
619
- }
620
- }
621
-
622
- function loadPackageData(pkgPath: string, cacheKey = pkgPath) {
623
- const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
624
- const pkgDir = path.dirname(pkgPath)
625
- const { sideEffects } = data
626
- let hasSideEffects: (id: string) => boolean
627
- if (typeof sideEffects === 'boolean') {
628
- hasSideEffects = () => sideEffects
629
- } else if (Array.isArray(sideEffects)) {
630
- hasSideEffects = createFilter(sideEffects, null, { resolve: pkgDir })
631
- } else {
632
- hasSideEffects = () => true
633
- }
634
-
635
- const pkg: PackageData = {
636
- dir: pkgDir,
637
- data,
638
- hasSideEffects,
639
- webResolvedImports: {},
640
- nodeResolvedImports: {},
641
- setResolvedCache(key: string, entry: string, targetWeb: boolean) {
642
- if (targetWeb) {
643
- pkg.webResolvedImports[key] = entry
644
- } else {
645
- pkg.nodeResolvedImports[key] = entry
646
- }
647
- },
648
- getResolvedCache(key: string, targetWeb: boolean) {
649
- if (targetWeb) {
650
- return pkg.webResolvedImports[key]
651
- } else {
652
- return pkg.nodeResolvedImports[key]
653
- }
654
- }
655
- }
656
- packageCache.set(cacheKey, pkg)
657
- return pkg
658
- }
659
-
660
- export function resolvePackageEntry(
661
- id: string,
662
- { dir, data, setResolvedCache, getResolvedCache }: PackageData,
663
- options: InternalResolveOptions,
664
- targetWeb: boolean,
665
- preserveSymlinks = false
666
- ): string | undefined {
667
- const cached = getResolvedCache('.', targetWeb)
668
- if (cached) {
669
- return cached
670
- }
671
- try {
672
- let entryPoint: string | undefined | void
673
-
674
- // resolve exports field with highest priority
675
- // using https://github.com/lukeed/resolve.exports
676
- if (data.exports) {
677
- entryPoint = resolveExports(data, '.', options, targetWeb)
678
- }
679
-
680
- // if exports resolved to .mjs, still resolve other fields.
681
- // This is because .mjs files can technically import .cjs files which would
682
- // make them invalid for pure ESM environments - so if other module/browser
683
- // fields are present, prioritize those instead.
684
- if (targetWeb && (!entryPoint || entryPoint.endsWith('.mjs'))) {
685
- // check browser field
686
- // https://github.com/defunctzombie/package-browser-field-spec
687
- const browserEntry =
688
- typeof data.browser === 'string'
689
- ? data.browser
690
- : isObject(data.browser) && data.browser['.']
691
- if (browserEntry) {
692
- // check if the package also has a "module" field.
693
- if (typeof data.module === 'string' && data.module !== browserEntry) {
694
- // if both are present, we may have a problem: some package points both
695
- // to ESM, with "module" targeting Node.js, while some packages points
696
- // "module" to browser ESM and "browser" to UMD.
697
- // the heuristics here is to actually read the browser entry when
698
- // possible and check for hints of UMD. If it is UMD, prefer "module"
699
- // instead; Otherwise, assume it's ESM and use it.
700
- const resolvedBrowserEntry = tryFsResolve(
701
- path.join(dir, browserEntry),
702
- options,
703
- preserveSymlinks
704
- )
705
- if (resolvedBrowserEntry) {
706
- const content = fs.readFileSync(resolvedBrowserEntry, 'utf-8')
707
- if (
708
- (/typeof exports\s*==/.test(content) &&
709
- /typeof module\s*==/.test(content)) ||
710
- /module\.exports\s*=/.test(content)
711
- ) {
712
- // likely UMD or CJS(!!! e.g. firebase 7.x), prefer module
713
- entryPoint = data.module
714
- }
715
- }
716
- } else {
717
- entryPoint = browserEntry
718
- }
719
- }
720
- }
721
-
722
- if (!entryPoint || entryPoint.endsWith('.mjs')) {
723
- for (const field of options.mainFields || DEFAULT_MAIN_FIELDS) {
724
- if (typeof data[field] === 'string') {
725
- entryPoint = data[field]
726
- break
727
- }
728
- }
729
- }
730
-
731
- entryPoint = entryPoint || data.main || 'index.js'
732
-
733
- // make sure we don't get scripts when looking for sass
734
- if (
735
- options.mainFields?.[0] === 'sass' &&
736
- !options.extensions?.includes(path.extname(entryPoint))
737
- ) {
738
- entryPoint = ''
739
- options.skipPackageJson = true
740
- }
741
-
742
- // resolve object browser field in package.json
743
- const { browser: browserField } = data
744
- if (targetWeb && isObject(browserField)) {
745
- entryPoint = mapWithBrowserField(entryPoint, browserField) || entryPoint
746
- }
747
-
748
- entryPoint = path.join(dir, entryPoint)
749
- const resolvedEntryPoint = tryFsResolve(
750
- entryPoint,
751
- options,
752
- preserveSymlinks
753
- )
754
-
755
- if (resolvedEntryPoint) {
756
- isDebug &&
757
- debug(
758
- `[package entry] ${chalk.cyan(id)} -> ${chalk.dim(
759
- resolvedEntryPoint
760
- )}`
761
- )
762
- setResolvedCache('.', resolvedEntryPoint, targetWeb)
763
- return resolvedEntryPoint
764
- } else {
765
- packageEntryFailure(id)
766
- }
767
- } catch (e) {
768
- packageEntryFailure(id, e.message)
769
- }
770
- }
771
-
772
- function packageEntryFailure(id: string, details?: string) {
773
- throw new Error(
774
- `Failed to resolve entry for package "${id}". ` +
775
- `The package may have incorrect main/module/exports specified in its package.json` +
776
- (details ? ': ' + details : '.')
777
- )
778
- }
779
-
780
- function resolveExports(
781
- pkg: PackageData['data'],
782
- key: string,
783
- options: InternalResolveOptions,
784
- targetWeb: boolean
785
- ) {
786
- const conditions = [options.isProduction ? 'production' : 'development']
787
- if (!options.isRequire) {
788
- conditions.push('module')
789
- }
790
- if (options.conditions) {
791
- conditions.push(...options.conditions)
792
- }
793
- return _resolveExports(pkg, key, {
794
- browser: targetWeb,
795
- require: options.isRequire,
796
- conditions
797
- })
798
- }
799
-
800
- function resolveDeepImport(
801
- id: string,
802
- {
803
- webResolvedImports,
804
- setResolvedCache,
805
- getResolvedCache,
806
- dir,
807
- data
808
- }: PackageData,
809
- options: InternalResolveOptions,
810
- targetWeb: boolean,
811
- preserveSymlinks: boolean
812
- ): string | undefined {
813
- const cache = getResolvedCache(id, targetWeb)
814
- if (cache) {
815
- return cache
816
- }
817
-
818
- let relativeId: string | undefined | void = id
819
- const { exports: exportsField, browser: browserField } = data
820
-
821
- // map relative based on exports data
822
- if (exportsField) {
823
- if (isObject(exportsField) && !Array.isArray(exportsField)) {
824
- relativeId = resolveExports(data, relativeId, options, targetWeb)
825
- } else {
826
- // not exposed
827
- relativeId = undefined
828
- }
829
- if (!relativeId) {
830
- throw new Error(
831
- `Package subpath '${relativeId}' is not defined by "exports" in ` +
832
- `${path.join(dir, 'package.json')}.`
833
- )
834
- }
835
- } else if (targetWeb && isObject(browserField)) {
836
- const mapped = mapWithBrowserField(relativeId, browserField)
837
- if (mapped) {
838
- relativeId = mapped
839
- } else if (mapped === false) {
840
- return (webResolvedImports[id] = browserExternalId)
841
- }
842
- }
843
-
844
- if (relativeId) {
845
- const resolved = tryFsResolve(
846
- path.join(dir, relativeId),
847
- options,
848
- preserveSymlinks,
849
- !exportsField, // try index only if no exports field
850
- targetWeb
851
- )
852
- if (resolved) {
853
- isDebug &&
854
- debug(`[node/deep-import] ${chalk.cyan(id)} -> ${chalk.dim(resolved)}`)
855
- setResolvedCache(id, resolved, targetWeb)
856
- return resolved
857
- }
858
- }
859
- }
860
-
861
- function tryResolveBrowserMapping(
862
- id: string,
863
- importer: string | undefined,
864
- options: InternalResolveOptions,
865
- isFilePath: boolean,
866
- preserveSymlinks: boolean
867
- ) {
868
- let res: string | undefined
869
- const pkg = importer && idToPkgMap.get(importer)
870
- if (pkg && isObject(pkg.data.browser)) {
871
- const mapId = isFilePath ? './' + slash(path.relative(pkg.dir, id)) : id
872
- const browserMappedPath = mapWithBrowserField(mapId, pkg.data.browser)
873
- if (browserMappedPath) {
874
- const fsPath = path.join(pkg.dir, browserMappedPath)
875
- if ((res = tryFsResolve(fsPath, options, preserveSymlinks))) {
876
- isDebug &&
877
- debug(`[browser mapped] ${chalk.cyan(id)} -> ${chalk.dim(res)}`)
878
- idToPkgMap.set(res, pkg)
879
- return {
880
- id: res,
881
- moduleSideEffects: pkg.hasSideEffects(res)
882
- }
883
- }
884
- } else if (browserMappedPath === false) {
885
- return browserExternalId
886
- }
887
- }
888
- }
889
-
890
- /**
891
- * given a relative path in pkg dir,
892
- * return a relative path in pkg dir,
893
- * mapped with the "map" object
894
- *
895
- * - Returning `undefined` means there is no browser mapping for this id
896
- * - Returning `false` means this id is explicitly externalized for browser
897
- */
898
- function mapWithBrowserField(
899
- relativePathInPkgDir: string,
900
- map: Record<string, string | false>
901
- ): string | false | undefined {
902
- const normalizedPath = path.posix.normalize(relativePathInPkgDir)
903
-
904
- for (const key in map) {
905
- const normalizedKey = path.posix.normalize(key)
906
- if (
907
- normalizedPath === normalizedKey ||
908
- equalWithoutSuffix(normalizedPath, normalizedKey, '.js') ||
909
- equalWithoutSuffix(normalizedPath, normalizedKey, '/index.js')
910
- ) {
911
- return map[key]
912
- }
913
- }
914
- }
915
-
916
- function equalWithoutSuffix(path: string, key: string, suffix: string) {
917
- return key.endsWith(suffix) && key.slice(0, -suffix.length) === path
918
- }
919
-
920
- function getRealPath(resolved: string, preserveSymlinks?: boolean): string {
921
- if (!preserveSymlinks && browserExternalId !== resolved) {
922
- return normalizePath(fs.realpathSync(resolved))
923
- }
924
- return resolved
925
- }