Skip to content

Commit

Permalink
docs(transformer): React: convert docs to standard format (#5891)
Browse files Browse the repository at this point in the history
Document React transforms in standardized style.
  • Loading branch information
overlookmotel committed Sep 19, 2024
1 parent cee9d0b commit 66b4688
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 53 deletions.
55 changes: 47 additions & 8 deletions crates/oxc_transformer/src/react/display_name.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
//! React Display Name
//!
//! Adds `displayName` property to `React.createClass` calls.
//!
//! > This plugin is included in `preset-react`.
//!
//! ## Example
//!
//! Input:
//! ```js
//! // some_filename.jsx
//! var foo = React.createClass({}); // React <= 15
//! bar = createReactClass({}); // React 16+
//!
//! var obj = { prop: React.createClass({}) };
//! obj.prop2 = React.createClass({});
//! obj["prop 3"] = React.createClass({});
//! export default React.createClass({});
//! ```
//!
//! Output:
//! ```js
//! var foo = React.createClass({ displayName: "foo" });
//! bar = createReactClass({ displayName: "bar" });
//!
//! var obj = { prop: React.createClass({ displayName: "prop" }) };
//! obj.prop2 = React.createClass({ displayName: "prop2" });
//! obj["prop 3"] = React.createClass({ displayName: "prop 3" });
//! export default React.createClass({ displayName: "some_filename" });
//! ```
//!
//! ## Implementation
//!
//! Implementation based on [@babel/plugin-transform-react-display-name](https://babeljs.io/docs/babel-plugin-transform-react-display-name).
//!
//! Babel does not get the display name for this example:
//!
//! ```js
//! obj["prop 3"] = React.createClass({});
//! ```
//!
//! This implementation does, which is a divergence from Babel, but probably an improvement.
//!
//! ## References:
//!
//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-display-name/src/index.ts>

use oxc_allocator::Box;
use oxc_ast::ast::*;
use oxc_span::{Atom, SPAN};
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};

use crate::context::Ctx;

/// [plugin-transform-react-display-name](https://babeljs.io/docs/babel-plugin-transform-react-display-name)
///
/// This plugin is included in `preset-react`.
///
/// ## Example
///
/// In: `var bar = createReactClass({});`
/// Out: `var bar = createReactClass({ displayName: "bar" });`
pub struct ReactDisplayName<'a> {
ctx: Ctx<'a>,
}
Expand Down
119 changes: 90 additions & 29 deletions crates/oxc_transformer/src/react/jsx.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,93 @@
//! React JSX
//!
//! This plugin transforms React JSX to JS.
//!
//! > This plugin is included in `preset-react`.
//!
//! Has two modes which create different output:
//! 1. Automatic
//! 2. Classic
//!
//! And also prod/dev modes:
//! 1. Production
//! 2. Development
//!
//! ## Example
//!
//! ### Automatic
//!
//! Input:
//! ```js
//! <div>foo</div>;
//! <Bar>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! Output:
//! ```js
//! // Production mode
//! import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
//! _jsx("div", { children: "foo" });
//! _jsx(Bar, { children: "foo" });
//! _jsx(_Fragment, { children: "foo" });
//! ```
//!
//! ```js
//! // Development mode
//! var _jsxFileName = "<CWD>/test.js";
//! import { jsxDEV as _jsxDEV, Fragment as _Fragment } from "react/jsx-dev-runtime";
//! _jsxDEV(
//! "div", { children: "foo" }, void 0, false,
//! { fileName: _jsxFileName, lineNumber: 1, columnNumber: 1 },
//! this
//! );
//! _jsxDEV(
//! Bar, { children: "foo" }, void 0, false,
//! { fileName: _jsxFileName, lineNumber: 2, columnNumber: 1 },
//! this
//! );
//! _jsxDEV(_Fragment, { children: "foo" }, void 0, false);
//! ```
//!
//! ### Classic
//!
//! Input:
//! ```js
//! <div>foo</div>;
//! <Bar>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! Output:
//! ```js
//! // Production mode
//! React.createElement("div", null, "foo");
//! React.createElement(Bar, null, "foo");
//! React.createElement(React.Fragment, null, "foo");
//! ```
//!
//! ```js
//! // Development mode
//! var _jsxFileName = "<CWD>/test.js";
//! React.createElement("div", {
//! __self: this,
//! __source: { fileName: _jsxFileName, lineNumber: 1, columnNumber: 1 }
//! }, "foo");
//! React.createElement(Bar, {
//! __self: this,
//! __source: { fileName: _jsxFileName, lineNumber: 2, columnNumber: 1 }
//! }, "foo");
//! React.createElement(React.Fragment, null, "foo");
//! ```
//!
//! ## Implementation
//!
//! Implementation based on [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/babel-plugin-transform-react-jsx).
//!
//! ## References:
//!
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-react-jsx>

use std::rc::Rc;

use oxc_allocator::Vec;
Expand All @@ -22,16 +112,6 @@ use crate::{
helpers::{bindings::BoundIdentifier, module_imports::NamedImport},
};

/// [plugin-transform-react-jsx](https://babeljs.io/docs/babel-plugin-transform-react-jsx)
///
/// This plugin generates production-ready JS code.
///
/// This plugin is included in `preset-react`.
///
/// References:
///
/// * <https://babeljs.io/docs/babel-plugin-transform-react-jsx>
/// * <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-react-jsx>
pub struct ReactJsx<'a> {
options: ReactOptions,

Expand Down Expand Up @@ -417,25 +497,6 @@ impl<'a> ReactJsx<'a> {
program.body.splice(index..index, imports);
}

/// ## Automatic
/// ### Element
/// Builds JSX into:
/// - Production: React.jsx(type, arguments, key)
/// - Development: React.jsxDEV(type, arguments, key, isStaticChildren, source, self)
///
/// ### Fragment
/// Builds JSX Fragment <></> into
/// - Production: React.jsx(type, arguments)
/// - Development: React.jsxDEV(type, { children })
///
/// ## Classic
/// ### Element
/// - Production: React.createElement(type, arguments, children)
/// - Development: React.createElement(type, arguments, children, source, self)
///
/// ### Fragment
/// React.createElement(React.Fragment, null, ...children)
///
fn transform_jsx<'b>(
&mut self,
e: &JSXElementOrFragment<'a, 'b>,
Expand Down
38 changes: 30 additions & 8 deletions crates/oxc_transformer/src/react/jsx_self.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
//! React JSX Self
//!
//! This plugin adds `__self` attribute to JSX elements.
//!
//! > This plugin is included in `preset-react`.
//!
//! ## Example
//!
//! Input:
//! ```js
//! <div>foo</div>;
//! <Bar>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! Output:
//! ```js
//! <div __self={this}>foo</div>;
//! <Bar __self={this}>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! ## Implementation
//!
//! Implementation based on [@babel/plugin-transform-react-jsx-self](https://babeljs.io/docs/babel-plugin-transform-react-jsx-self).
//!
//! ## References:
//!
//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-jsx-self/src/index.ts>

use oxc_ast::ast::*;
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{Span, SPAN};
Expand All @@ -7,14 +37,6 @@ use crate::context::Ctx;

const SELF: &str = "__self";

/// [plugin-transform-react-jsx-self](https://babeljs.io/docs/babel-plugin-transform-react-jsx-self)
///
/// This plugin is included in `preset-react` and only enabled in development mode.
///
/// ## Example
///
/// In: `<sometag />`
/// Out: `<sometag __self={this} />`
pub struct ReactJsxSelf<'a> {
ctx: Ctx<'a>,
}
Expand Down
43 changes: 35 additions & 8 deletions crates/oxc_transformer/src/react/jsx_source.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
//! React JSX Source
//!
//! This plugin adds `__source` attribute to JSX elements.
//!
//! > This plugin is included in `preset-react`.
//!
//! ## Example
//!
//! Input:
//! ```js
//! <div>foo</div>;
//! <Bar>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! Output:
//! ```js
//! var _jsxFileName = "<CWD>/test.js";
//! <div __source={
//! { fileName: _jsxFileName, lineNumber: 1, columnNumber: 1 }
//! }>foo</div>;
//! <Bar __source={
//! { fileName: _jsxFileName, lineNumber: 2, columnNumber: 1 }
//! }>foo</Bar>;
//! <>foo</>;
//! ```
//!
//! ## Implementation
//!
//! Implementation based on [@babel/plugin-transform-react-jsx-source](https://babeljs.io/docs/babel-plugin-transform-react-jsx-source).
//!
//! ## References:
//!
//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-jsx-source/src/index.ts>

use oxc_ast::{ast::*, NONE};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{Span, SPAN};
Expand All @@ -11,14 +46,6 @@ use crate::{context::Ctx, helpers::bindings::BoundIdentifier};
const SOURCE: &str = "__source";
const FILE_NAME_VAR: &str = "jsxFileName";

/// [plugin-transform-react-jsx-source](https://babeljs.io/docs/babel-plugin-transform-react-jsx-source)
///
/// This plugin is included in `preset-react` and only enabled in development mode.
///
/// ## Example
///
/// In: `<sometag />`
/// Out: `<sometag __source={ { fileName: 'this/file.js', lineNumber: 10, columnNumber: 1 } } />`
pub struct ReactJsxSource<'a> {
filename_var: Option<BoundIdentifier<'a>>,
source_rope: Option<Rope>,
Expand Down

0 comments on commit 66b4688

Please sign in to comment.