-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
147 lines (140 loc) · 4.98 KB
/
index.ts
File metadata and controls
147 lines (140 loc) · 4.98 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { Plugin, type HookFilter, type SourceMapInput } from 'rolldown'
import {
collectOptimizeDepsInclude,
createBabelOptionsConverter,
filterPresetsWithConfigResolved,
filterPresetsWithEnvironment,
resolveOptions,
type PluginOptions,
} from './options.ts'
import * as babel from './babelCompat.ts'
import type { PartialEnvironment, PresetConversionContext } from './rolldownPreset.ts'
import { calculatePluginFilters } from './filter.ts'
import type { ResolvedConfig, Plugin as VitePlugin } from 'vite'
async function babelPlugin(rawOptions: PluginOptions): Promise<Plugin> {
if (rawOptions.runtimeVersion) {
try {
import.meta.resolve('@babel/plugin-transform-runtime')
} catch (err) {
throw new Error(
`Failed to load @babel/plugin-transform-runtime. Please install it to use the runtime option.`,
{ cause: err },
)
}
}
let configFilteredOptions: PluginOptions | undefined
const envState = new Map<string | undefined, ReturnType<typeof createBabelOptionsConverter>>()
const plugin = {
name: '@rolldown/plugin-babel',
// this plugin should run before TS, JSX, TSX transformations are done
enforce: 'pre',
config() {
const include = collectOptimizeDepsInclude(rawOptions)
if (include.length > 0) {
return { optimizeDeps: { include } }
}
},
configResolved(config: ResolvedConfig) {
configFilteredOptions = filterPresetsWithConfigResolved(rawOptions, config)
const resolved = resolveOptions(configFilteredOptions)
plugin.transform.filter = calculatePluginFilters(resolved).transformFilter
},
applyToEnvironment(environment: PartialEnvironment) {
const envOptions = filterPresetsWithEnvironment(configFilteredOptions!, environment)
if (
!envOptions.presets?.length &&
!envOptions.plugins?.length &&
!envOptions.overrides?.some((o) => o.presets?.length || o.plugins?.length)
) {
return false
}
const resolved = resolveOptions(envOptions)
envState.set(environment.name, createBabelOptionsConverter(resolved))
return true
},
outputOptions() {
if (this.meta.viteVersion) return
const resolved = resolveOptions(rawOptions)
envState.set(undefined, createBabelOptionsConverter(resolved))
plugin.transform.filter = calculatePluginFilters(resolved).transformFilter
},
transform: {
filter: undefined as HookFilter | undefined,
async handler(code, id, opts) {
const convertToBabelOptions = envState.get(this.environment?.name)
if (!convertToBabelOptions) return
const conversionContext: PresetConversionContext = {
id,
moduleType: opts?.moduleType ?? 'js',
code,
}
const babelOptions = convertToBabelOptions(conversionContext)
const loadedOptions = await babel.loadOptionsAsync({
...babelOptions,
babelrc: false,
configFile: false,
parserOpts: {
sourceType: 'module',
allowAwaitOutsideFunction: true,
...babelOptions.parserOpts,
},
overrides: [
{
test: '**/*.jsx',
parserOpts: { plugins: ['jsx'] },
},
{
test: '**/*.ts',
parserOpts: { plugins: ['typescript'] },
},
{
test: '**/*.tsx',
parserOpts: { plugins: ['typescript', 'jsx'] },
},
...(babelOptions.overrides ?? []),
],
filename: id,
})
if (!loadedOptions || loadedOptions.plugins.length === 0) {
// No plugins to run — @babel/plugin-transform-runtime only affects
// how other plugins' helpers are emitted, so skip it too.
return
}
if (rawOptions.runtimeVersion) {
loadedOptions.plugins ??= []
loadedOptions.plugins.push([
'@babel/plugin-transform-runtime',
{ version: rawOptions.runtimeVersion },
])
}
let result: babel.FileResult | null
try {
result = await babel.transformAsync(
code,
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
loadedOptions as unknown as babel.InputOptions,
)
} catch (err: any) {
this.error({
message: `[BabelError] ${err.message}`,
loc: err.loc,
pos: err.pos,
cause: err,
pluginCode: `${err.code}:${err.reasonCode}`,
})
}
if (result) {
return {
code: result.code ?? undefined,
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
map: result.map as SourceMapInput,
}
}
},
},
} satisfies VitePlugin
return plugin as Plugin
}
export default babelPlugin
export { defineRolldownBabelPreset } from './rolldownPreset.ts'
export type { RolldownBabelPreset } from './rolldownPreset.ts'