天天看點

導入 react 的正确方法

背景

目前我們常見的有兩種引入

react

的方法:

import React from 'react';
// vs
import * as React from 'react';           

這兩種寫法目前都可以運作,但是同一個目的出現兩種寫法就容易産生分歧,本文主要闡述這兩種寫法的不同并給出我建議的寫法。

便捷性

從便捷性角度來講,無疑第一種方式要少打好多字元。另外如果我們要引用

react

包内的其它導出項時,第一種方式的有點更明顯:

import React, { useState } from 'react';

export default function MyComponent() {
  const [foo, setFoo] = useState();

  return <div>{foo}</div>;
}           

對比後一種寫法:

import * as React from 'react';

export default function MyComponent() {
  const [foo, setFoo] = React.useState();

  return <div>{foo}</div>;
}           

這裡隻能通過

React

命名空間來引用内部導出項。

或者也可以單獨再導出一遍内部項:

import * as React from 'react';
import { useState } from 'react';           

無論怎麼寫,都很難達到第一種寫法的便捷性。

文法和語義

ES 文法裡并沒有命名空間的文法,

export

關鍵字是作用于目前檔案的,是以隻有檔案是在 ES Module 語義下的命名空間。

export default

隻是

export

的一個特例,用于導出一個特殊的名字,并不能用來導出一個命名空間.有人還是習慣于用一個對象來模拟一個命名空間:

export default {foo, bar};           

這種寫法并不符合 ES Module 的方式,建構工具是無法進行靜态分析,也無法進行

Tree Shaking

更多關于

export default

的解釋可以參考

《export default 真的有害嗎?》

從語義的角度來講,第一種寫法就是錯誤的,

React

僅僅是作為一個命名空間存在的,我們并不會像使用一個值一樣來使用

React

。從 React 16.13.0 開始,React 的導出方式也已經更正為

export {xxx, ...}

的形式了(

commit

)。

之是以第一種導入方式還可以使用,是因為目前 React 的建構産物是 Commonjs 規範的,webpack 等建構工具做了相容。

自動導入

相對于語義的正确性,我覺得這一點便捷性是應該犧牲一下的,但是有沒有在不犧牲語義的情況下獲得便捷的方法?下面我們來聊聊自動導入。

正常情況,我們不需要使用

import * as

文法來導入一個包,但是 JSX 檔案的編譯需要

React

命名空間。既然 JSX 是文法層面的擴充,那麼把這個命名空間的導入也放到文法層面去解決也是理所當然的。

babel-plugin-transform-react-jsx 的自動導入模式

目前隻在 React 17 中可用,針對之前的版本,我們可以使用非官方的

babel-plugin-auto-import

插件。

總結

如何導出決定如何導入。

按順序簡要列一下可選的導入方案:

  1. 【最佳方案】自動導入
  2. 【相容性好】

    import * as React from 'react';

  3. 【不再推薦】

    import React from 'react';

思考題

下面兩種導入樣式的寫法有什麼差別?應該選擇哪種?

  • import * as styles from './index.module.scss

  • import styles from './index.module.scss

提示:

https://webpack.js.org/loaders/style-loader/#esmodule

繼續閱讀