設定開發React的環境 - React Hot Loader


前言

對照之前的設定開發React的環境文章,經過了一段時間內又有一些新的修改。首先最大的修改部份是原本被棄用的react-hot-loader,現在又復活了,而react-transform-hmr則是被棄用。這兩個用法有一些小差異,本文快速的說明新的樣版文件(boilerplate)的一些設定部份。

Hot Loading

Hot Loading(熱載入)的用途是讓開發者在開發過程中,如果對程式碼有修改或調整的部份,可以立即觸發網頁的重新載入(reloading,但這裡所指的並非一般的page reloading),不過並不是完全的重新載入,而是只針對修改的功能部份載入。它可以提供開發時的方便性,讓開發者的日常工作更為輕鬆,這也是一個開發時使用的主流作法。這個功能是藉由Webpack的Hot Module Replacement (HMR)功能所提供,所以它有幾個條件:

  • Using Plugins
  • Code Splitting
  • webpack-dev-server

Webpack另外有一種Hot Loading的作法,是使用Middleware(也是一種Plugin)的方式 - Webpack Hot Middleware,它不需要webpack-dev-server,所以可以搭配各種的已存在的Server框架,例如Express等等,這也是另一種常見的作法。在這篇stackoverflow的問答中你可以看到這兩種作法的差異性。

react-hot-loader

新發佈的react-hot-loader版本,除了提供了一篇專文說明外,另外也有一個樣版文件,以下大概說明一些由文件與樣版文件程式碼所提供的重要部份:

安裝

安裝沒什麼特別的,除了react-hot-loader本身之外,當然還需要安裝babel與eslint等等需要的套件庫:

npm install --save-dev react-hot-loader

當然,webpack-dev-server是必要的,所以你的專案中也需要安裝webpack-dev-server與webpack,這裡就不多說了。

webpack-dev-server設定

webpack-dev-server是主要的啟動伺服器,這裡有一個關鍵的設定,就是在建立一個新的WebpackDevServer時,需要指定hot: true這個選項,樣版文件中用了一個server.js專用於啟動webpack-dev-server之用,啟動時是使用node server.js的命令列指令:

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true
}).listen(3000, 'localhost', function (err, result) {
  if (err) {
    return console.log(err);
  }

  console.log('Listening at http://localhost:3000/');
});

webpack設定

webpack使用webpack.config.js檔案來進行設定,有一些與Hot Reloading是相關的,其中在entry的部份:

entry: [
    'webpack-dev-server/client?http://localhost:3000',// host 與 port
    'webpack/hot/only-dev-server',// "only" 可以避免在語法錯誤時重新載入
    './src/index'// 你的應用程式進入點
  ]

module的區段加入了react-hotbabel,這與之前的使用方式差不多:

module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['react-hot', 'babel'],
      include: path.join(__dirname, 'src')
    }]
  }

plugins的區段加入webpack.HotModuleReplacementPlugin(),在設定檔案webpack.config.js的最上面也要加上var webpack = require('webpack');才行,這一點是需要注意一下的:

plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],

註: 如果你是使用命令列的指令來執行webpack-dev-server的話,不需要使用這個plugin,而是在命令列中加上--hot的模式。

關於Sourcemap的產生設定值,為了效率與搭配hot loader使用,在這份文件中的建議設定值如下:

devtool: 'eval'

其他設定

.babelrc是babel的設定,樣版文件用的很簡單:

{
  "presets": ["es2015", "stage-0", "react"]
}

.eslintrc是eslint的設定,提升程式碼品質與檢查語法的套件,樣版文件也是用得很簡單。(這文件可以設定到很複雜。):

{
  "ecmaFeatures": {
    "jsx": true,
    "modules": true
  },
  "env": {
    "browser": true,
    "node": true
  },
  "parser": "babel-eslint",
  "rules": {
    "quotes": [2, "single"],
    "strict": [2, "never"],
    "react/jsx-uses-react": 2,
    "react/jsx-uses-vars": 2,
    "react/react-in-jsx-scope": 2
  },
  "plugins": [
    "react"
  ]
}

.jshintrc是JSHint的設定檔,它也是提升程式碼品質與檢查語法的工具,esnext代表ES6的選項,樣版文件也是很簡單的幾行設定而已:

{
  "node": true,
  "browser": true,
  "esnext": true,
  "newcap": false
}

其他樣版文件