-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
/
esbuildDepPlugin.ts
91 lines (87 loc) · 2.58 KB
/
esbuildDepPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import path from 'path'
import { Plugin } from 'esbuild'
import { knownAssetTypes } from '../constants'
import { ResolvedConfig } from '..'
import chalk from 'chalk'
import { deepImportRE, isBuiltin } from '../utils'
import { tryNodeResolve } from '../plugins/resolve'
const externalTypes = ['css', 'vue', 'svelte', ...knownAssetTypes]
export function esbuildDepPlugin(
qualified: Record<string, string>,
config: ResolvedConfig,
transitiveOptimized: Record<string, true>
): Plugin {
return {
name: 'vite:dep-pre-bundle',
setup(build) {
// externalize assets and commonly known non-js file types
build.onResolve(
{
filter: new RegExp(`\\.(` + externalTypes.join('|') + `)(\\?.*)?$`)
},
({ path: _path, importer }) => {
if (_path.startsWith('.')) {
const dir = path.dirname(importer)
return {
path: path.resolve(dir, _path),
external: true
}
}
}
)
build.onResolve({ filter: /^[\w@]/ }, ({ path: id, importer }) => {
// ensure esbuild uses our resolved entires of optimized deps in all
// cases
if (id in qualified) {
return {
path: path.resolve(qualified[id])
}
} else if (!isBuiltin(id)) {
// record transitive deps
const deepMatch = id.match(deepImportRE)
const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : id
transitiveOptimized[pkgId] = true
const resolved = tryNodeResolve(
id,
path.dirname(importer),
false,
true,
config.dedupe,
config.root
)
if (resolved) {
return {
path: path.resolve(resolved.id)
}
}
} else {
// redirect node-builtins to empty module for browser
config.logger.warn(
chalk.yellow(
`externalized node built-in "${id}" to empty module. ` +
`(imported by: ${chalk.white.dim(importer)})`
)
)
return {
path: id,
namespace: 'browser-external'
}
}
})
build.onLoad(
{ filter: /.*/, namespace: 'browser-external' },
({ path: id }) => {
return {
contents:
`export default new Proxy({}, {
get() {
throw new Error('Module "${id}" has been externalized for ` +
`browser compatibility and cannot be accessed in client code.')
}
})`
}
}
)
}
}
}