webpack-dev-server與熱加載插件整合設置 HMR 實現局部刷新的2種方式

webpack-dev-server與熱加載插件整合設置 HMR 實現局部刷新的2種方式

[toc]css

巨詳細文檔說明-各類狀況都有考慮html

本文將講 react-hot-loader -v3 與 webpack-dev-server -v2.2 整合的那些關鍵點(這個版本適用於開發環境)。 後續會補上 expresswebpack-dev-middlewarewebpack-hot-middleware 的版本(這個版本適用於生產環境)。node

本文與 redbox-react 一塊兒講.react

1. 利用 react-hot-loader 3

1.1. 與redbox-react整合的例子

The react-hot-loader example features the upcoming version 3 (currently 3.0.0-beta.2), but does not yet support error catching and rendering on updates, only on initial mount. This is the future, but it's not quite here.webpack

1.2. 官方文檔Hot Module Replacement - React

1.3.1. 注意-1

webpack-dev-server 必須開啓 2 種 hot server!!!!git

  • 一個 由 屬性 devServer.hot: true 控制(即entry: 'webpack/hot/dev-server') 使用 dev-server.js.
  • 另外一個 由 entry: 'webpack/hot/only-dev-server' 控制 使用 only-dev-server.js

加上 react-hot-loader 的 'react-hot-loader/patch' 就是3個。github

1.3.2. 注意-2

devServer.publicPath 有設置,則其值 必須也建議 與 output.publicPath 同樣。 若不同,則web

  1. index.html 中的bundle.js的引入地址 src="/build/bundle.js" 中的 /build/部分必須保持一致, 不然網頁會找不到bundle.js,由於此時的正確地址爲:devServer.publicPath + bundle.js。 也就是說,devServer.publicPath覆蓋了output.publicPath
    • 1.1. 但這仍是會致使再熱加載時,本應該局部替換頁面不刷新的狀況變成頁面總體刷新!!! 由於 output.publicPath // necessary for HMR to know where to load the hot update chunks

致使再熱加載時,本應該局部替換頁面不刷新的狀況變成頁面總體刷新 的失誤配置點

  1. 在正確設置好局部替換頁面不刷新熱加載相關配置後,又去設置了 devServer.watchContentBase = true
  2. index.html 中的bundle.js的引入地址 src="/build/bundle.js" 中的 /build/部分 與 output.publicPath 值不一致。
  3. devServer.hot 沒有設置爲 true

1.4. 配置注意事項

//.babelrc
"presets": [
  ["latest", { // 注意這裏的書寫格式
    "es2015": {
      "loose": true,
      "modules": false
    }
  }],
  "stage-1",
  "react"
],
// 在配置文件沒作好 分環境 考慮設置時,這個必須
"plugins": ["react-hot-loader/babel"],
// 用於已分好 開發環境用
"env": {
  "development": {
    "plugins": [
      "react-hot-loader/babel"
    ]
}
}
const render = (Component) => {
  ReactDOM.render(
    <AppContainer errorReporter={Redbox}>
      <Component />
    </AppContainer>,
    // document.querySelector('#container'),
    document.getElementById('container'),
  )
}

render(App) // 不能省

if (module.hot) {
  console.log(module.hot)
  // module.hot.accept('components/App', () => {
  module.hot.accept((err) => {  // 地址參數能夠省去
    if (err) {
      console.error('Cannot apply hot update', err)
    }
    render(App)
  })
}
devServer: {
  hot: true, // 使用'webpack/hot/dev-server'
  // watchContentBase: true, // 會引發整個頁面刷新
  // 這項無關緊要
  watchOptions: {
    aggregateTimeout: 300, // rebuild 延時, wait so long for more changes
    ignored: /node_modules/,
    poll: 1000, // 設置檢測文件變化的間隔時間段,Check for changes every second
  },
}

2. 利用 babel-plugin-react-transform - 不推薦

redbox-react整合的例子

The react-transform-catch-errors example shows how to catch and render errors with the deprecated react-transform-catch-errors plugin. This is the way of the past, but it works today.express

添加React Transform支持

Babel-plugin-react-transform 已通過時了,開發者也宣佈已經中止維護babel

"env": {
   "development": {
     "presets": [
       "react-hmre"
     ],
   "plugins": [
     "react-hot-loader/babel",
       ["react-transform", {
           "transforms": [{
             "transform": "react-transform-hmr",
             "imports": ["react"],
             "locals": ["module"]
             }, {
             "transform": "react-transform-catch-errors",
             "imports": ["react", "redbox-react", "../reporterOptions.js"]
           }],
           "factoryMethods": ["React.createClass", "createClass"]
     }]
   ]
 }
 }
相關文章
相關標籤/搜索