feat(transformer/react): handle babel 8 breaking removed-options (#1489)

1. removed options react jsx
2. Passed 4 test cases.
This commit is contained in:
IWANABETHATGUY 2023-11-22 11:01:40 +08:00 committed by GitHub
parent f06f0f2078
commit b6393f052f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 16 deletions

View file

@ -94,7 +94,7 @@ impl<'a> Transformer<'a> {
es2015_shorthand_properties: ShorthandProperties::new(Rc::clone(&ast), &options),
es2015_template_literals: TemplateLiterals::new(Rc::clone(&ast), &options),
es3_property_literal: PropertyLiteral::new(Rc::clone(&ast ), &options),
react_jsx: options.react_jsx.map(|options| ReactJsx::new(Rc::clone(&ast), ctx.clone(), options)),
react_jsx: ReactJsx::new(Rc::clone(&ast), ctx.clone(), options)
}
}

View file

@ -24,6 +24,7 @@ pub struct TransformOptions {
pub sticky_regex: bool,
pub template_literals: bool,
pub property_literals: bool,
pub babel_8_breaking: Option<bool>,
}
/// See <https://www.typescriptlang.org/tsconfig#target>

View file

@ -15,7 +15,7 @@ use oxc_syntax::{
};
pub use self::options::{ReactJsxOptions, ReactJsxRuntime};
use crate::context::TransformerCtx;
use crate::{context::TransformerCtx, TransformOptions};
#[derive(Debug, Error, Diagnostic)]
#[error("pragma and pragmaFrag cannot be set when runtime is automatic.")]
@ -59,6 +59,7 @@ pub struct ReactJsx<'a> {
import_create_element: bool,
require_jsx_runtime: bool,
jsx_runtime_importer: Atom,
pub babel_8_breaking: Option<bool>,
}
enum JSXElementOrFragment<'a, 'b> {
@ -100,21 +101,35 @@ impl<'a, 'b> JSXElementOrFragment<'a, 'b> {
}
impl<'a> ReactJsx<'a> {
pub fn new(ast: Rc<AstBuilder<'a>>, ctx: TransformerCtx<'a>, options: ReactJsxOptions) -> Self {
pub fn new(
ast: Rc<AstBuilder<'a>>,
mut ctx: TransformerCtx<'a>,
options: TransformOptions,
) -> Option<Self> {
let imports = ast.new_vec();
let options = options.with_comments(&ctx.semantic());
let jsx_options = options.react_jsx?.with_comments(&ctx.semantic());
if options.babel_8_breaking == Some(true) {
if jsx_options.use_built_ins.is_some() {
ctx.error(miette::Error::msg("@babel/plugin-transform-react-jsx: Since \"useBuiltIns\" is removed in Babel 8, you can remove it from the config."));
return None;
}
if jsx_options.use_spread.is_some() {
ctx.error(miette::Error::msg("@babel/plugin-transform-react-jsx: Since Babel 8, an inline object with spread elements is always used, and the \"useSpread\" option is no longer available. Please remove it from your config."));
return None;
}
}
let jsx_runtime_importer =
if options.import_source == "react" || options.runtime.is_classic() {
if jsx_options.import_source == "react" || jsx_options.runtime.is_classic() {
Atom::new_inline("react/jsx-runtime")
} else {
Atom::from(format!("{}/jsx-runtime", options.import_source))
Atom::from(format!("{}/jsx-runtime", jsx_options.import_source))
};
Self {
Some(Self {
ast,
ctx,
options,
options: jsx_options,
imports,
jsx_runtime_importer,
require_jsx_runtime: false,
@ -122,7 +137,8 @@ impl<'a> ReactJsx<'a> {
import_jsxs: false,
import_fragment: false,
import_create_element: false,
}
babel_8_breaking: options.babel_8_breaking,
})
}
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {

View file

@ -7,6 +7,7 @@ use serde::Deserialize;
#[serde(rename_all = "camelCase")]
pub struct ReactJsxOptions {
/// Decides which runtime to use.
#[serde(default)]
pub runtime: ReactJsxRuntime,
/// Toggles whether or not to throw an error if an XML namespaced tag name is used. e.g. `<f:image />`
/// Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.
@ -25,6 +26,15 @@ pub struct ReactJsxOptions {
/// Replace the component used when compiling JSX fragments. It should be a valid JSX tag name. default to `React.Fragment`
#[serde(default = "default_pragma_frag")]
pub pragma_frag: Cow<'static, str>,
/// When spreading props, use Object.assign directly instead of Babel's extend helper.
/// Use `Some<T>` instead of `bool` because we want to know if user set this field explicitly,
/// which used for creating warning, https://github.com/oxc-project/oxc/blob/c3e2098c04d8916cb812bdd16d2026bb430ac25f/crates/oxc_transformer/src/react_jsx/mod.rs#L111-L114
pub use_built_ins: Option<bool>,
/// When spreading props, use inline object with spread elements directly instead of Babel's extend helper or Object.assign.
/// Use `Some<T>` instead of `bool` because we want to know if user set this field explicitly,
/// which used for creating warning, https://github.com/oxc-project/oxc/blob/c3e2098c04d8916cb812bdd16d2026bb430ac25f/crates/oxc_transformer/src/react_jsx/mod.rs#L111-L114
pub use_spread: Option<bool>,
}
fn default_throw_if_namespace() -> bool {
@ -51,6 +61,8 @@ impl Default for ReactJsxOptions {
import_source: default_import_source(),
pragma: default_pragma(),
pragma_frag: default_pragma_frag(),
use_built_ins: None,
use_spread: None,
}
}
}

View file

@ -1,4 +1,4 @@
Passed: 265/1081
Passed: 269/1081
# All Passed:
* babel-plugin-transform-numeric-separator
@ -844,7 +844,7 @@ Passed: 265/1081
* regression/11061/input.mjs
* variable-declaration/non-null-in-optional-chain/input.ts
# babel-plugin-transform-react-jsx (139/156)
# babel-plugin-transform-react-jsx (143/156)
* autoImport/after-polyfills-compiled-to-cjs/input.mjs
* autoImport/complicated-scope-module/input.js
* react/arrow-functions/input.js
@ -855,10 +855,6 @@ Passed: 265/1081
* react-automatic/should-throw-when-filter-is-specified/input.js
* regression/issue-12478-automatic/input.js
* regression/issue-12478-classic/input.js
* removed-options/invalid-use-builtins-false/input.js
* removed-options/invalid-use-builtins-true/input.js
* removed-options/invalid-use-spread-false/input.js
* removed-options/invalid-use-spread-true/input.js
* runtime/invalid-runtime/input.js
* spread-transform/transform-to-babel-extend/input.js
* spread-transform/transform-to-object-assign/input.js

View file

@ -88,6 +88,7 @@ pub trait TestCase {
let options = self.options();
TransformOptions {
target: TransformTarget::ESNext,
babel_8_breaking: options.babel_8_breaking,
react_jsx: options
.get_plugin("transform-react-jsx")
.map(get_options::<ReactJsxOptions>),