使用webpack4一步步搭建react項目(三)

第二章的配置基本已能達到正常的開發需求了。可是還有不少地方能夠進行改善。javascript

第三章 改善項目

使用最新的ES語法

React開發中不免要用到ES最新語法。例如經常使用的Decorators還在Stage 2階段,Dynamic import還在Stage 3階段。這些新的語法並沒被@babel/preset-env涵蓋。所以咱們須要額外配置對應的babel插件。css

安裝babel插件:java

  • 支持裝飾器 @babel/plugin-proposal-decorators
  • 支持類屬性 @babel/plugin-proposal-class-properties
  • 支持動態import @babel/plugin-syntax-dynamic-import

配置.babelrc文件:node

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    // 注意decorators插件要寫在class-properties前面
    // decorators插件須要配置legacy爲true來兼容之前的裝飾器寫法
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    "@babel/plugin-syntax-dynamic-import"
  ]
}
複製代碼

添加css預處理與postcss

咱們可使用sass來加強css的編程和抽象能力,使用postcss的autoprefixer插件給css自動添加瀏覽器廠商前綴。react

安裝:webpack

  • sass-loader
  • postcss-loader autoprefixer

webpack.dev.js的配置:git

// ...
module: {
  rules: [
    {
      test: /\.scss$/,
      // loader是從後往前加載的,postcss-loader得在sass-loader前面
      use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"]
    },
    // ...
  ]
},
// ...
複製代碼

webpack.prod.js的配置:es6

// ...
module: {
  rules: [
    {
      test: /\.scss$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader",
        "sass-loader"
      ]
    },
    // ...
  ]
},
// ...
複製代碼

在項目根目錄下建立postcss.config.js文件:github

module.exports = {
  plugins: [require("autoprefixer")]
};
複製代碼

配置瀏覽器兼容範圍

.babelrc內配置的@babel/preset-env能自動爲項目打包必要的polyfill,postcss.config.js內配置的autoprefixer插件能自動爲css添加必要的瀏覽器廠商前綴。它們是怎麼肯定哪些polyfill還有哪些瀏覽器廠商前綴是必要添加的呢,畢竟不一樣公司甚至不一樣項目所要兼容的瀏覽器版本不同。有的項目沒有任何兼容需求,那麼項目應該少依賴一些polyfill,有些項目要兼容到IE瀏覽器,那就要添加更多的polyfill和瀏覽器廠商前綴。因此咱們須要配置.browserslistrc來告訴這些打包工具咱們要兼容的瀏覽器範圍。web

在項目根目錄下建立.browserslistrc文件:

> 1%
last 2 versions
not ie <= 8
複製代碼

這個配置的大概意思是:市場份額大於1%的瀏覽器,最新的兩個版本,排除IE8如下的瀏覽器。

配置.editorconfig

有些人喜歡用水平製表符縮進,而有些人喜歡用2個空格。由於使用的操做系統不一樣,有些人換行符是LF,有些人是CRLF。雖然這些瑣碎的東西能夠在項目開發初期約定好,並設置到每一個開發人員編輯器格式化配置內。可是這樣很麻煩。

咱們在項目根目錄下建立.editorconfig

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
複製代碼

這個配置告訴編輯器,當前項目的縮進用的是2個空格,換行用的是LF,並在每一個文件底部插入一行空行。編輯器看到項目內有.editorconfig文件,就會按它的要求來格式化項目文件。

使用editorconfig的好處是,他能更細粒度的控制每一個項目甚至不一樣文件類型的格式化風格,這樣可讓不一樣的項目擁有不一樣的格式化風格。

配置完後,編輯器須要在插件市場下載editorconfig插件。webstorm內部默認安裝了該插件,因此能夠不用下載。

配置ESLint和prettier

ESLint能夠校驗咱們的代碼風格和一些語法錯誤,在團隊開發時,能夠保證代碼風格的一致性並及早發現一些錯誤。

ESLint不少時候會由於缺乏空格或逗號而報錯,這些瑣碎的錯誤會很惱人,所以咱們可使用prettier來幫助咱們來格式化代碼。

安裝:

  • eslint eslint-loader
  • babel-eslint
  • eslint-config-airbnb eslint-config-prettier

在安裝eslint-config-airbnb時,控制檯會有warning,咱們須要根據它的warning將全部的peer dependency都安裝好。

webpack.common.js配置:

// ...
module: {
  rules: [
    {
      enforce: "pre",
      test: /\.jsx?$/,
      include: path.resolve(__dirname, "src"),
      use: "eslint-loader"
    },
    // ...
  ]
}
// ...
複製代碼

根目錄下添加.eslintrc.js

module.exports = {
  root: true,
  parser: "babel-eslint",
  env: {
    browser: true,
    es6: true,
    node: true
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: "module"
  },
  extends: ["airbnb", "prettier"],
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
  }
};

複製代碼

package.json內添加lint precommit兩條腳本

// ...
"scripts": {
  "start": "cross-env NODE_ENV=development webpack-dev-server --config webpack.dev.js",
  "build": "cross-env NODE_ENV=production webpack --config webpack.prod.js",
  "lint": "cross-env NODE_ENV=production eslint --ext .jsx --ext .js --fix ./src",
  "precommit": "npm run lint"
},
// ...
複製代碼

執行npm run lint時,ESLint會檢查./src目錄下的全部.js .jsx結尾的文件,並盡力修復一些問題。ESLint不能修復的問題會打印到控制檯上,此時就要手動去修復問題了。

每次git提交代碼前會先執行precommit腳本,該腳本就是讓ESLint檢查代碼,若是檢查不經過就沒法提交代碼。這樣能夠保證代碼倉庫內的代碼質量。想要precommit腳本生效,須要安裝husky(哈士奇),並且咱們在腳本內使用「cross-env」來修改環境變量,因此得安裝cross-env

安裝:

  • husky
  • cross-env

推薦在編輯器內安裝ESLint 插件,這樣能在書寫代碼實就能看的ESLint的報錯信息。安裝ESLint插件後,它可能會在咱們不肯意它去檢查的文件內報錯,因此咱們添加.eslintignore來告訴插件要跳過的檢查文件與目錄。

.eslintignore配置

node_modules
/dist

webpack.common.js
webpack.prod.js
webpack.dev.js
postcss.config.js
複製代碼

同時推薦安裝prettier插件,並配置編輯器在保存時自動格式化。

熱更新 (Hot Module Replacement)

使用webpack-dev-server開發React時,每次文件修改便會自動刷新頁面。雖然這和傳統的手動刷新頁面相比方便了不少,可是在某些狀況下還不夠方便。就好比開發一個表單模態窗口時,刷新頁面會致使模態窗口被關閉,而且表單內填寫的信息丟失。

webpack的熱更新就能解決這個痛點,它能在界面不刷新的狀態下更新界面。

webpack4默認支持熱更新,咱們只須要開啓這個功能就能夠。

webpack.dev.js內開啓熱更新:

// ...
devServer: {
  hot: true, // 開啓熱更新
  historyApiFallback: true
},
// ...
複製代碼

咱們使用react-hot-loader來支持React的熱更新。

安裝:

  • react-hot-loader

.babelrc添加react-hot-loader提供的插件:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    "@babel/plugin-syntax-dynamic-import",
    "react-hot-loader/babel"
  ]
}
複製代碼

注意這個插件的寫法是react-hot-loader/babel

最後,修改App.jsx內的代碼。使用react-hot-loader提供的高階組件來裝飾咱們的App組件。

import React from "react";
// 導入hot函數
import { hot } from "react-hot-loader/root"; 

// ...

function App() {
  return (
    // ...
  );
}

// 使用hot函數裝飾App組件
export default hot(App);
複製代碼

搖樹優化 (Tree Shaking)

webpack4在production模式下會開啓Tree Shaking,可是須要注意如下幾點

  • 使用ES2015模塊語法(例:importexport),被編譯成CommonJS規範的模塊不能被優化。
  • 須要在package.json文件內添加"sideEffects"字段。該字段的值能夠是模塊名稱數組,用來告訴webpack哪些模塊是有負做用的。該字段的值也能夠是false,表示全部模塊都沒有反作用。被標識有反作用的模塊不會被Tree Shaking。
  • webpack配置內的mode設爲"production"

代碼

項目代碼 Github 倉庫

其餘章節

相關文章
相關標籤/搜索