Skip to content

Commit d4bface

Browse files
authored
fix: add proper babel 7 support (#6)
1 parent 03e7988 commit d4bface

8 files changed

Lines changed: 83 additions & 10 deletions

File tree

.github/workflows/ci.yml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,52 @@ jobs:
5454
- name: Test
5555
run: pnpm run test
5656

57+
test-babel7:
58+
timeout-minutes: 20
59+
runs-on: ubuntu-latest
60+
name: 'Test: babel 7 compat'
61+
steps:
62+
- name: Checkout
63+
uses: actions/checkout@v6
64+
65+
- name: Install pnpm
66+
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
67+
68+
- name: Set node version to 24
69+
uses: actions/setup-node@v6
70+
with:
71+
node-version: 24
72+
cache: 'pnpm'
73+
74+
- name: Override @babel/core to v7
75+
run: yq -i '.overrides."@babel/core" = "^7.29.0"' pnpm-workspace.yaml
76+
77+
- name: Install deps
78+
run: pnpm install --no-frozen-lockfile
79+
80+
- name: Install @babel/core v7 types
81+
run: pnpm add -Dw @types/babel__core@^7.20.5
82+
83+
- name: Build
84+
run: pnpm run build
85+
86+
- name: Test
87+
run: pnpm run test
88+
89+
- name: Lint (type check)
90+
run: pnpm run lint
91+
5792
test-passed:
5893
if: (!cancelled() && !failure())
59-
needs: test
94+
needs: [test, test-babel7]
6095
runs-on: ubuntu-latest
6196
name: Build & Test Passed or Skipped
6297
steps:
6398
- run: echo "Build & Test Passed or Skipped"
6499

65100
test-failed:
66101
if: (!cancelled() && failure())
67-
needs: test
102+
needs: [test, test-babel7]
68103
runs-on: ubuntu-latest
69104
name: Build & Test Failed
70105
steps:

packages/babel/src/babelCompat.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* A type compatibility layer for Babel 7 and 8.
3+
*/
4+
5+
export * from '@babel/core'
6+
7+
import * as babel from '@babel/core'
8+
9+
// https://github.com/type-challenges/type-challenges/issues/29285
10+
type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false
11+
12+
// @ts-ignore -- InputOptions doesn't exist in Babel 7
13+
type InputOptions8 = babel.InputOptions
14+
// @ts-ignore -- PresetItem doesn't exist in Babel 7
15+
type PresetItem8 = babel.PresetItem
16+
// @ts-ignore -- PluginObject doesn't exist in Babel 7
17+
type PluginObject8<T> = babel.PluginObject<T>
18+
// @ts-ignore -- FileResult doesn't exist in Babel 7
19+
type FileResult8 = babel.FileResult
20+
21+
// @ts-ignore -- TransformOptions doesn't exist in Babel 8
22+
type TransformOptions = babel.TransformOptions
23+
// @ts-ignore -- PluginObj doesn't exist in Babel 8
24+
type PluginObj<T> = babel.PluginObj<T>
25+
// @ts-ignore -- BabelFileResult doesn't exist in Babel 8
26+
type BabelFileResult = babel.BabelFileResult
27+
28+
export type InputOptions = IsAny<InputOptions8> extends false ? InputOptions8 : TransformOptions
29+
export type PresetItem = IsAny<PresetItem8> extends false ? PresetItem8 : babel.PluginItem
30+
export type PluginObject<T = babel.PluginPass> =
31+
IsAny<PluginObject8<T>> extends false ? PluginObject8<T> : PluginObj<T>
32+
export type FileResult = IsAny<FileResult8> extends false ? FileResult8 : BabelFileResult
33+
34+
export const loadOptionsAsync: (
35+
options?: InputOptions,
36+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
37+
) => Promise<InputOptions & { plugins: babel.PluginItem[] }> = (babel as any).loadOptionsAsync

packages/babel/src/filter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { HookFilter, GeneralHookFilter, ModuleTypeFilter } from 'rolldown'
22
import type { ResolvedPluginOptions } from './options'
33
import type { RolldownBabelPresetItem, RolldownBabelPreset } from './rolldownPreset'
4-
import type { InputOptions } from '@babel/core'
4+
import type { InputOptions } from './babelCompat'
55
import { arrayify } from './utils'
66

77
type ConfigApplicableTest = Exclude<InputOptions['include'], undefined>

packages/babel/src/index.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { assert, describe, expect, test } from 'vitest'
22
import babelPlugin from './index.ts'
3-
import * as babel from '@babel/core'
3+
import * as babel from './babelCompat.ts'
44
import { rolldown, type OutputChunk } from 'rolldown'
55
import { build as viteBuild, createBuilder, type Rollup } from 'vite'
66
import path from 'node:path'
77
import { collectOptimizeDepsInclude, type PluginOptions } from './options.ts'
88
import type { RolldownBabelPreset } from './rolldownPreset.ts'
9+
import { stripVTControlCharacters } from 'node:util'
910

1011
test('plugin works', async () => {
1112
const result = await build('foo.js', 'export const result = foo', {
@@ -226,7 +227,7 @@ test('wrapPluginVisitorMethod wraps visitor calls', async () => {
226227
const result = await build('foo.js', 'export const result = foo', {
227228
plugins: [identifierReplaceBabelPlugin('foo', true)],
228229
wrapPluginVisitorMethod(_pluginAlias, _visitorType, callback) {
229-
return function (this, p, state) {
230+
return function (this: any, p, state) {
230231
wrapCalled = true
231232
return callback.call(this, p, state)
232233
}
@@ -553,7 +554,7 @@ test('babel syntax error produces enhanced error message', async () => {
553554
const err = await build('foo.js', 'export const = ;', {
554555
plugins: [identifierReplaceBabelPlugin('foo', true)],
555556
}).catch((e) => e)
556-
const normalized = err.message
557+
const normalized = stripVTControlCharacters(err.message)
557558
.replace(/\r\n/g, '\n')
558559
.replace(/(?:[A-Z]:)?[\\/][^\s:]+[\\/](?=foo\.js)/gi, '<cwd>/')
559560
.replace(/\n {4,}at .+/g, '')

packages/babel/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
resolveOptions,
88
type PluginOptions,
99
} from './options.ts'
10-
import * as babel from '@babel/core'
10+
import * as babel from './babelCompat.ts'
1111
import type { PartialEnvironment, PresetConversionContext } from './rolldownPreset.ts'
1212
import { calculatePluginFilters } from './filter.ts'
1313
import type { ResolvedConfig, Plugin as VitePlugin } from 'vite'

packages/babel/src/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as babel from '@babel/core'
1+
import * as babel from './babelCompat'
22
import type { ResolvedConfig } from 'vite'
33
import {
44
compilePresetFilter,

packages/babel/src/rolldownPreset.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type {
1111
PresetConversionContext,
1212
RolldownBabelPreset,
1313
} from './rolldownPreset.ts'
14-
import type * as babel from '@babel/core'
14+
import type * as babel from './babelCompat.ts'
1515
import type { ResolvedConfig } from 'vite'
1616

1717
const presetA: babel.PresetItem = () => ({ plugins: [] })

packages/babel/src/rolldownPreset.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as babel from '@babel/core'
1+
import * as babel from './babelCompat.ts'
22
import type { GeneralHookFilter, ModuleTypeFilter } from 'rolldown'
33
import type { ResolvedConfig, Plugin as VitePlugin } from 'vite'
44
import picomatch from 'picomatch'

0 commit comments

Comments
 (0)