【问题标题】:How to create your own babel processor alternative to `React`如何创建自己的 babel 处理器替代 `React`
【发布时间】:2019-11-29 05:48:59
【问题描述】:

当您在 JS 文件中使用 JSX 时,您必须导入 React 否则生成的代码将无法编译。这是因为:

import React from 'react'
import ReactDOM from 'react-dom'

function Foo() { return 'hello world' }

ReactDOM.render(<Foo/>, document.body)

变成:

import React from 'react'
import ReactDOM from 'react-dom'

function Foo() { return 'hello world' }

ReactDOM.render(React.createElement(Foo), document.body)

所以React.createElement 中的React 是由某处的某些 babel 或 webpack 工具生成的,它在某处指定,我不记得了。我的问题首先是在哪里指定它将 JSX 转换为 React.createElement

第二个也是主要的问题是,我如何自定义它以将 JSX 转换为 MyThing.create?我记得很久以前在virtual-dom 库中看到过这个,但我已经忘记了。想知道这样做需要什么。

我想做的是创建一个类似这样的 API

<Foo/>
<Bar/>
<Baz/>

MyThing.create('Foo')
MyThing.create('Bar')
MyThing.create('Baz')

【问题讨论】:

    标签: javascript reactjs jsx babeljs


    【解决方案1】:

    负责 JSX 处理的 Babel 插件是@babel/plugin-transform-react-jsx。尽管它的名称是特定于 React 的,但您可以通过在 .babelrc 文件中设置一个选项来使用您喜欢的任何 pragmaReact.createElement 是默认的 pragma):

    {
        "presets": ["@babel/preset-env"],
        "plugins": [
            ["@babel/plugin-transform-react-jsx", {
                "pragma": "MyThing.create"
            }]
        ]
    }
    

    除了pragma,还有pragmaFrag 用于设置&lt;&gt;...&lt;/&gt; JSX 结构的输出。 (默认为React.Fragment。)

    例如,Mithril.js 使用 "pragma": "m""pragmaFrag": "'['"Preact 使用 "pragma": "Preact.h""pragmaFrag": "Preact.Fragment"

    ~5 年前我使用了一个不同的 JSX-to-JavaScript 编译器,它工作得很好,但我现在找不到它。这是有道理的:JavaScript 在过去五年中发生了很大变化,而让编译器与这些变化保持同步的时间承诺将是非常重要的。鉴于 Babel 的成功,很容易看到开发人员决定不追求它。

    我知道有一种选择:Sucrase。它编译 JSX、TypeScript 和 Flow,没有 Babel 的插件结构。 (因此,它非常快。)

    【讨论】:

    • 感谢您对 Sucrase 的推荐,看起来很棒!我该如何创建一个插件,这样我就可以摆脱那个杂注,只需从 @babel/plugin-transform-react-jsx 复制代码?
    • 另外,你可以同时使用React pragma 和MyThing pragma 吗?也就是说,假设您有 1000 个文件应用程序,一半在反应中,一半在神话中,所有这些都混合到一个构建中。你可以认为构建使用了 2 个不同的编译指示吗?
    • @LancePollard - 我不推荐 Sucrase,我从未使用过它,只知道它存在。 :-) 我不确定您为什么要避免使用pragma 选项,但是是的,您可以复制插件,更改其名称,然后更改默认值。但是随后您将承担使您的副本保持最新的工作,合并以后的 PR 等。FWIW,其他项目似乎很乐意只使用现有插件的配置(例如,Mithril.js 和 Preact) .
    • @LancePollard - .babelrc 是文件相关的,因此您可以在项目中为 React 文件创建一个目录,并为 MyThing 文件创建另一个目录。目录特定的.babelrc 文件中的定义与项目范围的.babelrc 文件合并,因此您不必复制所有内容。详情in the .babelrc documentation.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2023-04-09
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多