Add experimental version of the `babel-plugin-transform-react-… (#11154)
* add next option for babel-plugin-transform-react-jsx * address review comments * chore: update test fixtures * Update fixture * Add "columnNumber" to the new React transform * Update windows fixtures * Delete unused output.js * Update windows tests * Fix windows again * fix comments Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com> Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com> Co-authored-by: Moti Zilberman <motiz88@gmail.com>
This commit is contained in:
parent
10aa97bc10
commit
748897be07
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "@babel/helper-builder-react-jsx-experimental",
|
||||
"version": "7.8.3",
|
||||
"description": "Helper function to build react jsx",
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-builder-react-jsx-experimental",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/types": "^7.8.3",
|
||||
"esutils": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,799 @@
|
||||
import esutils from "esutils";
|
||||
import * as t from "@babel/types";
|
||||
import { addNamed, addNamespace, isModule } from "@babel/helper-module-imports";
|
||||
|
||||
export function helper(babel, options) {
|
||||
const FILE_NAME_VAR = "_jsxFileName";
|
||||
|
||||
const JSX_SOURCE_ANNOTATION_REGEX = /\*?\s*@jsxImportSource\s+([^\s]+)/;
|
||||
const JSX_RUNTIME_ANNOTATION_REGEX = /\*?\s*@jsxRuntime\s+([^\s]+)/;
|
||||
|
||||
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
|
||||
const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/;
|
||||
|
||||
// This is the number of possible import names
|
||||
// development: jsxDEV, Fragment, createElement
|
||||
// production: jsx, jsxs, Fragment, createElement
|
||||
const IMPORT_NAME_SIZE = options.development ? 3 : 4;
|
||||
|
||||
const {
|
||||
importSource: IMPORT_SOURCE_DEFAULT = "react",
|
||||
runtime: RUNTIME_DEFAULT = "automatic",
|
||||
pragma: PRAGMA_DEFAULT = "React.createElement",
|
||||
pragmaFrag: PRAGMA_FRAG_DEFAULT = "React.Fragment",
|
||||
} = options;
|
||||
|
||||
return {
|
||||
JSXNamespacedName(path, state) {
|
||||
const throwIfNamespace =
|
||||
state.opts.throwIfNamespace === undefined
|
||||
? true
|
||||
: !!state.opts.throwIfNamespace;
|
||||
if (throwIfNamespace) {
|
||||
throw path.buildCodeFrameError(
|
||||
`Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
|
||||
You can set \`throwIfNamespace: false\` to bypass this warning.`,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
JSXSpreadChild(path) {
|
||||
throw path.buildCodeFrameError(
|
||||
"Spread children are not supported in React.",
|
||||
);
|
||||
},
|
||||
|
||||
JSXElement: {
|
||||
exit(path, file) {
|
||||
let callExpr;
|
||||
if (
|
||||
file.get("@babel/plugin-react-jsx/runtime") === "classic" ||
|
||||
shouldUseCreateElement(path)
|
||||
) {
|
||||
callExpr = buildCreateElementCall(path, file);
|
||||
} else {
|
||||
callExpr = buildJSXElementCall(path, file);
|
||||
}
|
||||
|
||||
path.replaceWith(t.inherits(callExpr, path.node));
|
||||
},
|
||||
},
|
||||
|
||||
JSXFragment: {
|
||||
exit(path, file) {
|
||||
let callExpr;
|
||||
if (file.get("@babel/plugin-react-jsx/runtime") === "classic") {
|
||||
callExpr = buildCreateElementFragmentCall(path, file);
|
||||
} else {
|
||||
callExpr = buildJSXFragmentCall(path, file);
|
||||
}
|
||||
|
||||
path.replaceWith(t.inherits(callExpr, path.node));
|
||||
},
|
||||
},
|
||||
|
||||
JSXAttribute(path) {
|
||||
if (t.isJSXElement(path.node.value)) {
|
||||
path.node.value = t.jsxExpressionContainer(path.node.value);
|
||||
}
|
||||
},
|
||||
|
||||
Program: {
|
||||
enter(path, state) {
|
||||
if (hasJSX(path)) {
|
||||
const { file } = state;
|
||||
let runtime = RUNTIME_DEFAULT;
|
||||
|
||||
// For jsx mode
|
||||
let source = IMPORT_SOURCE_DEFAULT;
|
||||
let sourceSet = !!options.importSource;
|
||||
|
||||
// For createElement mode
|
||||
let pragma = PRAGMA_DEFAULT;
|
||||
let pragmaFrag = PRAGMA_FRAG_DEFAULT;
|
||||
let pragmaSet = !!options.pragma;
|
||||
let pragmaFragSet = !!options.pragmaFrag;
|
||||
|
||||
if (file.ast.comments) {
|
||||
for (const comment of (file.ast.comments: Array<Object>)) {
|
||||
const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec(
|
||||
comment.value,
|
||||
);
|
||||
if (sourceMatches) {
|
||||
source = sourceMatches[1];
|
||||
sourceSet = true;
|
||||
}
|
||||
|
||||
const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec(
|
||||
comment.value,
|
||||
);
|
||||
if (runtimeMatches) {
|
||||
runtime = runtimeMatches[1];
|
||||
}
|
||||
|
||||
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxMatches) {
|
||||
pragma = jsxMatches[1];
|
||||
pragmaSet = true;
|
||||
}
|
||||
const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(
|
||||
comment.value,
|
||||
);
|
||||
if (jsxFragMatches) {
|
||||
pragmaFrag = jsxFragMatches[1];
|
||||
pragmaFragSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.set("@babel/plugin-react-jsx/runtime", runtime);
|
||||
if (runtime === "classic") {
|
||||
if (sourceSet) {
|
||||
throw path.buildCodeFrameError(
|
||||
`importSource cannot be set when runtime is classic.`,
|
||||
);
|
||||
}
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
createIdentifierParser(pragma),
|
||||
);
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/jsxFragIdentifier",
|
||||
createIdentifierParser(pragmaFrag),
|
||||
);
|
||||
state.set("@babel/plugin-react-jsx/usedFragment", false);
|
||||
state.set("@babel/plugin-react-jsx/pragmaSet", pragmaSet);
|
||||
state.set("@babel/plugin-react-jsx/pragmaFragSet", pragmaFragSet);
|
||||
} else if (runtime === "automatic") {
|
||||
if (pragmaSet || pragmaFragSet) {
|
||||
throw path.buildCodeFrameError(
|
||||
`pragma and pragmaFrag cannot be set when runtime is automatic.`,
|
||||
);
|
||||
}
|
||||
|
||||
const importName = addAutoImports(path, {
|
||||
...state.opts,
|
||||
source,
|
||||
});
|
||||
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/jsxIdentifier",
|
||||
createIdentifierParser(
|
||||
createIdentifierName(
|
||||
path,
|
||||
options.development ? "jsxDEV" : "jsx",
|
||||
importName,
|
||||
),
|
||||
),
|
||||
);
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/jsxStaticIdentifier",
|
||||
createIdentifierParser(
|
||||
createIdentifierName(
|
||||
path,
|
||||
options.development ? "jsxDEV" : "jsxs",
|
||||
importName,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
createIdentifierParser(
|
||||
createIdentifierName(path, "createElement", importName),
|
||||
),
|
||||
);
|
||||
|
||||
state.set(
|
||||
"@babel/plugin-react-jsx/jsxFragIdentifier",
|
||||
createIdentifierParser(
|
||||
createIdentifierName(path, "Fragment", importName),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
throw path.buildCodeFrameError(
|
||||
`Runtime must be either "classic" or "automatic".`,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
exit(path, state) {
|
||||
if (
|
||||
state.get("@babel/plugin-react-jsx/runtime") === "classic" &&
|
||||
state.get("@babel/plugin-react-jsx/pragmaSet") &&
|
||||
state.get("@babel/plugin-react-jsx/usedFragment") &&
|
||||
!state.get("@babel/plugin-react-jsx/pragmaFragSet")
|
||||
) {
|
||||
throw new Error(
|
||||
"transform-react-jsx: pragma has been set but " +
|
||||
"pragmaFrag has not been set",
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// We want to use React.createElement, even in the case of
|
||||
// jsx, for <div {...props} key={key} /> to distinguish it
|
||||
// from <div key={key} {...props} />. This is an intermediary
|
||||
// step while we deprecate key spread from props. Afterwards,
|
||||
// we will stop using createElement in the transform.
|
||||
function shouldUseCreateElement(path) {
|
||||
const openingPath = path.get("openingElement");
|
||||
const attributes = openingPath.node.attributes;
|
||||
|
||||
let seenPropsSpread = false;
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
const attr = attributes[i];
|
||||
if (
|
||||
seenPropsSpread &&
|
||||
t.isJSXAttribute(attr) &&
|
||||
attr.name.name === "key"
|
||||
) {
|
||||
return true;
|
||||
} else if (t.isJSXSpreadAttribute(attr)) {
|
||||
seenPropsSpread = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function createIdentifierName(path, name, importName) {
|
||||
if (isModule(path)) {
|
||||
const identifierName = `${importName[name]}`;
|
||||
return identifierName;
|
||||
} else {
|
||||
return `${importName[name]}.${name}`;
|
||||
}
|
||||
}
|
||||
|
||||
function getImportNames(parentPath) {
|
||||
const imports = new Set();
|
||||
|
||||
parentPath.traverse({
|
||||
"JSXElement|JSXFragment"(path) {
|
||||
if (path.type === "JSXFragment") imports.add("Fragment");
|
||||
const openingPath = path.get("openingElement");
|
||||
const validChildren = openingPath.parent.children.filter(
|
||||
child =>
|
||||
!t.isJSXEmptyExpression(child) &&
|
||||
!(t.isJSXText(child) && child.value.trim() === ""),
|
||||
);
|
||||
|
||||
let importName;
|
||||
if (path.type === "JSXElement" && shouldUseCreateElement(path)) {
|
||||
importName = "createElement";
|
||||
} else if (options.development) {
|
||||
importName = "jsxDEV";
|
||||
} else if (validChildren.length > 1) {
|
||||
importName = "jsxs";
|
||||
} else {
|
||||
importName = "jsx";
|
||||
}
|
||||
imports.add(importName);
|
||||
|
||||
if (imports.size === IMPORT_NAME_SIZE) {
|
||||
path.stop();
|
||||
}
|
||||
},
|
||||
});
|
||||
return imports;
|
||||
}
|
||||
|
||||
function hasJSX(parentPath) {
|
||||
let fileHasJSX = false;
|
||||
parentPath.traverse({
|
||||
"JSXElement|JSXFragment"(path) {
|
||||
fileHasJSX = true;
|
||||
path.stop();
|
||||
},
|
||||
});
|
||||
|
||||
return fileHasJSX;
|
||||
}
|
||||
|
||||
function getSource(source, importName) {
|
||||
switch (importName) {
|
||||
case "Fragment":
|
||||
return `${source}/${
|
||||
options.development ? "jsx-dev-runtime" : "jsx-runtime"
|
||||
}`;
|
||||
case "jsxDEV":
|
||||
return `${source}/jsx-dev-runtime`;
|
||||
case "jsx":
|
||||
case "jsxs":
|
||||
return `${source}/jsx-runtime`;
|
||||
case "createElement":
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
function addAutoImports(path, state) {
|
||||
const imports = getImportNames(path, state);
|
||||
if (isModule(path)) {
|
||||
// import {jsx} from "react";
|
||||
// import {createElement} from "react";
|
||||
const importMap = {};
|
||||
|
||||
imports.forEach(importName => {
|
||||
if (!importMap[importName]) {
|
||||
importMap[importName] = addNamed(
|
||||
path,
|
||||
importName,
|
||||
getSource(state.source, importName),
|
||||
{
|
||||
importedInterop: "uncompiled",
|
||||
ensureLiveReference: true,
|
||||
},
|
||||
).name;
|
||||
}
|
||||
});
|
||||
|
||||
return importMap;
|
||||
} else {
|
||||
const importMap = {};
|
||||
const sourceMap = {};
|
||||
imports.forEach(importName => {
|
||||
const source = getSource(state.source, importName);
|
||||
if (!importMap[importName]) {
|
||||
if (!sourceMap[source]) {
|
||||
// var _react = require("react")
|
||||
sourceMap[source] = addNamespace(path, source, {
|
||||
importedInterop: "uncompiled",
|
||||
ensureLiveReference: true,
|
||||
}).name;
|
||||
}
|
||||
|
||||
importMap[importName] = sourceMap[source];
|
||||
}
|
||||
});
|
||||
return importMap;
|
||||
}
|
||||
}
|
||||
|
||||
function createIdentifierParser(id) {
|
||||
return () => {
|
||||
return id
|
||||
.split(".")
|
||||
.map(name => t.identifier(name))
|
||||
.reduce((object, property) => t.memberExpression(object, property));
|
||||
};
|
||||
}
|
||||
|
||||
function makeTrace(fileNameIdentifier, lineNumber, column0Based) {
|
||||
const fileLineLiteral =
|
||||
lineNumber != null ? t.numericLiteral(lineNumber) : t.nullLiteral();
|
||||
|
||||
const fileColumnLiteral =
|
||||
column0Based != null
|
||||
? t.numericLiteral(column0Based + 1)
|
||||
: t.nullLiteral();
|
||||
|
||||
const fileNameProperty = t.objectProperty(
|
||||
t.identifier("fileName"),
|
||||
fileNameIdentifier,
|
||||
);
|
||||
const lineNumberProperty = t.objectProperty(
|
||||
t.identifier("lineNumber"),
|
||||
fileLineLiteral,
|
||||
);
|
||||
const columnNumberProperty = t.objectProperty(
|
||||
t.identifier("columnNumber"),
|
||||
fileColumnLiteral,
|
||||
);
|
||||
return t.objectExpression([
|
||||
fileNameProperty,
|
||||
lineNumberProperty,
|
||||
columnNumberProperty,
|
||||
]);
|
||||
}
|
||||
|
||||
function makeSource(path, state) {
|
||||
const location = path.node.openingElement.loc;
|
||||
if (!location) {
|
||||
// the element was generated and doesn't have location information
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.fileNameIdentifier) {
|
||||
const { filename = "" } = state;
|
||||
|
||||
const fileNameIdentifier = path.scope.generateUidIdentifier(
|
||||
FILE_NAME_VAR,
|
||||
);
|
||||
const scope = path.hub.getScope();
|
||||
if (scope) {
|
||||
scope.push({
|
||||
id: fileNameIdentifier,
|
||||
init: t.stringLiteral(filename),
|
||||
});
|
||||
}
|
||||
state.fileNameIdentifier = fileNameIdentifier;
|
||||
}
|
||||
|
||||
return makeTrace(
|
||||
state.fileNameIdentifier,
|
||||
location.start.line,
|
||||
location.start.column,
|
||||
);
|
||||
}
|
||||
|
||||
function convertJSXIdentifier(node, parent) {
|
||||
if (t.isJSXIdentifier(node)) {
|
||||
if (node.name === "this" && t.isReferenced(node, parent)) {
|
||||
return t.thisExpression();
|
||||
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
return t.stringLiteral(node.name);
|
||||
}
|
||||
} else if (t.isJSXMemberExpression(node)) {
|
||||
return t.memberExpression(
|
||||
convertJSXIdentifier(node.object, node),
|
||||
convertJSXIdentifier(node.property, node),
|
||||
);
|
||||
} else if (t.isJSXNamespacedName(node)) {
|
||||
/**
|
||||
* If the flag "throwIfNamespace" is false
|
||||
* print XMLNamespace like string literal
|
||||
*/
|
||||
return t.stringLiteral(`${node.namespace.name}:${node.name.name}`);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function convertAttributeValue(node) {
|
||||
if (t.isJSXExpressionContainer(node)) {
|
||||
return node.expression;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function convertAttribute(node) {
|
||||
const value = convertAttributeValue(node.value || t.booleanLiteral(true));
|
||||
|
||||
if (t.isJSXSpreadAttribute(node)) {
|
||||
return t.spreadElement(node.argument);
|
||||
}
|
||||
|
||||
if (t.isStringLiteral(value) && !t.isJSXExpressionContainer(node.value)) {
|
||||
value.value = value.value.replace(/\n\s+/g, " ");
|
||||
|
||||
// "raw" JSXText should not be used from a StringLiteral because it needs to be escaped.
|
||||
if (value.extra && value.extra.raw) {
|
||||
delete value.extra.raw;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isJSXNamespacedName(node.name)) {
|
||||
node.name = t.stringLiteral(
|
||||
node.name.namespace.name + ":" + node.name.name.name,
|
||||
);
|
||||
} else if (esutils.keyword.isIdentifierNameES6(node.name.name)) {
|
||||
node.name.type = "Identifier";
|
||||
} else {
|
||||
node.name = t.stringLiteral(node.name.name);
|
||||
}
|
||||
|
||||
return t.inherits(t.objectProperty(node.name, value), node);
|
||||
}
|
||||
|
||||
// Builds JSX into:
|
||||
// Production: React.jsx(type, arguments, key)
|
||||
// Development: React.jsxDEV(type, arguments, key, isStaticChildren, source, self)
|
||||
function buildJSXElementCall(path, file) {
|
||||
const openingPath = path.get("openingElement");
|
||||
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
|
||||
|
||||
const tagExpr = convertJSXIdentifier(
|
||||
openingPath.node.name,
|
||||
openingPath.node,
|
||||
);
|
||||
const args = [];
|
||||
|
||||
let tagName;
|
||||
if (t.isIdentifier(tagExpr)) {
|
||||
tagName = tagExpr.name;
|
||||
} else if (t.isLiteral(tagExpr)) {
|
||||
tagName = tagExpr.value;
|
||||
}
|
||||
|
||||
const state = {
|
||||
tagExpr: tagExpr,
|
||||
tagName: tagName,
|
||||
args: args,
|
||||
};
|
||||
|
||||
if (options.pre) {
|
||||
options.pre(state, file);
|
||||
}
|
||||
|
||||
let attribs = [];
|
||||
let key;
|
||||
let source;
|
||||
let self;
|
||||
|
||||
// for React.jsx, key, __source (dev), and __self (dev) is passed in as
|
||||
// a separate argument rather than in the args object. We go through the
|
||||
// props and filter out these three keywords so we can pass them in
|
||||
// as separate arguments later
|
||||
for (let i = 0; i < openingPath.node.attributes.length; i++) {
|
||||
const attr = openingPath.node.attributes[i];
|
||||
if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
|
||||
if (attr.name.name === "key") {
|
||||
key = convertAttribute(attr).value;
|
||||
} else if (
|
||||
attr.name.name === "__source" ||
|
||||
attr.name.name === "__self"
|
||||
) {
|
||||
throw path.buildCodeFrameError(
|
||||
`__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config.`,
|
||||
);
|
||||
} else {
|
||||
// If someone is still using the __source and __self Babel plugins
|
||||
// filter the results out
|
||||
attribs.push(attr);
|
||||
}
|
||||
} else {
|
||||
attribs.push(attr);
|
||||
}
|
||||
}
|
||||
|
||||
if (attribs.length || path.node.children.length) {
|
||||
attribs = buildJSXOpeningElementAttributes(
|
||||
attribs,
|
||||
file,
|
||||
path.node.children,
|
||||
);
|
||||
} else {
|
||||
// attributes should never be null
|
||||
attribs = t.objectExpression([]);
|
||||
}
|
||||
|
||||
args.push(attribs);
|
||||
|
||||
if (!options.development) {
|
||||
if (key !== undefined) {
|
||||
args.push(key);
|
||||
}
|
||||
} else {
|
||||
// isStaticChildren, __source, and __self are only used in development
|
||||
// automatically include __source and __self in this plugin
|
||||
// so we can eliminate the need for separate Babel plugins in Babel 8
|
||||
source = makeSource(path, file);
|
||||
self = t.thisExpression();
|
||||
args.push(
|
||||
key === undefined ? path.scope.buildUndefinedNode() : key,
|
||||
t.booleanLiteral(path.node.children.length > 1),
|
||||
source ?? path.scope.buildUndefinedNode(),
|
||||
self,
|
||||
);
|
||||
}
|
||||
|
||||
if (options.post) {
|
||||
options.post(state, file);
|
||||
}
|
||||
|
||||
return (
|
||||
state.call ||
|
||||
t.callExpression(
|
||||
path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee,
|
||||
args,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Builds props for React.jsx. This function adds children into the props
|
||||
// and ensures that props is always an object
|
||||
function buildJSXOpeningElementAttributes(attribs, file, children) {
|
||||
const _attribs = attribs.filter(
|
||||
prop =>
|
||||
!(
|
||||
t.isJSXAttribute(prop) &&
|
||||
prop.name &&
|
||||
(prop.name.name === "__source" || prop.name.name === "__self")
|
||||
),
|
||||
);
|
||||
|
||||
const props = _attribs.map(convertAttribute);
|
||||
|
||||
// In React.jsx, children is no longer a separate argument, but passed in
|
||||
// through the argument object
|
||||
if (children && children.length > 0) {
|
||||
if (children.length === 1) {
|
||||
props.push(t.objectProperty(t.identifier("children"), children[0]));
|
||||
} else {
|
||||
props.push(
|
||||
t.objectProperty(
|
||||
t.identifier("children"),
|
||||
t.arrayExpression(children),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return t.objectExpression(props);
|
||||
}
|
||||
|
||||
// Builds JSX Fragment <></> into
|
||||
// Production: React.jsx(type, arguments)
|
||||
// Development: React.jsxDEV(type, { children})
|
||||
function buildJSXFragmentCall(path, file) {
|
||||
const openingPath = path.get("openingElement");
|
||||
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
|
||||
|
||||
const args = [];
|
||||
const tagName = null;
|
||||
const tagExpr = file.get("@babel/plugin-react-jsx/jsxFragIdentifier")();
|
||||
|
||||
const state = {
|
||||
tagExpr: tagExpr,
|
||||
tagName: tagName,
|
||||
args: args,
|
||||
};
|
||||
|
||||
if (options.pre) {
|
||||
options.pre(state, file);
|
||||
}
|
||||
|
||||
let childrenNode;
|
||||
if (path.node.children.length > 0) {
|
||||
if (path.node.children.length === 1) {
|
||||
childrenNode = path.node.children[0];
|
||||
} else {
|
||||
childrenNode = t.arrayExpression(path.node.children);
|
||||
}
|
||||
}
|
||||
|
||||
args.push(
|
||||
t.objectExpression(
|
||||
childrenNode !== undefined
|
||||
? [t.objectProperty(t.identifier("children"), childrenNode)]
|
||||
: [],
|
||||
),
|
||||
);
|
||||
|
||||
if (options.development) {
|
||||
args.push(
|
||||
path.scope.buildUndefinedNode(),
|
||||
t.booleanLiteral(path.node.children.length > 1),
|
||||
);
|
||||
}
|
||||
|
||||
if (options.post) {
|
||||
options.post(state, file);
|
||||
}
|
||||
|
||||
return (
|
||||
state.call ||
|
||||
t.callExpression(
|
||||
path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee,
|
||||
args,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildCreateElementFragmentCall(path, file) {
|
||||
if (options.filter && !options.filter(path.node, file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const openingPath = path.get("openingElement");
|
||||
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
|
||||
|
||||
const args = [];
|
||||
const tagName = null;
|
||||
const tagExpr = file.get("@babel/plugin-react-jsx/jsxFragIdentifier")();
|
||||
|
||||
const state = {
|
||||
tagExpr: tagExpr,
|
||||
tagName: tagName,
|
||||
args: args,
|
||||
};
|
||||
|
||||
if (options.pre) {
|
||||
options.pre(state, file);
|
||||
}
|
||||
|
||||
// no attributes are allowed with <> syntax
|
||||
args.push(t.nullLiteral(), ...path.node.children);
|
||||
|
||||
if (options.post) {
|
||||
options.post(state, file);
|
||||
}
|
||||
|
||||
file.set("@babel/plugin-react-jsx/usedFragment", true);
|
||||
return state.call || t.callExpression(state.createElementCallee, args);
|
||||
}
|
||||
|
||||
// Builds JSX into:
|
||||
// Production: React.createElement(type, arguments, children)
|
||||
// Development: React.createElement(type, arguments, children, source, self)
|
||||
function buildCreateElementCall(path, file) {
|
||||
const openingPath = path.get("openingElement");
|
||||
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
|
||||
|
||||
const tagExpr = convertJSXIdentifier(
|
||||
openingPath.node.name,
|
||||
openingPath.node,
|
||||
);
|
||||
const args = [];
|
||||
|
||||
let tagName;
|
||||
if (t.isIdentifier(tagExpr)) {
|
||||
tagName = tagExpr.name;
|
||||
} else if (t.isLiteral(tagExpr)) {
|
||||
tagName = tagExpr.value;
|
||||
}
|
||||
|
||||
const state = {
|
||||
tagExpr: tagExpr,
|
||||
tagName: tagName,
|
||||
args: args,
|
||||
};
|
||||
|
||||
if (options.pre) {
|
||||
options.pre(state, file);
|
||||
}
|
||||
|
||||
const attribs = buildCreateElementOpeningElementAttributes(
|
||||
path,
|
||||
openingPath.node.attributes,
|
||||
file,
|
||||
);
|
||||
|
||||
args.push(attribs, ...path.node.children);
|
||||
|
||||
if (options.post) {
|
||||
options.post(state, file);
|
||||
}
|
||||
|
||||
return state.call || t.callExpression(state.createElementCallee, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logic for this is quite terse. It's because we need to
|
||||
* support spread elements. We loop over all attributes,
|
||||
* breaking on spreads, we then push a new object containing
|
||||
* all prior attributes to an array for later processing.
|
||||
*/
|
||||
function buildCreateElementOpeningElementAttributes(path, attribs, file) {
|
||||
// We want source and self to be automatically included in the future
|
||||
// so we will error when we see it
|
||||
|
||||
const hasSourceSelf = attribs.some(
|
||||
prop =>
|
||||
t.isJSXAttribute(prop) &&
|
||||
prop.name &&
|
||||
(prop.name.name === "__source" || prop.name.name === "__self"),
|
||||
);
|
||||
|
||||
if (hasSourceSelf) {
|
||||
throw path.buildCodeFrameError(
|
||||
`__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (options.development) {
|
||||
attribs.push(
|
||||
t.jsxAttribute(
|
||||
t.jsxIdentifier("__source"),
|
||||
t.jsxExpressionContainer(makeSource(path, file)),
|
||||
),
|
||||
);
|
||||
attribs.push(
|
||||
t.jsxAttribute(
|
||||
t.jsxIdentifier("__self"),
|
||||
t.jsxExpressionContainer(t.thisExpression()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const props = attribs.map(convertAttribute);
|
||||
|
||||
return props.length > 0 ? t.objectExpression(props) : t.nullLiteral();
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ export default function(opts) {
|
||||
if (opts.throwIfNamespace) {
|
||||
throw path.buildCodeFrameError(
|
||||
`Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
|
||||
You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
|
||||
You can set \`throwIfNamespace: false\` to bypass this warning.`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
src
|
||||
test
|
||||
*.log
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@babel/plugin-transform-react-jsx-development",
|
||||
"version": "7.8.3",
|
||||
"description": "Turn JSX into React function calls in development",
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-development",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"keywords": [
|
||||
"babel-plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/helper-builder-react-jsx-experimental": "^7.8.3",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/plugin-syntax-jsx": "^7.8.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.3",
|
||||
"@babel/helper-plugin-test-runner": "^7.8.3"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
import jsx from "@babel/plugin-syntax-jsx";
|
||||
import { helper } from "@babel/helper-builder-react-jsx-experimental";
|
||||
import { declare } from "@babel/helper-plugin-utils";
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default declare((api, options) => {
|
||||
const visitor = helper(api, {
|
||||
pre(state) {
|
||||
const tagName = state.tagName;
|
||||
const args = state.args;
|
||||
if (t.react.isCompatTag(tagName)) {
|
||||
args.push(t.stringLiteral(tagName));
|
||||
} else {
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
post(state, pass) {
|
||||
if (pass.get("@babel/plugin-react-jsx/runtime") === "classic") {
|
||||
state.createElementCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
)();
|
||||
} else {
|
||||
state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")();
|
||||
state.jsxStaticCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/jsxStaticIdentifier",
|
||||
)();
|
||||
state.createElementCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
)();
|
||||
}
|
||||
},
|
||||
|
||||
...options,
|
||||
development: true,
|
||||
});
|
||||
|
||||
return {
|
||||
name: "transform-react-jsx",
|
||||
inherits: jsx,
|
||||
visitor,
|
||||
};
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": ["transform-react-jsx-development"],
|
||||
"sourceType": "module",
|
||||
"os": ["linux", "darwin"]
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
import { createElement as _createElement } from "react";
|
||||
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
|
||||
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/auto-import-dev/input.js";
|
||||
|
||||
var x = _jsxDEV(_Fragment, {
|
||||
children: _jsxDEV("div", {
|
||||
children: [_jsxDEV("div", {}, "1", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 7
|
||||
}, this), _jsxDEV("div", {
|
||||
meow: "wolf"
|
||||
}, "2", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 5,
|
||||
columnNumber: 7
|
||||
}, this), _jsxDEV("div", {}, "3", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 6,
|
||||
columnNumber: 7
|
||||
}, this), _createElement("div", { ...props,
|
||||
key: "4",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 7,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
})]
|
||||
}, void 0, true, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 5
|
||||
}, this)
|
||||
}, void 0, false);
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
["transform-react-jsx-development", { "runtime": "classic" }],
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"os": ["linux", "darwin"],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx-development", { "runtime": "classic" }]],
|
||||
"os": ["linux", "darwin"]
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/classic-runtime/input.js";
|
||||
var x = React.createElement(React.Fragment, null, React.createElement("div", {
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 5
|
||||
},
|
||||
__self: this
|
||||
}, React.createElement("div", {
|
||||
key: "1",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 9
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", {
|
||||
key: "2",
|
||||
meow: "wolf",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 5,
|
||||
columnNumber: 9
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", {
|
||||
key: "3",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 6,
|
||||
columnNumber: 9
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", { ...props,
|
||||
key: "4",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 7,
|
||||
columnNumber: 9
|
||||
},
|
||||
__self: this
|
||||
})));
|
||||
1
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/input.js
vendored
Normal file
1
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/input.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var x = <><div /></>;
|
||||
11
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/output.js
vendored
Normal file
11
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/output.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, {
|
||||
children: _reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
}, void 0, false);
|
||||
@ -0,0 +1 @@
|
||||
var x = <React.Fragment key="foo"></React.Fragment>;
|
||||
@ -0,0 +1,9 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-fragments-with-key/input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 9
|
||||
}, this);
|
||||
@ -0,0 +1 @@
|
||||
var x = <div>{[<span key={"0"} />, <span key={"1"} />]}</div>;
|
||||
@ -0,0 +1,19 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-nonstatic-children/input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV("div", {
|
||||
children: [_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 16
|
||||
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, "1", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 36
|
||||
}, this)]
|
||||
}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 9
|
||||
}, this);
|
||||
@ -0,0 +1,6 @@
|
||||
var x = (
|
||||
<div>
|
||||
<span />
|
||||
{[<span key={"0"} />, <span key={"1"} />]}
|
||||
</div>
|
||||
);
|
||||
@ -0,0 +1,23 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-static-children/input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV("div", {
|
||||
children: [_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 5
|
||||
}, this), [_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 7
|
||||
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, "1", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 27
|
||||
}, this)]]
|
||||
}, void 0, true, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 2,
|
||||
columnNumber: 3
|
||||
}, this);
|
||||
9
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/options.json
vendored
Normal file
9
packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/options.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
"external-helpers",
|
||||
"transform-react-jsx-development",
|
||||
"transform-react-display-name",
|
||||
"transform-arrow-functions"
|
||||
],
|
||||
"os": ["linux", "darwin"]
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"plugins": [
|
||||
"transform-react-jsx-development",
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"sourceType": "module",
|
||||
"os": ["linux", "darwin"],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": ["transform-react-jsx-development"],
|
||||
"sourceType": "module"
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
import { createElement as _createElement } from "react";
|
||||
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
|
||||
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\auto-import-dev-windows\\input.js";
|
||||
|
||||
var x = _jsxDEV(_Fragment, {
|
||||
children: _jsxDEV("div", {
|
||||
children: [_jsxDEV("div", {}, "1", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 7
|
||||
}, this), _jsxDEV("div", {
|
||||
meow: "wolf"
|
||||
}, "2", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 5,
|
||||
columnNumber: 7
|
||||
}, this), _jsxDEV("div", {}, "3", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 6,
|
||||
columnNumber: 7
|
||||
}, this), _createElement("div", { ...props,
|
||||
key: "4",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 7,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
})]
|
||||
}, void 0, true, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 5
|
||||
}, this)
|
||||
}, void 0, false);
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx-development", { "runtime": "classic" }]]
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\classic-runtime-windows\\input.js";
|
||||
var x = React.createElement(React.Fragment, null, React.createElement("div", {
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 5
|
||||
},
|
||||
__self: this
|
||||
}, React.createElement("div", {
|
||||
key: "1",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", {
|
||||
key: "2",
|
||||
meow: "wolf",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 5,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", {
|
||||
key: "3",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 6,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
}), React.createElement("div", { ...props,
|
||||
key: "4",
|
||||
__source: {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 7,
|
||||
columnNumber: 7
|
||||
},
|
||||
__self: this
|
||||
})));
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugins": [
|
||||
["transform-react-jsx-development", { "runtime": "classic" }],
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
var x = <><div /></>;
|
||||
@ -0,0 +1,11 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\fragments-windows\\input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, {
|
||||
children: _reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
}, void 0, false);
|
||||
@ -0,0 +1 @@
|
||||
var x = <React.Fragment key='foo'></React.Fragment>;
|
||||
@ -0,0 +1,9 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-fragments-with-key-windows\\input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 1,
|
||||
columnNumber: 9
|
||||
}, this);
|
||||
@ -0,0 +1,5 @@
|
||||
var x = (
|
||||
<div>
|
||||
{[<span key={'0'} />, <span key={'1'} />]}
|
||||
</div>
|
||||
);
|
||||
@ -0,0 +1,19 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-nonstatic-children-windows\\input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV("div", {
|
||||
children: [_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 11
|
||||
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, '1', false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 31
|
||||
}, this)]
|
||||
}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 2,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
@ -0,0 +1,6 @@
|
||||
var x = (
|
||||
<div>
|
||||
<span />
|
||||
{[<span key={'0'} />, <span key={'1'} />]}
|
||||
</div>
|
||||
);
|
||||
@ -0,0 +1,23 @@
|
||||
var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
|
||||
|
||||
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-static-children-windows\\input.js";
|
||||
|
||||
var x = _reactJsxDevRuntime.jsxDEV("div", {
|
||||
children: [_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 3,
|
||||
columnNumber: 9
|
||||
}, this), [_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 11
|
||||
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, '1', false, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 4,
|
||||
columnNumber: 31
|
||||
}, this)]]
|
||||
}, void 0, true, {
|
||||
fileName: _jsxFileName,
|
||||
lineNumber: 2,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
9
packages/babel-plugin-transform-react-jsx-development/test/fixtures/windows/options.json
vendored
Normal file
9
packages/babel-plugin-transform-react-jsx-development/test/fixtures/windows/options.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
"external-helpers",
|
||||
"transform-react-jsx-development",
|
||||
"transform-react-display-name",
|
||||
"transform-arrow-functions"
|
||||
],
|
||||
"os": ["win32"]
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"plugins": [
|
||||
"transform-react-jsx-development",
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"sourceType": "module",
|
||||
"os": ["windows"],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
import runner from "@babel/helper-plugin-test-runner";
|
||||
|
||||
runner(__dirname);
|
||||
@ -1,3 +1,4 @@
|
||||
{
|
||||
"plugins": ["syntax-jsx", "transform-react-jsx-self"]
|
||||
"plugins": ["syntax-jsx", "transform-react-jsx-self"],
|
||||
"sourceType": "script"
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/helper-builder-react-jsx": "^7.8.3",
|
||||
"@babel/helper-builder-react-jsx-experimental": "^7.8.3",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/plugin-syntax-jsx": "^7.8.3"
|
||||
},
|
||||
|
||||
@ -1,100 +1,18 @@
|
||||
/* eslint-disable-next-line @babel/development/plugin-name */
|
||||
import transformClassic from "./transform-classic";
|
||||
/* eslint-disable-next-line @babel/development/plugin-name */
|
||||
import transformAutomatic from "./transform-automatic";
|
||||
import { declare } from "@babel/helper-plugin-utils";
|
||||
import jsx from "@babel/plugin-syntax-jsx";
|
||||
import helper from "@babel/helper-builder-react-jsx";
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default declare((api, options) => {
|
||||
api.assertVersion(7);
|
||||
const { runtime = "classic" } = options;
|
||||
|
||||
const THROW_IF_NAMESPACE =
|
||||
options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace;
|
||||
|
||||
const PRAGMA_DEFAULT = options.pragma || "React.createElement";
|
||||
const PRAGMA_FRAG_DEFAULT = options.pragmaFrag || "React.Fragment";
|
||||
|
||||
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
|
||||
const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/;
|
||||
|
||||
// returns a closure that returns an identifier or memberExpression node
|
||||
// based on the given id
|
||||
const createIdentifierParser = (id: string) => () => {
|
||||
return id
|
||||
.split(".")
|
||||
.map(name => t.identifier(name))
|
||||
.reduce((object, property) => t.memberExpression(object, property));
|
||||
};
|
||||
|
||||
const visitor = helper({
|
||||
pre(state) {
|
||||
const tagName = state.tagName;
|
||||
const args = state.args;
|
||||
if (t.react.isCompatTag(tagName)) {
|
||||
args.push(t.stringLiteral(tagName));
|
||||
} else {
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
post(state, pass) {
|
||||
state.callee = pass.get("jsxIdentifier")();
|
||||
},
|
||||
|
||||
throwIfNamespace: THROW_IF_NAMESPACE,
|
||||
});
|
||||
|
||||
visitor.Program = {
|
||||
enter(path, state) {
|
||||
const { file } = state;
|
||||
|
||||
let pragma = PRAGMA_DEFAULT;
|
||||
let pragmaFrag = PRAGMA_FRAG_DEFAULT;
|
||||
let pragmaSet = !!options.pragma;
|
||||
let pragmaFragSet = !!options.pragmaFrag;
|
||||
|
||||
if (file.ast.comments) {
|
||||
for (const comment of (file.ast.comments: Array<Object>)) {
|
||||
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxMatches) {
|
||||
pragma = jsxMatches[1];
|
||||
pragmaSet = true;
|
||||
}
|
||||
const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxFragMatches) {
|
||||
pragmaFrag = jsxFragMatches[1];
|
||||
pragmaFragSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.set("jsxIdentifier", createIdentifierParser(pragma));
|
||||
state.set("jsxFragIdentifier", createIdentifierParser(pragmaFrag));
|
||||
state.set("usedFragment", false);
|
||||
state.set("pragmaSet", pragmaSet);
|
||||
state.set("pragmaFragSet", pragmaFragSet);
|
||||
},
|
||||
exit(path, state) {
|
||||
if (
|
||||
state.get("pragmaSet") &&
|
||||
state.get("usedFragment") &&
|
||||
!state.get("pragmaFragSet")
|
||||
) {
|
||||
throw new Error(
|
||||
"transform-react-jsx: pragma has been set but " +
|
||||
"pragmaFrag has not been set",
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
visitor.JSXAttribute = function(path) {
|
||||
if (t.isJSXElement(path.node.value)) {
|
||||
path.node.value = t.jsxExpressionContainer(path.node.value);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
name: "transform-react-jsx",
|
||||
inherits: jsx,
|
||||
visitor,
|
||||
};
|
||||
// we throw a warning in helper-builder-react-jsx-experimental if runtime
|
||||
// is neither automatic or classic because we will remove this file
|
||||
// in v8.0.0
|
||||
if (runtime === "classic") {
|
||||
return transformClassic(api, options);
|
||||
} else {
|
||||
return transformAutomatic(api, options);
|
||||
}
|
||||
});
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
import jsx from "@babel/plugin-syntax-jsx";
|
||||
import { helper } from "@babel/helper-builder-react-jsx-experimental";
|
||||
import { declare } from "@babel/helper-plugin-utils";
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default declare((api, options) => {
|
||||
const visitor = helper(api, {
|
||||
pre(state) {
|
||||
const tagName = state.tagName;
|
||||
const args = state.args;
|
||||
if (t.react.isCompatTag(tagName)) {
|
||||
args.push(t.stringLiteral(tagName));
|
||||
} else {
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
post(state, pass) {
|
||||
if (pass.get("@babel/plugin-react-jsx/runtime") === "classic") {
|
||||
state.createElementCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
)();
|
||||
} else {
|
||||
state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")();
|
||||
state.jsxStaticCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/jsxStaticIdentifier",
|
||||
)();
|
||||
state.createElementCallee = pass.get(
|
||||
"@babel/plugin-react-jsx/createElementIdentifier",
|
||||
)();
|
||||
}
|
||||
},
|
||||
|
||||
...options,
|
||||
development: false,
|
||||
});
|
||||
|
||||
return {
|
||||
name: "transform-react-jsx",
|
||||
inherits: jsx,
|
||||
visitor,
|
||||
};
|
||||
});
|
||||
@ -0,0 +1,98 @@
|
||||
import { declare } from "@babel/helper-plugin-utils";
|
||||
import jsx from "@babel/plugin-syntax-jsx";
|
||||
import helper from "@babel/helper-builder-react-jsx";
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default declare((api, options) => {
|
||||
const THROW_IF_NAMESPACE =
|
||||
options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace;
|
||||
|
||||
const PRAGMA_DEFAULT = options.pragma || "React.createElement";
|
||||
const PRAGMA_FRAG_DEFAULT = options.pragmaFrag || "React.Fragment";
|
||||
|
||||
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
|
||||
const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/;
|
||||
|
||||
// returns a closure that returns an identifier or memberExpression node
|
||||
// based on the given id
|
||||
const createIdentifierParser = (id: string) => () => {
|
||||
return id
|
||||
.split(".")
|
||||
.map(name => t.identifier(name))
|
||||
.reduce((object, property) => t.memberExpression(object, property));
|
||||
};
|
||||
|
||||
const visitor = helper({
|
||||
pre(state) {
|
||||
const tagName = state.tagName;
|
||||
const args = state.args;
|
||||
if (t.react.isCompatTag(tagName)) {
|
||||
args.push(t.stringLiteral(tagName));
|
||||
} else {
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
post(state, pass) {
|
||||
state.callee = pass.get("jsxIdentifier")();
|
||||
},
|
||||
|
||||
throwIfNamespace: THROW_IF_NAMESPACE,
|
||||
});
|
||||
|
||||
visitor.Program = {
|
||||
enter(path, state) {
|
||||
const { file } = state;
|
||||
|
||||
let pragma = PRAGMA_DEFAULT;
|
||||
let pragmaFrag = PRAGMA_FRAG_DEFAULT;
|
||||
let pragmaSet = !!options.pragma;
|
||||
let pragmaFragSet = !!options.pragmaFrag;
|
||||
|
||||
if (file.ast.comments) {
|
||||
for (const comment of (file.ast.comments: Array<Object>)) {
|
||||
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxMatches) {
|
||||
pragma = jsxMatches[1];
|
||||
pragmaSet = true;
|
||||
}
|
||||
const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxFragMatches) {
|
||||
pragmaFrag = jsxFragMatches[1];
|
||||
pragmaFragSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.set("jsxIdentifier", createIdentifierParser(pragma));
|
||||
state.set("jsxFragIdentifier", createIdentifierParser(pragmaFrag));
|
||||
state.set("usedFragment", false);
|
||||
state.set("pragmaSet", pragmaSet);
|
||||
state.set("pragmaFragSet", pragmaFragSet);
|
||||
},
|
||||
exit(path, state) {
|
||||
if (
|
||||
state.get("pragmaSet") &&
|
||||
state.get("usedFragment") &&
|
||||
!state.get("pragmaFragSet")
|
||||
) {
|
||||
throw new Error(
|
||||
"transform-react-jsx: pragma has been set but " +
|
||||
"pragmaFrag has not been set",
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
visitor.JSXAttribute = function(path) {
|
||||
if (t.isJSXElement(path.node.value)) {
|
||||
path.node.value = t.jsxExpressionContainer(path.node.value);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
name: "transform-react-jsx",
|
||||
inherits: jsx,
|
||||
visitor,
|
||||
};
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]],
|
||||
"sourceType": "module"
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
import { createElement as _createElement } from "react";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { Fragment as _Fragment } from "react/jsx-runtime";
|
||||
|
||||
var x = _jsx(_Fragment, {
|
||||
children: _jsxs("div", {
|
||||
children: [_jsx("div", {}, "1"), _jsx("div", {
|
||||
meow: "wolf"
|
||||
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props,
|
||||
key: "4"
|
||||
})]
|
||||
})
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]],
|
||||
"sourceType": "script"
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
var _react = require("react");
|
||||
|
||||
var _reactJsxRuntime = require("react/jsx-runtime");
|
||||
|
||||
var x = _reactJsxRuntime.jsx(_reactJsxRuntime.Fragment, {
|
||||
children: _reactJsxRuntime.jsxs("div", {
|
||||
children: [_reactJsxRuntime.jsx("div", {}, "1"), _reactJsxRuntime.jsx("div", {
|
||||
meow: "wolf"
|
||||
}, "2"), _reactJsxRuntime.jsx("div", {}, "3"), _react.createElement("div", { ...props,
|
||||
key: "4"
|
||||
})]
|
||||
})
|
||||
});
|
||||
@ -0,0 +1,15 @@
|
||||
const Bar = () => {
|
||||
const Foo = () => {
|
||||
const Component = ({thing, ..._react}) => {
|
||||
if (!thing) {
|
||||
var _react2 = "something useless";
|
||||
var b = _react3();
|
||||
var c = _react5();
|
||||
var jsx = 1;
|
||||
var _jsx = 2;
|
||||
return <div />;
|
||||
};
|
||||
return <span />;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]],
|
||||
"sourceType": "module"
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import { jsx as _jsx2 } from "react/jsx-runtime";
|
||||
|
||||
const Bar = () => {
|
||||
const Foo = () => {
|
||||
const Component = ({
|
||||
thing,
|
||||
..._react
|
||||
}) => {
|
||||
if (!thing) {
|
||||
var _react2 = "something useless";
|
||||
|
||||
var b = _react3();
|
||||
|
||||
var c = _react5();
|
||||
|
||||
var jsx = 1;
|
||||
var _jsx = 2;
|
||||
return _jsx2("div", {});
|
||||
}
|
||||
|
||||
;
|
||||
return _jsx2("span", {});
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
const Bar = () => {
|
||||
const Foo = () => {
|
||||
const Component = ({thing, ..._react}) => {
|
||||
if (!thing) {
|
||||
var _react2 = "something useless";
|
||||
var b = _react3();
|
||||
var c = _react5();
|
||||
var jsx = 1;
|
||||
var _jsx = 2;
|
||||
return <div />;
|
||||
};
|
||||
return <span />;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]],
|
||||
"sourceType": "script"
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
var _reactJsxRuntime = require("react/jsx-runtime");
|
||||
|
||||
const Bar = () => {
|
||||
const Foo = () => {
|
||||
const Component = ({
|
||||
thing,
|
||||
..._react
|
||||
}) => {
|
||||
if (!thing) {
|
||||
var _react2 = "something useless";
|
||||
|
||||
var b = _react3();
|
||||
|
||||
var c = _react5();
|
||||
|
||||
var jsx = 1;
|
||||
var _jsx = 2;
|
||||
return _reactJsxRuntime.jsx("div", {});
|
||||
}
|
||||
|
||||
;
|
||||
return _reactJsxRuntime.jsx("span", {});
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,2 @@
|
||||
/** @jsxImportSource baz */
|
||||
var x = (<div><span /></div>);
|
||||
@ -0,0 +1,6 @@
|
||||
import { jsx as _jsx } from "baz/jsx-runtime";
|
||||
|
||||
/** @jsxImportSource baz */
|
||||
var x = _jsx("div", {
|
||||
children: _jsx("span", {})
|
||||
});
|
||||
@ -0,0 +1 @@
|
||||
var x = (<div><span /></div>);
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
["transform-react-jsx", { "importSource": "foo", "runtime": "automatic" }]
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
import { jsx as _jsx } from "foo/jsx-runtime";
|
||||
|
||||
var x = _jsx("div", {
|
||||
children: _jsx("span", {})
|
||||
});
|
||||
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/no-jsx/input.js
vendored
Normal file
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/no-jsx/input.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var foo = "<div></div>";
|
||||
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/no-jsx/output.mjs
vendored
Normal file
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/no-jsx/output.mjs
vendored
Normal file
@ -0,0 +1 @@
|
||||
var foo = "<div></div>";
|
||||
4
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/options.json
vendored
Normal file
4
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/options.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]],
|
||||
"sourceType": "module"
|
||||
}
|
||||
10
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/react-defined/input.js
vendored
Normal file
10
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/react-defined/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import * as react from "react";
|
||||
var y = react.createElement("div", {foo: 1});
|
||||
var x = (
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
);
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": [["transform-react-jsx", { "runtime": "automatic" }]]
|
||||
}
|
||||
15
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/react-defined/output.mjs
vendored
Normal file
15
packages/babel-plugin-transform-react-jsx/test/fixtures/nextAutoImport/react-defined/output.mjs
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { createElement as _createElement } from "react";
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import * as react from "react";
|
||||
var y = react.createElement("div", {
|
||||
foo: 1
|
||||
});
|
||||
|
||||
var x = _jsxs("div", {
|
||||
children: [_jsx("div", {}, "1"), _jsx("div", {
|
||||
meow: "wolf"
|
||||
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props,
|
||||
key: "4"
|
||||
})]
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
var x = (
|
||||
<div>
|
||||
{/* A comment at the beginning */}
|
||||
{/* A second comment at the beginning */}
|
||||
<span>
|
||||
{/* A nested comment */}
|
||||
</span>
|
||||
{/* A sandwiched comment */}
|
||||
<br />
|
||||
{/* A comment at the end */}
|
||||
{/* A second comment at the end */}
|
||||
</div>
|
||||
);
|
||||
@ -0,0 +1,3 @@
|
||||
<Component
|
||||
{...props}
|
||||
sound="moo" />
|
||||
@ -0,0 +1,5 @@
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
|
||||
_jsx(Component, { ...props,
|
||||
sound: "moo"
|
||||
});
|
||||
7
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/arrow-functions/input.js
vendored
Normal file
7
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/arrow-functions/input.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
var foo = function () {
|
||||
return () => <this />;
|
||||
};
|
||||
|
||||
var bar = function () {
|
||||
return () => <this.foo />;
|
||||
};
|
||||
17
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/arrow-functions/output.mjs
vendored
Normal file
17
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/arrow-functions/output.mjs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
|
||||
var foo = function () {
|
||||
var _this = this;
|
||||
|
||||
return function () {
|
||||
return _jsx(_this, {});
|
||||
};
|
||||
};
|
||||
|
||||
var bar = function () {
|
||||
var _this2 = this;
|
||||
|
||||
return function () {
|
||||
return _jsx(_this2.foo, {});
|
||||
};
|
||||
};
|
||||
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/assignment/input.js
vendored
Normal file
1
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/assignment/input.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var div = <Component {...props} foo="bar" />
|
||||
5
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/assignment/output.mjs
vendored
Normal file
5
packages/babel-plugin-transform-react-jsx/test/fixtures/nextReact/assignment/output.mjs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
|
||||
var div = _jsx(Component, { ...props,
|
||||
foo: "bar"
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
var x =
|
||||
<div>
|
||||
foo
|
||||
{"bar"}
|
||||
baz
|
||||
<div>
|
||||
buz
|
||||
bang
|
||||
</div>
|
||||
qux
|
||||
{null}
|
||||
quack
|
||||
</div>
|
||||
@ -0,0 +1,8 @@
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
|
||||
var x = _jsxs("div", {
|
||||
children: ["foo", "bar", "baz", _jsx("div", {
|
||||
children: "buz bang"
|
||||
}), "qux", null, "quack"]
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
var Component;
|
||||
Component = React.createClass({
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
var Component;
|
||||
Component = React.createClass({
|
||||
displayName: "Component",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
export default React.createClass({
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
export default React.createClass({
|
||||
displayName: "input",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
var Whateva = React.createClass({
|
||||
displayName: "Whatever",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
var Bar = React.createClass({
|
||||
"displayName": "Ba",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,12 @@
|
||||
var Whateva = React.createClass({
|
||||
displayName: "Whatever",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
var Bar = React.createClass({
|
||||
"displayName": "Ba",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
exports = {
|
||||
Component: React.createClass({
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
};
|
||||
@ -0,0 +1,8 @@
|
||||
exports = {
|
||||
Component: React.createClass({
|
||||
displayName: "Component",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
exports.Component = React.createClass({
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
exports.Component = React.createClass({
|
||||
displayName: "Component",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
var Component = React.createClass({
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
var Component = React.createClass({
|
||||
displayName: "Component",
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,32 @@
|
||||
var actual = transform(
|
||||
`var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);`,
|
||||
Object.assign({}, opts, { filename: 'C:\\fake\\path\\mock.js' })
|
||||
).code;
|
||||
|
||||
var expected =
|
||||
`import { createElement as _createElement } from "react";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { Fragment as _Fragment } from "react/jsx-runtime";
|
||||
var _jsxFileName = "C:\\\\fake\\\\path\\\\mock.js";
|
||||
|
||||
var x = _jsx(_Fragment, {
|
||||
children: _jsxs("div", {
|
||||
children: [_jsx("div", {}, "1"), _jsx("div", {
|
||||
meow: "wolf"
|
||||
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props,
|
||||
key: "4"
|
||||
})]
|
||||
})
|
||||
});`;
|
||||
|
||||
expect(actual).toBe(expected);
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"transform-react-jsx",
|
||||
{
|
||||
"autoImport": "namedExports",
|
||||
"runtime": "automatic"
|
||||
}
|
||||
],
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"sourceType": "module",
|
||||
"os": ["win32"],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
var actual = transform(
|
||||
`var x = (
|
||||
<>
|
||||
<div>
|
||||
<div key="1" />
|
||||
<div key="2" meow="wolf" />
|
||||
<div key="3" />
|
||||
<div {...props} key="4" />
|
||||
</div>
|
||||
</>
|
||||
);`,
|
||||
Object.assign({}, opts, { filename: '/fake/path/mock.js' })
|
||||
).code;
|
||||
|
||||
var expected =
|
||||
`import { createElement as _createElement } from "react";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { Fragment as _Fragment } from "react/jsx-runtime";
|
||||
var _jsxFileName = "/fake/path/mock.js";
|
||||
|
||||
var x = _jsx(_Fragment, {
|
||||
children: _jsxs("div", {
|
||||
children: [_jsx("div", {}, "1"), _jsx("div", {
|
||||
meow: "wolf"
|
||||
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props,
|
||||
key: "4"
|
||||
})]
|
||||
})
|
||||
});`;
|
||||
|
||||
expect(actual).toBe(expected);
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"transform-react-jsx",
|
||||
{
|
||||
"autoImport": "namedExports",
|
||||
"runtime": "automatic"
|
||||
}
|
||||
],
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self"
|
||||
],
|
||||
"sourceType": "module",
|
||||
"os": ["linux", "darwin"],
|
||||
"throws": "__source and __self should not be defined in props. You are most likely using the deprecated transform-react-jsx-self or transform-react-jsx-source Babel plugins. __source and __self will be set automatically in automatic runtime. Please remove transform-react-jsx-self or transform-react-jsx-source from your Babel config."
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
<Text>
|
||||
To get started, edit index.ios.js!!!{"\n"}
|
||||
Press Cmd+R to reload
|
||||
</Text>
|
||||
@ -0,0 +1,5 @@
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
|
||||
_jsxs(Text, {
|
||||
children: ["To get started, edit index.ios.js!!!", "\n", "Press Cmd+R to reload"]
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user