Skip to content

Commit

Permalink
feat(plugin-react): check for api.reactBabel on other plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
aleclarson committed Jan 4, 2022
1 parent 26c8207 commit 93e6578
Showing 1 changed file with 53 additions and 25 deletions.
78 changes: 53 additions & 25 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
import * as babel from '@babel/core'
import { createFilter } from '@rollup/pluginutils'
import resolve from 'resolve'
import type { Plugin, PluginOption } from 'vite'
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
import {
addRefreshWrapper,
isRefreshBoundary,
Expand Down Expand Up @@ -43,6 +43,24 @@ export interface Options {
parserPlugins?: ParserOptions['plugins']
}

type ReactBabelOptions = {
[P in keyof TransformOptions]-?: (P extends 'parserOpts'
? { plugins: Exclude<ParserOptions['plugins'], undefined> }
: unknown) &
Exclude<TransformOptions[P], null | undefined>
}

declare module 'vite' {
export interface Plugin {
api?: {
/**
* Manipulate the Babel options of `@vitejs/plugin-react`
*/
reactBabel?: (options: ReactBabelOptions, config: ResolvedConfig) => void
}
}
}

export default function viteReact(opts: Options = {}): PluginOption[] {
// Provide default values for Rollup compat.
let base = '/'
Expand All @@ -54,9 +72,16 @@ export default function viteReact(opts: Options = {}): PluginOption[] {

const useAutomaticRuntime = opts.jsxRuntime !== 'classic'

const userPlugins = opts.babel?.plugins || []
const userParserPlugins =
opts.parserPlugins || opts.babel?.parserOpts?.plugins || []
const babelOptions = {
babelrc: false,
configFile: false,
...opts.babel
} as ReactBabelOptions

babelOptions.plugins ||= []
babelOptions.presets ||= []
babelOptions.parserOpts ||= {} as any
babelOptions.parserOpts.plugins ||= opts.parserPlugins || []

// Support pattens like:
// - import * as React from 'react';
Expand Down Expand Up @@ -88,15 +113,21 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
)
}

config.plugins.forEach(
(plugin) =>
(plugin.name === 'react-refresh' ||
(plugin !== viteReactJsx && plugin.name === 'vite:react-jsx')) &&
config.logger.warn(
config.plugins.forEach((plugin) => {
const hasConflict =
plugin.name === 'react-refresh' ||
(plugin !== viteReactJsx && plugin.name === 'vite:react-jsx')

if (hasConflict)
return config.logger.warn(
`[@vitejs/plugin-react] You should stop using "${plugin.name}" ` +
`since this plugin conflicts with it.`
)
)

if (plugin.api?.reactBabel) {
plugin.api.reactBabel(babelOptions, config)
}
})
},
async transform(code, id, options) {
const ssr = typeof options === 'boolean' ? options : options?.ssr === true
Expand All @@ -108,10 +139,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
[]

if (/\.(mjs|[tj]sx?)$/.test(extension)) {
const plugins = [...userPlugins]
const plugins = [...babelOptions.plugins]

const parserPlugins: typeof userParserPlugins = [
...userParserPlugins,
const parserPlugins: typeof babelOptions.parserOpts.plugins = [
...babelOptions.parserOpts.plugins,
'importMeta',
// This plugin is applied before esbuild transforms the code,
// so we need to enable some stage 3 syntax that is supported in
Expand Down Expand Up @@ -191,35 +222,32 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
}
}

const isReasonReact = extension.endsWith('.bs.js')
const transformAsync = ast
? babel.transformFromAstAsync.bind(babel, ast, code)
: babel.transformAsync.bind(babel, code)

const babelOpts: TransformOptions = {
babelrc: false,
configFile: false,
...opts.babel,
const isReasonReact = extension.endsWith('.bs.js')
const result = await transformAsync({
...babelOptions,
ast: !isReasonReact,
root: projectRoot,
filename: id,
sourceFileName: id,
parserOpts: {
...opts.babel?.parserOpts,
...babelOptions.parserOpts,
sourceType: 'module',
allowAwaitOutsideFunction: true,
plugins: parserPlugins
},
generatorOpts: {
...opts.babel?.generatorOpts,
...babelOptions.generatorOpts,
decoratorsBeforeExport: true
},
plugins,
sourceMaps: true,
// Vite handles sourcemap flattening
inputSourceMap: false as any
}

const result = ast
? await babel.transformFromAstAsync(ast, code, babelOpts)
: await babel.transformAsync(code, babelOpts)
})

if (result) {
let code = result.code!
Expand Down

0 comments on commit 93e6578

Please sign in to comment.