React 17版本候选中的新JSX转换引擎

React 17 Release Candidate引入了一种转换JSX的新方法。有了它,在捆绑包中,不需要React本身,尽管仍然需要使用钩子。这是新机制的主要好处。以下是ReactJS博客上一篇文章的简短翻译



什么是JSX转换



由于浏览器无法立即理解JSX,因此开发人员依靠Babel或Typescript等编译器将JSX转换为纯JS。React 17 Release Candidate引入了一个新的,可选的JSX到JS转换机制。



好处如下:



  • 在不使用React Import的情况下使用JSX
  • 根据设置的不同,捆绑包可能会略有减少
  • 将来,将提供功能以简化工作并做出反应


(也许我没有完全准确地翻译它-这是原始内容:它将使将来的改进减少您学习React所需的概念的数量。



升级不会以任何方式更改JSX本身,并且所有编译器都可以正常工作。没有放弃它们的计划。计划为较早版本的React支持新的JSX转换机制:16.x,15.x,14.x,此处升级说明。



发生了什么变化



旧的JSX转换的工作方式如下:



代码



import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}


转化成



import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}


但这不是很好,这是为什么:





为了解决这个问题,React 17引入了两个新的入口点,供其他工具(例如Babel和Typescript)使用,现在不再转换为React.createElement,而是从React包中导入并调用新函数。



假设您的代码如下所示:



function App() {
  return <h1>Hello World</h1>;
}


经过新的转换后,它将如下所示:



// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}


新机制不会导入React,尽管钩子仍需要工作。



新的转换与所有现有的JSX代码完全兼容,您无需进行任何更改。是有关新JSX转换如何工作技术细节。



如何升级



如果您还没有准备好升级或正在将JSX用于其他库,请不要担心,不会删除旧的转换并将其受支持。



要升级,您需要做两件事:



  • 具有新转换支持的React版本。到目前为止只有17个,但在将来的16.x,15.x和14.x
  • 兼容的编译器(见下文)


Create React App



创建React App支持将在v4.0版本中进行,现在处于beta测试中(截至09/22/2020)



。Next.js



Next.js v9.5.3 +已将新的React转换用于兼容版本。



Gatsby



Gatsby v2.24.5 +已将新的React转换用于兼容版本。



注意
Gatsby 17.0.0-rc.2, npm update



v7.9.0及更高版本的手动Babel配置



支持 如果您正在使用



巴别塔/ plugin-transform-react-jsx:



#npm

npm update @babel/core @babel/plugin-transform-react-jsx

#yarn

yarn upgrade @babel/core @babel/plugin-transform-react-jsx



如果您使用巴别塔/预设反应:



#npm

npm update @babel/core @babel/preset-react

#yarn

yarn upgrade @babel/core @babel/preset-react



现在用于将JSX转换为巴别塔/ plugin-transform-react-jsx和 巴别塔/ preset-react,默认值为{“ runtime”:“ classic”},这是转换的旧版本。要启用新的转换,需要使用{“ runtime”:“ automatic”}选项(



如果使用)巴别塔/预设反应:



{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}


如果您正在使用 巴别塔/ plugin-transform-react-jsx:



{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}


从Babel 8开始,两个插件的默认设置均为“自动”。@ babel / plugin-transform-react-jsx@ babel / preset-react这里有更多详细的文档



注意
, importSource , . , .



ESLint



如果您具有eslint-plugin-react插件,则不再需要react / jsx-uses-react和react / react-in-jsx-scope规则,可以将其删除。



{
  // ...
  "rules": {
    // ...
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off"
  }
}






4.1 beta版开始,TypeScript支持JSX转换



流程



支持从版本JSX转换0.126.0和更高。



如何去除未使用的React导入



由于新的JSX转换将自动导入react / jsx-runtime,因此使用JSX不再需要React。未使用的导入并不重要,但是如果要删除它们,建议使用codemod脚本。



cd your_project
npx react-codemod update-react-imports


结果是:



  • 删除任何未使用的React导入
  • 所有导入(例如从“ react”导入import React)都将从“ react”更改为命名导入{useState}。这是首选的导入方法。Codemod不会影响像import *这样的导入,例如来自“ react”的React,这也是有效的导入,在版本17中它可以工作,但是将来我们会要求您摆脱它


代码:



import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}


将被替换为:



function App() {
  return <h1>Hello World</h1>;
}


如果你用别的东西的反应(例如钩),然后命名的进口将出现在代码:



代码



import React from 'react';

function App() {
  const [text, setText] = React.useState('Hello World');
  return <h1>{text}</h1>;
}


替换为代码:



import { useState } from 'react';

function App() {
  const [text, setText] = useState('Hello World');
  return <h1>{text}</h1>;
}


删除未使用的导入将有助于为React的下一版本(不是17)做准备,在该版本中将支持ES模块并且没有默认导出。



致谢



我们要感谢Babel,TypeScript,Create React App,Next.js,Gatsby,ESLint和Flow团队在集成新JSX转换引擎方面的帮助。我们也感谢React社区对RFC的反馈和讨论



All Articles