原文链接:大家不要再手动引入 React 了

一、TS 是如何编译成 JS 文件

很多人会觉得我们用 ts 那肯定是 tsc 编译的,其实不是,目前大多数的 ts 工程都是 ts 类型检查 + babel 编译这样的组合。

用 babel 编译 ts,就可以实现这样一种效果:babel 编译一切,降低开发/配置成本

我们代码中的jsx/tsx文件,就是用@babel/plugin-transform-react-jsx 这个babel插件转换的:插件地址

注意:This plugin is included in @babel/preset-react.

二、组件文件开头引入 React

通常我们在写每个组件开头都引入:

  1. import React from 'react'

之所以这么做的原因是,jsx 只是个语法糖,上文中的那个插件,会把 jsx 这样转换:

  1. import React from 'react';
  2. function App() {
  3. return <h1>Hello World</h1>;
  4. }

转换成:

  1. import React from 'react';
  2. function App() {
  3. return React.createElement('h1', null, 'Hello world');
  4. }

大家看到转换出来的结果是要用 React 变量的,所以必须要引入 React 以保证它在作用域中

三、为什么不需要再引入 React 了

因为上面说的那种转换方式是上一个版本的转换方式了。

2020年底 plugin-transform-react-jsx 发布了新版本,从 v7.9.0 开始,就不用手动引入 React 了,因为转换变成这样了:

  1. const profile = (
  2. <div>
  3. <img src="avatar.png" className="profile" />
  4. <h3>{[user.firstName, user.lastName].join(" ")}</h3>
  5. </div>
  6. );

编译成:

  1. import { jsx as _jsx } from "react/jsx-runtime";
  2. import { jsxs as _jsxs } from "react/jsx-runtime";
  3. const profile = _jsxs("div", {
  4. children: [
  5. _jsx("img", {
  6. src: "avatar.png",
  7. className: "profile",
  8. }),
  9. _jsx("h3", {
  10. children: [user.firstName, user.lastName].join(" "),
  11. }),
  12. ],
  13. });

所以就可以摆脱手动引入 React 了。这个功能默认是关闭的,但是从 create-react-app 4.0 开始,默认就是打开的了。

总之,大家的工程不需要手动引入 React。