Add a 'throwIfNamespace' option for JSX transform (#6563)

* Added tests for ifThrowNamespace flag

* JSX transformator could work with XMLNamespaces (ifThrowNamespace flag)

* Use template literal instead

* Attempt to reword the message

* Added docs

* Reworded docs

* Reworded docs

* Fixed missing space in error message
This commit is contained in:
Jakub Beneš
2017-10-29 02:44:15 +02:00
committed by Henry Zhu
parent 9ac326b075
commit 04d2c030be
10 changed files with 58 additions and 7 deletions

View File

@@ -14,11 +14,13 @@ export default function(opts) {
const visitor = {};
visitor.JSXNamespacedName = function(path) {
throw path.buildCodeFrameError(
"Namespace tags are not supported. ReactJSX is not XML.",
);
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.`,
);
}
};
visitor.JSXElement = {
exit(path, file) {
const callExpr = buildElementCall(path, file);
@@ -44,6 +46,12 @@ export default function(opts) {
convertJSXIdentifier(node.object, node),
convertJSXIdentifier(node.property, node),
);
} else if (t.isJSXNamespacedName(node)) {
/**
* If there is flag "throwIfNamespace"
* print XMLNamespace like string literal
*/
return t.stringLiteral(`${node.namespace.name}:${node.name.name}`);
}
return node;

View File

@@ -78,7 +78,8 @@ With options:
{
"plugins": [
["@babel/transform-react-jsx", {
"pragma": "dom" // default pragma is React.createElement
"pragma": "dom", // default pragma is React.createElement
"throwIfNamespace": false // defaults to true
}]
]
}
@@ -113,3 +114,13 @@ Note that the `@jsx React.DOM` pragma has been deprecated as of React v0.12
`boolean`, defaults to `false`.
When spreading props, use `Object.assign` directly instead of Babel's extend helper.
### `throwIfNamespace`
`boolean`, defaults to `true`.
Toggles whether or not to throw an error if a XML namespaced tag name is used. For example:
<f:image />
Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.

View File

@@ -3,6 +3,8 @@ import helper from "@babel/helper-builder-react-jsx";
export default function({ types: t }, options) {
const pragma = options.pragma || "React.createElement";
const throwIfNamespace =
options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace;
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
@@ -20,6 +22,8 @@ export default function({ types: t }, options) {
post(state, pass) {
state.callee = pass.get("jsxIdentifier")();
},
throwIfNamespace,
});
visitor.Program = function(path, state) {

View File

@@ -1,3 +1,3 @@
{
"throws": "Namespace tags are not supported. ReactJSX is not XML."
"throws": "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."
}

View File

@@ -0,0 +1,11 @@
{
"plugins": [
[
"transform-react-jsx",
{
"pragma": "h",
"throwIfNamespace": false
}
]
]
}

View File

@@ -0,0 +1,12 @@
{
"plugins": [
[
"transform-react-jsx",
{
"pragma": "h",
"throwIfNamespace": true
}
]
],
"throws": "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."
}

View File

@@ -129,7 +129,9 @@ defineType("CallExpression", {
arguments: {
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("Expression", "SpreadElement")),
assertEach(
assertNodeType("Expression", "SpreadElement", "JSXNamespacedName"),
),
),
},
optional: {