feat(es/transforms/react): New jsx transform (#1408)

swc_ecma_transforms_react:
  - Implement new jsx transform. (#1103, denoland/deno#7993)
This commit is contained in:
강동윤 2021-02-19 14:32:53 +09:00 committed by GitHub
parent 702e20ef56
commit 0be20ff0ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
438 changed files with 3057 additions and 103 deletions

View File

@ -9,7 +9,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc"
repository = "https://github.com/swc-project/swc.git"
version = "0.4.0"
version = "0.5.0"
[lib]
name = "swc"
@ -31,8 +31,8 @@ swc_ecma_ast = {version = "0.38.0", path = "./ecmascript/ast"}
swc_ecma_codegen = {version = "0.45.0", path = "./ecmascript/codegen"}
swc_ecma_ext_transforms = {version = "0.4.0", path = "./ecmascript/ext-transforms"}
swc_ecma_parser = {version = "0.47.0", path = "./ecmascript/parser"}
swc_ecma_preset_env = {version = "0.5.0", path = "./ecmascript/preset_env"}
swc_ecma_transforms = {version = "0.35.0", path = "./ecmascript/transforms", features = [
swc_ecma_preset_env = {version = "0.6.0", path = "./ecmascript/preset_env"}
swc_ecma_transforms = {version = "0.36.0", path = "./ecmascript/transforms", features = [
"compat",
"module",
"optimization",

View File

@ -9,7 +9,7 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/**/*.js"]
license = "Apache-2.0/MIT"
name = "swc_bundler"
repository = "https://github.com/swc-project/swc.git"
version = "0.22.0"
version = "0.23.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
@ -34,7 +34,7 @@ swc_common = {version = "0.10.0", path = "../common"}
swc_ecma_ast = {version = "0.38.0", path = "../ecmascript/ast"}
swc_ecma_codegen = {version = "0.45.0", path = "../ecmascript/codegen"}
swc_ecma_parser = {version = "0.47.0", path = "../ecmascript/parser"}
swc_ecma_transforms = {version = "0.35.0", path = "../ecmascript/transforms", features = ["optimization"]}
swc_ecma_transforms = {version = "0.36.0", path = "../ecmascript/transforms", features = ["optimization"]}
swc_ecma_utils = {version = "0.28.0", path = "../ecmascript/utils"}
swc_ecma_visit = {version = "0.24.0", path = "../ecmascript/visit"}
@ -43,7 +43,7 @@ hex = "0.4"
ntest = "0.7.2"
reqwest = {version = "0.10.8", features = ["blocking"]}
sha-1 = "0.9"
swc_ecma_transforms = {version = "0.35.0", path = "../ecmascript/transforms", features = ["react", "typescript"]}
swc_ecma_transforms = {version = "0.36.0", path = "../ecmascript/transforms", features = ["react", "typescript"]}
tempfile = "3.1.0"
testing = {version = "0.10.0", path = "../testing"}
url = "2.1.1"

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecmascript"
repository = "https://github.com/swc-project/swc.git"
version = "0.21.1"
version = "0.22.0"
[package.metadata.docs.rs]
all-features = true
@ -31,7 +31,7 @@ swc_ecma_ast = {version = "0.38.0", path = "./ast"}
swc_ecma_codegen = {version = "0.45.0", path = "./codegen", optional = true}
swc_ecma_dep_graph = {version = "0.15.0", path = "./dep-graph", optional = true}
swc_ecma_parser = {version = "0.47.0", path = "./parser", optional = true}
swc_ecma_transforms = {version = "0.35.0", path = "./transforms", optional = true}
swc_ecma_transforms = {version = "0.36.0", path = "./transforms", optional = true}
swc_ecma_utils = {version = "0.28.0", path = "./utils", optional = true}
swc_ecma_visit = {version = "0.24.0", path = "./visit", optional = true}

View File

@ -5,7 +5,7 @@ documentation = "https://swc.rs/rustdoc/swc_ecma_preset_env/"
edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_preset_env"
version = "0.5.0"
version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -21,7 +21,7 @@ string_enum = {version = "0.3", path = "../../macros/string_enum"}
swc_atoms = {version = "0.2", path = "../../atoms"}
swc_common = {version = "0.10", path = "../../common"}
swc_ecma_ast = {version = "0.38.0", path = "../ast"}
swc_ecma_transforms = {version = "0.35.0", path = "../transforms", features = ["compat", "proposal"]}
swc_ecma_transforms = {version = "0.36.0", path = "../transforms", features = ["compat", "proposal"]}
swc_ecma_utils = {version = "0.28.0", path = "../utils"}
swc_ecma_visit = {version = "0.24.0", path = "../visit"}
walkdir = "2"

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms"
repository = "https://github.com/swc-project/swc.git"
version = "0.35.0"
version = "0.36.0"
[features]
compat = ["swc_ecma_transforms_compat"]
@ -24,9 +24,9 @@ swc_ecma_parser = {version = "0.47.0", path = "../parser"}
swc_ecma_transforms_base = {version = "0.4.0", path = "./base"}
swc_ecma_transforms_compat = {version = "0.5.0", path = "./compat", optional = true}
swc_ecma_transforms_module = {version = "0.5.0", path = "./module", optional = true}
swc_ecma_transforms_optimization = {version = "0.5.0", path = "./optimization", optional = true}
swc_ecma_transforms_optimization = {version = "0.6.0", path = "./optimization", optional = true}
swc_ecma_transforms_proposal = {version = "0.5.0", path = "./proposal", optional = true}
swc_ecma_transforms_react = {version = "0.5.0", path = "./react", optional = true}
swc_ecma_transforms_react = {version = "0.6.0", path = "./react", optional = true}
swc_ecma_transforms_typescript = {version = "0.5.0", path = "./typescript", optional = true}
swc_ecma_utils = {version = "0.28.0", path = "../utils"}
swc_ecma_visit = {version = "0.24.0", path = "../visit"}

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_optimization"
repository = "https://github.com/swc-project/swc.git"
version = "0.5.0"
version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@ -29,6 +29,6 @@ swc_ecma_visit = {version = "0.24.0", path = "../../visit"}
swc_ecma_transforms_compat = {version = "0.5.0", path = "../compat"}
swc_ecma_transforms_module = {version = "0.5.0", path = "../module"}
swc_ecma_transforms_proposal = {version = "0.5.0", path = "../proposal"}
swc_ecma_transforms_react = {version = "0.5.0", path = "../react"}
swc_ecma_transforms_react = {version = "0.6.0", path = "../react"}
swc_ecma_transforms_testing = {version = "0.4.0", path = "../testing"}
swc_ecma_transforms_typescript = {version = "0.5.0", path = "../typescript"}

View File

@ -3,10 +3,11 @@ authors = ["강동윤 <kdy1997.dev@gmail.com>"]
description = "rust port of babel and closure compiler."
documentation = "https://swc.rs/rustdoc/swc_ecma_transforms_react/"
edition = "2018"
include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_react"
repository = "https://github.com/swc-project/swc.git"
version = "0.5.1"
version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@ -14,6 +15,7 @@ dashmap = "4.0.1"
once_cell = "1.5.2"
regex = "1.4.2"
serde = {version = "1.0.118", features = ["derive"]}
string_enum = {version = "0.3", path = "../../../macros/string_enum"}
swc_atoms = {version = "0.2", path = "../../../atoms"}
swc_common = {version = "0.10", path = "../../../common"}
swc_ecma_ast = {version = "0.38.0", path = "../../ast"}
@ -26,3 +28,4 @@ swc_ecma_visit = {version = "0.24.0", path = "../../visit"}
swc_ecma_transforms_compat = {version = "0.5.0", path = "../compat/"}
swc_ecma_transforms_module = {version = "0.5.0", path = "../module"}
swc_ecma_transforms_testing = {version = "0.4.0", path = "../testing/"}
testing = {version = "0.10.2", path = "../../../testing"}

View File

@ -0,0 +1 @@
*.js

View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
npx tsc scripts/patch-options.ts
node scripts/patch-options.js

View File

@ -0,0 +1,57 @@
import * as fs from 'fs';
import * as path from 'path';
async function* walk(dir: string): AsyncGenerator<string> {
for await (const d of await fs.promises.opendir(dir)) {
const entry = path.join(dir, d.name);
if (d.isDirectory()) yield* walk(entry);
else if (d.isFile()) yield entry;
}
}
// Then, use it with a simple async for loop
async function main() {
// TODO: Generalize path
for await (const f of walk('src/jsx/fixture')) {
if (!f.endsWith('.json')) {
continue
}
const obj = JSON.parse(await fs.promises.readFile(f, { encoding: 'utf-8' }));
const dir = path.dirname(f);
if (obj.throws) {
await fs.promises.writeFile(path.join(dir, "output.stderr"), obj.throws);
}
console.log(f);
if (obj.plugins) {
if (obj.plugins.includes('transform-react-jsx')) {
const newObj = {
...obj,
};
delete newObj.sourceType
delete newObj.plugins;
await fs.promises.writeFile(f, JSON.stringify(newObj), { encoding: 'utf-8' });
continue
}
for (const [plugin, config] of obj.plugins) {
if (plugin === 'transform-react-jsx') {
console.log(plugin, config);
const newObj = {
...obj,
...config,
};
delete newObj.sourceType
delete newObj.plugins;
await fs.promises.writeFile(f, JSON.stringify(newObj), { encoding: 'utf-8' });
break
}
}
}
}
}
main()

View File

@ -0,0 +1,10 @@
// https://github.com/babel/babel/issues/12522
require('react-app-polyfill/ie11');
require('react-app-polyfill/stable');
const ReactDOM = require('react-dom');
ReactDOM.render(
<p>Hello, World!</p>,
document.getElementById('root')
);

View File

@ -0,0 +1,12 @@
var _reactJsxRuntime = require("react/jsx-runtime");
// https://github.com/babel/babel/issues/12522
require('react-app-polyfill/ie11');
require('react-app-polyfill/stable');
const ReactDOM = require('react-dom');
ReactDOM.render( /*#__PURE__*/_reactJsxRuntime.jsx("p", {
children: "Hello, World!"
}), document.getElementById('root'));

View File

@ -0,0 +1,10 @@
var x = (
<>
<div>
<div key="1" />
<div key="2" meow="wolf" />
<div key="3" />
<div {...props} key="4" />
</div>
</>
);

View File

@ -0,0 +1,13 @@
var _react = require("react");
var _reactJsxRuntime = require("react/jsx-runtime");
var x = /*#__PURE__*/_reactJsxRuntime.jsx(_reactJsxRuntime.Fragment, {
children: /*#__PURE__*/_reactJsxRuntime.jsxs("div", {
children: [/*#__PURE__*/_reactJsxRuntime.jsx("div", {}, "1"), /*#__PURE__*/_reactJsxRuntime.jsx("div", {
meow: "wolf"
}, "2"), /*#__PURE__*/_reactJsxRuntime.jsx("div", {}, "3"), /*#__PURE__*/_react.createElement("div", { ...props,
key: "4"
})]
})
});

View File

@ -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 />;
};
}
}

View File

@ -0,0 +1 @@
{"runtime":"automatic"}

View File

@ -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 /*#__PURE__*/_reactJsxRuntime.jsx("div", {});
}
;
return /*#__PURE__*/_reactJsxRuntime.jsx("span", {});
};
};
};

View File

@ -0,0 +1,11 @@
// https://github.com/babel/babel/issues/12522
ReactDOM.render(
<p>Hello, World!</p>,
document.getElementById('root')
);
// Imports are hoisted, so this is still ok
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import ReactDOM from 'react-dom';

View File

@ -0,0 +1,9 @@
// https://github.com/babel/babel/issues/12522
ReactDOM.render( /*#__PURE__*/_jsx("p", {
children: "Hello, World!"
}), document.getElementById('root')); // Imports are hoisted, so this is still ok
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import ReactDOM from 'react-dom';
import { jsx as _jsx } from "react/jsx-runtime";

View File

@ -0,0 +1,10 @@
// https://github.com/babel/babel/issues/12522
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import ReactDOM from 'react-dom';
ReactDOM.render(
<p>Hello, World!</p>,
document.getElementById('root')
);

View File

@ -0,0 +1,16 @@
"use strict";
require("react-app-polyfill/ie11");
require("react-app-polyfill/stable");
var _reactDom = _interopRequireDefault(require("react-dom"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// https://github.com/babel/babel/issues/12522
_reactDom.default.render( /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
children: "Hello, World!"
}), document.getElementById('root'));

View File

@ -0,0 +1,10 @@
// https://github.com/babel/babel/issues/12522
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import ReactDOM from 'react-dom';
ReactDOM.render(
<p>Hello, World!</p>,
document.getElementById('root')
);

View File

@ -0,0 +1,8 @@
// https://github.com/babel/babel/issues/12522
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import ReactDOM from 'react-dom';
import { jsx as _jsx } from "react/jsx-runtime";
ReactDOM.render( /*#__PURE__*/_jsx("p", {
children: "Hello, World!"
}), document.getElementById('root'));

View File

@ -0,0 +1,10 @@
var x = (
<>
<div>
<div key="1" />
<div key="2" meow="wolf" />
<div key="3" />
<div {...props} key="4" />
</div>
</>
);

View File

@ -0,0 +1,13 @@
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
var x = /*#__PURE__*/_jsx(_Fragment, {
children: /*#__PURE__*/_jsxs("div", {
children: [/*#__PURE__*/_jsx("div", {}, "1"), /*#__PURE__*/_jsx("div", {
meow: "wolf"
}, "2"), /*#__PURE__*/_jsx("div", {}, "3"), /*#__PURE__*/_createElement("div", {
...props,
key: "4"
})]
})
});

View File

@ -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 />;
};
}
}

View File

@ -0,0 +1 @@
{"runtime":"automatic"}

View File

@ -0,0 +1,19 @@
import { jsx as _jsx } 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 _jsx1 = 2;
return _jsx("div", {
});
}
;
return _jsx("span", {
});
};
};
};

View File

@ -0,0 +1,2 @@
/** @jsxImportSource baz */
var x = (<div><span /></div>);

View File

@ -0,0 +1,6 @@
import { jsx as _jsx } from "baz/jsx-runtime";
/** @jsxImportSource baz */
var x = _jsx("div", {
children: _jsx("span", {})
});

View File

@ -0,0 +1 @@
var x = (<div><span /></div>);

View File

@ -0,0 +1 @@
{"importSource":"foo","runtime":"automatic"}

View File

@ -0,0 +1,5 @@
import { jsx as _jsx } from "foo/jsx-runtime";
var x = _jsx("div", {
children: _jsx("span", {})
});

View File

@ -0,0 +1 @@
var foo = "<div></div>";

View File

@ -0,0 +1 @@
var foo = "<div></div>";

View File

@ -0,0 +1 @@
{"runtime":"automatic"}

View 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>
);

View File

@ -0,0 +1 @@
{"runtime":"automatic"}

View File

@ -0,0 +1,21 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
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"
})
]
});

View File

@ -0,0 +1 @@
{"pure":false,"runtime":"automatic"}

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic.","pragma":"h","pure":false,"runtime":"automatic"}

View File

@ -0,0 +1 @@
pragma and pragmaFrag cannot be set when runtime is automatic.

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic.","pragma":"h","pure":true,"runtime":"automatic"}

View File

@ -0,0 +1 @@
pragma and pragmaFrag cannot be set when runtime is automatic.

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic.","pragma":"h","runtime":"automatic"}

View File

@ -0,0 +1 @@
pragma and pragmaFrag cannot be set when runtime is automatic.

View File

@ -0,0 +1 @@
{"pure":false,"runtime":"classic"}

View File

@ -0,0 +1 @@
React.createElement("div", null);

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic","pure":false,"runtime":"automatic"}

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1,6 @@
error: pragma and pragmaFrag cannot be set when runtime is automatic
--> input.js:3:1
|
3 | <div />;
| ^^^^^^^^

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1 @@
{"pure":false,"runtime":"classic"}

View File

@ -0,0 +1,2 @@
/* @jsx h */
h("div", null);

View File

@ -0,0 +1 @@
{"pragma":"h","pure":false,"runtime":"classic"}

View File

@ -0,0 +1 @@
{"pure":true,"runtime":"automatic"}

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1 @@
{"pure":true,"runtime":"classic"}

View File

@ -0,0 +1,2 @@
/*#__PURE__*/
React.createElement("div", null);

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic","pure":true,"runtime":"automatic"}

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1,6 @@
error: pragma and pragmaFrag cannot be set when runtime is automatic
--> input.js:3:1
|
3 | <div />;
| ^^^^^^^^

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1 @@
{"pure":true,"runtime":"classic"}

View File

@ -0,0 +1,4 @@
/* @jsx h */
/*#__PURE__*/
h("div", null);

View File

@ -0,0 +1 @@
{"pragma":"h","pure":true,"runtime":"classic"}

View File

@ -0,0 +1,2 @@
/*#__PURE__*/
h("div", null);

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1,2 @@
/*#__PURE__*/
React.createElement("div", null);

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1 @@
{"throws":"pragma and pragmaFrag cannot be set when runtime is automatic","runtime":"automatic"}

View File

@ -0,0 +1,3 @@
import { jsx as _jsx } from "react/jsx-runtime";
_jsx("div", {
});

View File

@ -0,0 +1,6 @@
error: pragma and pragmaFrag cannot be set when runtime is automatic
--> input.js:3:1
|
3 | <div />;
| ^^^^^^^^

View File

@ -0,0 +1,3 @@
/* @jsx h */
<div />;

View File

@ -0,0 +1,2 @@
/* @jsx h */
h("div", null);

View File

@ -0,0 +1 @@
{"pragma":"h","runtime":"classic"}

Some files were not shown because too many files have changed in this diff Show More