在 TSX 中仅转换 JSX 并维护 TS 的最佳方式
Best way to convert only JSX in TSX and maintaining TS
我有一堆用 Inferno 编写的 TSX 组件(类似于 React/Preact)。我只需要转换了 JSX 方面的 .ts 版本。我使用它的环境只支持 TypeScript,而 Inferno JSX 转换器只为 Babel 编写。我相信我可以用 Babel 做到这一点,但不确定要添加哪些标志。
这是我的脚本示例:
import { Component, linkEvent } from 'inferno';
import './index.scss';
interface HeaderProps {
name: string,
address: string
}
export default class Header extends Component {
render(props:HeaderProps) {
return (
<header class="wrap">
<img class="logo" src="logo.svg" />
<h1>{ props.name }</h1>
<img src="arrow.svg" />
</header>
);
}
}
在我编译此脚本后,任何 TS(例如界面)都应该保留,但是 JSX 应该转换为 createVNode()
函数。做这个的babel插件是:https://github.com/infernojs/babel-plugin-inferno
这是我当前的 .babelrc:
{
"compact": false,
"presets": [
[
"@babel/preset-env",
{
"loose": true,
"targets": {
"browsers": ["ie >= 11", "safari > 10"]
}
}
],
[
"@babel/typescript",
{ "isTSX": true, "allExtensions": true }
]
],
"plugins": [
["babel-plugin-inferno",
{ "imports": true }],
"@babel/plugin-transform-runtime",
[
"@babel/plugin-proposal-class-properties",
{ "loose": true }
]
]
}
我将 @babel/typescript
包含在 rc 文件中,因为它需要能够在不抱怨语法的情况下读取 TS。但是,应该保留输出。
如果这不是最好的方法,您能否就更有效的转换方法提出建议? ps。我不能使用 TS JSX 转换器,它与 Inferno 不兼容。
这是我的 tsconfig:
{
"compilerOptions": {
"pretty": true,
"target": "es5",
"module": "esnext",
"allowSyntheticDefaultImports": true,
"preserveConstEnums": true,
"sourceMap": true,
"moduleResolution": "node",
"lib": ["es2017", "dom"],
"types": [
"inferno"
],
"jsx": "preserve",
"noUnusedLocals": true,
"baseUrl": "./src",
"noEmit": true,
"skipLibCheck": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
},
"include": [
"src/**/*",
"node_modules/inferno/dist/index.d.ts"
]
}
这是您需要的.babelrc
:
{
"plugins": [
["babel-plugin-inferno", { "imports": true }],
["@babel/plugin-syntax-typescript", { "isTSX": true }],
]
}
注意,不要使用 tsc,只使用 babel。
展开查看测试结果:
// ============== input ==============
const x: number = 1;
enum Enum { one, two }
interface Foobar { key: string; }
const bar = () => <div>bar</div>
const zoo = () => <><span>yolo</span></>
// ============== output ==============
import { createVNode, createFragment } from "inferno";
const x: number = 1;
enum Enum {
one,
two,
}
interface Foobar {
key: string;
}
const bar = () => createVNode(1, "div", null, "bar", 16);
const zoo = () => createFragment([createVNode(1, "span", null, "yolo", 16)], 4);
我有一堆用 Inferno 编写的 TSX 组件(类似于 React/Preact)。我只需要转换了 JSX 方面的 .ts 版本。我使用它的环境只支持 TypeScript,而 Inferno JSX 转换器只为 Babel 编写。我相信我可以用 Babel 做到这一点,但不确定要添加哪些标志。
这是我的脚本示例:
import { Component, linkEvent } from 'inferno';
import './index.scss';
interface HeaderProps {
name: string,
address: string
}
export default class Header extends Component {
render(props:HeaderProps) {
return (
<header class="wrap">
<img class="logo" src="logo.svg" />
<h1>{ props.name }</h1>
<img src="arrow.svg" />
</header>
);
}
}
在我编译此脚本后,任何 TS(例如界面)都应该保留,但是 JSX 应该转换为 createVNode()
函数。做这个的babel插件是:https://github.com/infernojs/babel-plugin-inferno
这是我当前的 .babelrc:
{
"compact": false,
"presets": [
[
"@babel/preset-env",
{
"loose": true,
"targets": {
"browsers": ["ie >= 11", "safari > 10"]
}
}
],
[
"@babel/typescript",
{ "isTSX": true, "allExtensions": true }
]
],
"plugins": [
["babel-plugin-inferno",
{ "imports": true }],
"@babel/plugin-transform-runtime",
[
"@babel/plugin-proposal-class-properties",
{ "loose": true }
]
]
}
我将 @babel/typescript
包含在 rc 文件中,因为它需要能够在不抱怨语法的情况下读取 TS。但是,应该保留输出。
如果这不是最好的方法,您能否就更有效的转换方法提出建议? ps。我不能使用 TS JSX 转换器,它与 Inferno 不兼容。
这是我的 tsconfig:
{
"compilerOptions": {
"pretty": true,
"target": "es5",
"module": "esnext",
"allowSyntheticDefaultImports": true,
"preserveConstEnums": true,
"sourceMap": true,
"moduleResolution": "node",
"lib": ["es2017", "dom"],
"types": [
"inferno"
],
"jsx": "preserve",
"noUnusedLocals": true,
"baseUrl": "./src",
"noEmit": true,
"skipLibCheck": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
},
"include": [
"src/**/*",
"node_modules/inferno/dist/index.d.ts"
]
}
这是您需要的.babelrc
:
{
"plugins": [
["babel-plugin-inferno", { "imports": true }],
["@babel/plugin-syntax-typescript", { "isTSX": true }],
]
}
注意,不要使用 tsc,只使用 babel。
展开查看测试结果:
// ============== input ==============
const x: number = 1;
enum Enum { one, two }
interface Foobar { key: string; }
const bar = () => <div>bar</div>
const zoo = () => <><span>yolo</span></>
// ============== output ==============
import { createVNode, createFragment } from "inferno";
const x: number = 1;
enum Enum {
one,
two,
}
interface Foobar {
key: string;
}
const bar = () => createVNode(1, "div", null, "bar", 16);
const zoo = () => createFragment([createVNode(1, "span", null, "yolo", 16)], 4);