webpack之babel配置和HMR

wuzhengyan2015發表於2018-07-01

webpack 是前端開發最常用的模組打包器之一,我們可能是使用github上提供的腳手架如react-boilerplate,也有可能根據自己的專案來寫webpack配置。無論你是屬於哪一種情況,你還是要熟悉webpack的相關配置才能更好的使用它。

接下來主要介紹webpack中的babel配置和HMR兩塊內容。

babel

Babel 是一個 JavaScript 編譯器。 通過編譯轉換允許你立刻使用新語法,無需等待瀏覽器支援。

現在babel的版本是6.x,下面提到的知識點都是基於這個版本的。

.babelrc

.babelrc 是用來配置轉碼的規則和外掛的。

{
  // 倒序編譯
  "presets": [
    "env",
    "react"
    "stage-2",
  ],
  "plugins": ["transform-runtime"],
}
複製程式碼

presets是一堆plugins的預設,起到方便的作用。

plugins是編碼轉化工具,babel會根據你配置的外掛對程式碼進行相應的轉化。

除了presets和plguins配置,babel還支援對應的環境下相關配置。

"env": {
    "production": {
      "plugins": ["transform-react-constant-elements"]
    }
  }
複製程式碼

babel-preset-env

babel-preset-env 預設情況下是等於 ES2015 + ES2016 + ES2017,也就是說它對這三個版本的ES語法進行轉化。

這個preset提供了一些配置,如下面通過配置針對各個瀏覽器的最新的兩個版本,以及safari的版本7及以上進行轉碼

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      }
    }]
  ]
}
複製程式碼

babel-preset-stage-n

ECMAScript標準的制定流程包含下面幾個階段。

  • Stage 0 - Strawman(展示階段)
  • Stage 1 - Proposal(徵求意見階段)
  • Stage 2 - Draft(草案階段)
  • Stage 3 - Candidate(候選人階段)
  • Stage 4 - Finished(定案階段)

babel-preset-stage-n 包括了 babel-preset-stage-0, babel-preset-stage-1, babel-preset-stage-2, babel-preset-stage-3。

那麼為什麼沒有babel-preset-stage-4呢?第四階段屬於定案完成階段了,相關的內容就在上邊的babel-preset-env中。

各個stage之間是包含關係,stage-0會包含stage-1, stage-2, stage-3, 如此類推。

每個stage都包含相應的外掛,個人常用的是stage-2,包含外掛有類屬性語法、裝飾器語法、物件展開操作、async/await等。

babel-preset-react

這個預設就是包含了react開發所需的相關外掛,支援react開發相關語法。

babel-polyfill

Babel 預設只轉換新的 JavaScript 句法(syntax),而不轉換新的 API ,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全域性物件,以及一些定義在全域性物件上的方法(比如 Object.assign)都不會轉碼。

如上述所說,對於新的API,你可能需要引入babel-polyfill來進行相容

安裝和使用:

npm install --save babel-polyfill
+ import "babel-polyfill"
+ module.exports = { entry: ['babel-polyfill', './app/js'] }
複製程式碼

關鍵點:

  • babel-polyfill 是為了模擬一個完整的ES2015+環境,旨在用於應用程式而不是庫/工具。
  • babel-polyfill 會汙染全域性作用域

babel-runtime 和 transform-runtime

babel-runtime的作用:

  • 提取輔助函式。ES6轉碼時,babel 會需要一些輔助函式,例如 _extend。babel 預設會將這些輔助函式內聯到每一個 js 檔案裡, babel 提供了 transform-runtime 來將這些輔助函式“搬”到一個單獨的模組 babel-runtime 中,這樣做能減小專案檔案的大小。
  • 提供polyfill:不會汙染全域性作用域,但是不支援例項方法如Array.includes

安裝:

npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime
複製程式碼

babel-runtime 更像是分散的 polyfill 模組,需要在各自的模組裡單獨引入,藉助 transform-runtime 外掛來自動化處理這一切,也就是說你不要在檔案開頭import相關的polyfill,你只需使用,transform-runtime會幫你引入。

babel-runtime一般用在庫的開發

HMR

兩種方式都可以實現熱載入。

CLI方式

  1. package.json 增加 --hot
"dev": "webpack-dev-server --color --progress --hot"
複製程式碼
  1. src/index.js 增加module.hot.accept(),如下。當模組更新的時候,通知index.js
if (module.hot) {
    module.hot.accept();
}

console.log('hot module replacement work')
複製程式碼

Node.js API方式

  1. webpack.config.js
const webpack = require('webpack');

devServer: {
    hot: true
}

plugins:[
     new webpack.HotModuleReplacementPlugin()
]
複製程式碼
  1. src/index.js 增加module.hot.accept(),如下。當模組更新的時候,通知index.js

相關參考

相關文章