Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,52 @@ jobs:
- name: Test
run: pnpm run test

test-babel7:
timeout-minutes: 20
runs-on: ubuntu-latest
name: 'Test: babel 7 compat'
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0

- name: Set node version to 24
uses: actions/setup-node@v6
with:
node-version: 24
cache: 'pnpm'

- name: Override @babel/core to v7
run: yq -i '.overrides."@babel/core" = "^7.29.0"' pnpm-workspace.yaml

- name: Install deps
run: pnpm install --no-frozen-lockfile

- name: Install @babel/core v7 types
run: pnpm add -Dw @types/babel__core@^7.20.5

- name: Build
run: pnpm run build

- name: Test
run: pnpm run test

- name: Lint (type check)
run: pnpm run lint

test-passed:
if: (!cancelled() && !failure())
needs: test
needs: [test, test-babel7]
runs-on: ubuntu-latest
name: Build & Test Passed or Skipped
steps:
- run: echo "Build & Test Passed or Skipped"

test-failed:
if: (!cancelled() && failure())
needs: test
needs: [test, test-babel7]
runs-on: ubuntu-latest
name: Build & Test Failed
steps:
Expand Down
37 changes: 37 additions & 0 deletions packages/babel/src/babelCompat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* A type compatibility layer for Babel 7 and 8.
*/

export * from '@babel/core'

import * as babel from '@babel/core'

// https://github.com/type-challenges/type-challenges/issues/29285
type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false

// @ts-ignore -- InputOptions doesn't exist in Babel 7
type InputOptions8 = babel.InputOptions
// @ts-ignore -- PresetItem doesn't exist in Babel 7
type PresetItem8 = babel.PresetItem
// @ts-ignore -- PluginObject doesn't exist in Babel 7
type PluginObject8<T> = babel.PluginObject<T>
// @ts-ignore -- FileResult doesn't exist in Babel 7
type FileResult8 = babel.FileResult

// @ts-ignore -- TransformOptions doesn't exist in Babel 8
type TransformOptions = babel.TransformOptions
// @ts-ignore -- PluginObj doesn't exist in Babel 8
type PluginObj<T> = babel.PluginObj<T>
// @ts-ignore -- BabelFileResult doesn't exist in Babel 8
type BabelFileResult = babel.BabelFileResult

export type InputOptions = IsAny<InputOptions8> extends false ? InputOptions8 : TransformOptions
export type PresetItem = IsAny<PresetItem8> extends false ? PresetItem8 : babel.PluginItem
export type PluginObject<T = babel.PluginPass> =
IsAny<PluginObject8<T>> extends false ? PluginObject8<T> : PluginObj<T>
export type FileResult = IsAny<FileResult8> extends false ? FileResult8 : BabelFileResult

export const loadOptionsAsync: (
options?: InputOptions,
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
) => Promise<InputOptions & { plugins: babel.PluginItem[] }> = (babel as any).loadOptionsAsync
2 changes: 1 addition & 1 deletion packages/babel/src/filter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { HookFilter, GeneralHookFilter, ModuleTypeFilter } from 'rolldown'
import type { ResolvedPluginOptions } from './options'
import type { RolldownBabelPresetItem, RolldownBabelPreset } from './rolldownPreset'
import type { InputOptions } from '@babel/core'
import type { InputOptions } from './babelCompat'
import { arrayify } from './utils'

type ConfigApplicableTest = Exclude<InputOptions['include'], undefined>
Expand Down
7 changes: 4 additions & 3 deletions packages/babel/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { assert, describe, expect, test } from 'vitest'
import babelPlugin from './index.ts'
import * as babel from '@babel/core'
import * as babel from './babelCompat.ts'
import { rolldown, type OutputChunk } from 'rolldown'
import { build as viteBuild, createBuilder, type Rollup } from 'vite'
import path from 'node:path'
import { collectOptimizeDepsInclude, type PluginOptions } from './options.ts'
import type { RolldownBabelPreset } from './rolldownPreset.ts'
import { stripVTControlCharacters } from 'node:util'

test('plugin works', async () => {
const result = await build('foo.js', 'export const result = foo', {
Expand Down Expand Up @@ -226,7 +227,7 @@ test('wrapPluginVisitorMethod wraps visitor calls', async () => {
const result = await build('foo.js', 'export const result = foo', {
plugins: [identifierReplaceBabelPlugin('foo', true)],
wrapPluginVisitorMethod(_pluginAlias, _visitorType, callback) {
return function (this, p, state) {
return function (this: any, p, state) {
wrapCalled = true
return callback.call(this, p, state)
}
Expand Down Expand Up @@ -553,7 +554,7 @@ test('babel syntax error produces enhanced error message', async () => {
const err = await build('foo.js', 'export const = ;', {
plugins: [identifierReplaceBabelPlugin('foo', true)],
}).catch((e) => e)
const normalized = err.message
const normalized = stripVTControlCharacters(err.message)
.replace(/\r\n/g, '\n')
.replace(/(?:[A-Z]:)?[\\/][^\s:]+[\\/](?=foo\.js)/gi, '<cwd>/')
.replace(/\n {4,}at .+/g, '')
Expand Down
2 changes: 1 addition & 1 deletion packages/babel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
resolveOptions,
type PluginOptions,
} from './options.ts'
import * as babel from '@babel/core'
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'
Expand Down
2 changes: 1 addition & 1 deletion packages/babel/src/options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as babel from '@babel/core'
import * as babel from './babelCompat'
import type { ResolvedConfig } from 'vite'
import {
compilePresetFilter,
Expand Down
2 changes: 1 addition & 1 deletion packages/babel/src/rolldownPreset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
PresetConversionContext,
RolldownBabelPreset,
} from './rolldownPreset.ts'
import type * as babel from '@babel/core'
import type * as babel from './babelCompat.ts'
import type { ResolvedConfig } from 'vite'

const presetA: babel.PresetItem = () => ({ plugins: [] })
Expand Down
2 changes: 1 addition & 1 deletion packages/babel/src/rolldownPreset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as babel from '@babel/core'
import * as babel from './babelCompat.ts'
import type { GeneralHookFilter, ModuleTypeFilter } from 'rolldown'
import type { ResolvedConfig, Plugin as VitePlugin } from 'vite'
import picomatch from 'picomatch'
Expand Down