【问题标题】:Best way to convert only JSX in TSX and maintaining TS在 TSX 中仅转换 JSX 并维护 TS 的最佳方法
【发布时间】:2019-09-11 06:15:14
【问题描述】:

我有一堆用 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 }
    ]
  ]
}

我在 rc 文件中包含@babel/typescript,因为它需要能够读取 TS 而不会抱怨语法。但是,应该保留输出。

如果这不是最好的方法,您能否就更有效的转换方法提出建议?附言。我不能使用 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"
    ]
}

【问题讨论】:

  • 你也在使用 tsc 编译器吗?如果您无法分辨,请向我们展示完整的构建配置,包括 tsconfig.json
  • 添加在上面。我假设第一步是改变目标?但是对于什么,文档中的选项除了 ES 版本之外不允许任何内容?
  • 好的,我终于明白你想要做什么了。抱歉之前的评论,我没有仔细阅读。
  • 哇,你想要的很奇怪。既然.ts 不可运行并且无论如何都需要进一步转译,为什么这个中间产品对你很重要?可能会分享您要解决的真正问题是什么?也许我们还可以研究其他解决方法。
  • 我知道它很奇特,但 Inferno 的 JSX 转换器很特别,我正在为一个很难详细说明的非常具体的用例解决它。不幸的是,这不是以不同的方式解决问题的问题,而是我正在使用的环境如何运作。澄清一下:我想要一个脚本并只转换 JSX。如果没有办法,我会感到震惊。

标签: typescript babeljs infernojs


【解决方案1】:

这是您需要的.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);

【讨论】:

  • 谢谢!我正在接近类似的结论。这让我得到了解决问题所需的东西。欣赏洞察力。
猜你喜欢
  • 2016-09-27
  • 2016-12-01
  • 1970-01-01
  • 2018-12-04
  • 2014-10-13
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多