天天看點

React 搭建開發環境

React

本文記錄了本人以及目前團隊從無到有使用React的過程,我們将從webpack開始說起,一步一步展現React最基本的開發生态。在這裡并不會介紹任何jsx或es6相關的文法,隻聚焦于如何使用react生态搭建利于團隊協作、有利于提升開發效率的開發環境。

腳手架工具——webpack 

工欲善必須利其器,想要高效的開發react,必須保證有一個高效有序的開發環境。我們使用的是Facebook開源的腳手架工具——webpack來搭建一個完全不依賴伺服器的開發環境。實作高效內建、實時編輯可見、動态編譯jsx和es6等強悍功能。

添加webpack

webpack最早是Facebook的instagram團隊研發出的腳手架工具,用于支援前端系統的開發。雖然webpack一直都和react嵌套在一起使用,但是他的使用場景并不局限于react,你可以把他應用于所有的前端開發場景。

webpack也是依賴nodejs和npm的,在安裝webpack之前務必先安裝nodejs的環境,如果在此之前你還沒有安裝nodejs的環境,可以看這篇

關于nodejs安裝

的文章獲得一些參考。

可以像下面這樣安裝一個全局的webpack環境。

$ npm install webpack -g           

或者以依賴工程的方式安裝

# 進入項目目錄
# 确定已經有 package.json,沒有就通過 npm init 建立
# 安裝 webpack 依賴
$ npm install webpack --save-dev           

測試運作webpack

(本例子的代碼存放在:

https://github.com/chkui/webpack-demo

。下載下傳後用 npm install 下載下傳npm依賴即可使用。)

Setp1:簡單打包

首先我們增加一些用于測試元素。先寫一個index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script src="bundle.js"></script>
</body>
</html>           

然後添加一個entry.js

/**
 * Created by chkui on 2016/11/16.
 */
require("!style!css!./style.css");
document.write('<h1>hello webpack</h1>');           

然後就可以執行打包指令了:

$ webpack ./entry.js bundle.js           

運作以後,就會發現在目錄中生成了一個bundle.js檔案。浏覽器中打開index.html就會看到執行效果。

Step2:利用webpack分析工具打包 

增加一個名為module.js的檔案:

/**
 * Created by chkui on 2016/11/16.
 */
module.exports = 'It works from module.js.'           

在原來的entry.js增加引用:

/**
 * Created by chkui on 2016/11/16.
 */
require("!style!css!./style.css");
document.write('<h1>hello webpack</h1>');
//新增對module.js的引用
document.write(require('./module.js'));           

然後同樣執行webpack打包指令:

$ webpack ./entry.js bundle.js           

然後在打開index.html,會發現我們新增加的module.js的内容被正确輸出。這是因為我們在頁面中通過nodejs的require的方式引入的module.js,而使用webpack打包時會自動在依賴關系中引入module.js。

加載器

webpack提供了一個非常強大的loader功能,這個功能可以用于管理各種依賴關系子產品,在webpack中所有的檔案都視作一個子產品。

首先npm導入webpack loader:

npm install css-loader style-loader           

添加一個用于測試的style.css檔案:

h1{
    color:red;
}           

在entry.js中添加引用:

/**
 * Created by chkui on 2016/11/16.
 */
require("!style!css!./style.css");//添加對css的引用
document.write('<h1>hello webpack</h1>');
document.write(require('./module.js'));           

使用指令行打包:

webpack ./entry.js bundle.js --module-bind 'css=style!css'           

會發現css的樣式生效了。可以将繁瑣的“!style!css!./style.css”簡寫成"./style.css"。

使用配置管理

細心的人會發現,我們每次使用指令行打包都帶了大量的參數,這樣不僅繁瑣更不利于規模化使用。webpack同樣可以使用标準化配置檔案來替代指令行中的各種參數。

webpack的配置檔案是nodejs的檔案,通常命名為 

webpack.config.js

。我們在工程中增加配置檔案:

/**
 * Created by chkui on 2016/11/16.
 */
module.exports = {
    entry: './entry.js',//定義要引入的js檔案
    output: {
        path: __dirname,
        filename: 'bundle.js' //定義要輸出的js檔案
    },
    module: {
        loaders: [//定義加載内容
            {test: /\.css$/, loader: 'style!css'}
        ]
    }
}           

現在,我們在指令行中輸入webpack就可以實作和前面一樣的打包。

豐富打包輸出内容

可以使用:

webpack --progress --colors           

指令來豐富打包輸出的内容,更容易了解出現的問題。

監聽更新模式

在我們進行編碼開發的時候,每次對檔案的編輯我們都想立即看到編譯效果,如果每次編輯都要去打包,會非常麻煩。webpack提供了一個監聽模式(類似grunt的watch),用于監聽每次對檔案的修改,修改後會立即進行增量更新。啟用監聽模式:

webpack --progress --colors --watch           

監聽模式使用的是記憶體增量更新。webpack會将所有需要打包的檔案copy到記憶體,然後監控檔案修改,如果檔案發生了修改,會将修改的檔案替換記憶體中的對應檔案。是以開發完之後,切記進行一次手動打包才能生效。

開發環境模式

webpack更強大的是,他整合了nodejs的express提供了一個靜态伺服器。(雖然沒有官方正式,我覺得webstrom和微信本地開發環境都是整合的nodejs的express)

使用了開發環境模式,我們所有的動态修改和操作都可以實時看到效果,并且解決了靜态資源各種路徑引用的問題。首先npm安裝工具:

npm install webpack-dev-server -g           

然後使用指令行工具啟用開發環境:

webpack-dev-server --progress --colors           

webpack的開發環境模式很強悍,比使用--watch更犀利的地方在于可以實作編輯即可見。浏覽器立即同步重新整理運作。開發環境模式可以延伸到生産環境實作代碼同步級别的熱部署。 

開發環境擴充——Linux下檔案變化監控個數配置

webpack在linux下監控檔案的變化用到了 Inotify機制。有可能在檔案比較多的時候修改、編輯檔案無法觸發webpack熱部署。我們可以通過一下方式檢測并調整監控檔案個數:

#檢查inotify監控檔案的個數
cat /proc/sys/fs/inotify/max_user_watches           

然後可以

#将同時監控的檔案個數修改為18000
echo fs.inotify.max_user_watches=18000 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
           

再次檢視個數可以看到輸出已經配置的參數

開發環境擴充——webstorm的坑

由于本人的前端頁面使用webstorm開發,在使用過程中發現了一個webstorm的坑。webstorm有檔案緩存的功能,在編輯完畢儲存之後并不會實時的更新磁盤檔案,這樣的就導緻webpack的開發環境無法同步更新檔案。以下是解決方法:

1.File->settings->System Settings

2.找到彈出框的Use "safe write",将其勾選解除。

輸出調試資訊

webpack的配置較為複雜,一不小心就會出現錯誤。它提供了一個輸出調試資訊的參數:

$ webpack --display-error-details           

調試運作webpack指令出錯的時候使用。Webpack 中涉及路徑配置最好使用絕對路徑,建議通過 

path.resolve(__dirname, "app/folder")

 或 

path.join(__dirname, "app", "folder")

 的方式來配置,以相容 Windows 環境。

webpack插件

某些時候,webpack的正常功能無法滿足我們的需求,我們可以為webpack開發插件,或者使用其他開發團隊已經完成的插件。

下面是一個插件的标準格式:

function MyPlugin(options) {
  // Configure your plugin with options...
}

MyPlugin.prototype.apply = function(compiler) {
  compiler.plugin("compile", function(params) {
    console.log("The compiler is starting to compile...");
  });

  compiler.plugin("compilation", function(compilation) {
    console.log("The compiler is starting a new compilation...");

    compilation.plugin("optimize", function() {
      console.log("The compilation is starting to optimize files...");
    });
  });

  compiler.plugin("emit", function(compilation, callback) {
    console.log("The compilation is going to emit files...");
    callback();
  });
};

module.exports = MyPlugin;           

需要實作什麼功能,可以按照這個标準去開發自己的插件。

React開發

使用webpack搭建好開發環境後,我們就可以開始着手開發react了。開始之前,我們還是要優先完成開發環境的配置和搭建。

react使用的文法是jsx,現在還新增了對es6的支援。為了可以高效開發,我們需要使用webpack的loader功能,将jsx或es6使用文法糖轉義成浏覽器可以識别的标準JavaScript文法。

下面将繼續在前文webpack的基礎上繼續說明如何開發react。

安裝必要的依賴工具

react的基礎工具包:

$ npm install react --save-dev           

react的dom元件:

$ npm install react react-dom --save-dev           

在前面介紹webpack的時候已經介紹了加載器的概念,這裡需要額外安裝babel用于對react的jsx風格的編碼進行解析,babel除了jsx外還可以解析es6等。安裝babel:

$ npm install babel-loader           

安裝babel-loader之後\node_modules目錄中會額外多安裝一個babel-core,這是babel的核心包。

有了babel,我們還需要安裝編碼轉換規則,用于解析jsx、es6等等。

$ npm install babel-preset-es2015 babel-preset-react --save-dev           

除了babel提供的es6和jsx,webpack還可以使用各種loader來轉換編碼,比如coffeescript等。想要什麼就去google找吧。

完善本地開發環境指令

前面的案例使用 webpack-dev-server 來熱部署本地開發環境提升開發效率。但是每次都靠長長的指令行啟動和停止太過于繁瑣。我們可以利用npm的package.json配置腳本運作來統一管理腳本指令:

{
  "name": "demo2-react",
  "version": "1.0.0",
  "description": "react demo",
  "main": "index.js",
  "scripts":{
    "dev": "webpack-dev-server --progress --colors --inline" //配置運作指令
  },
  //more
}           

添加了scripts後,我們今後隻需要運作

$ npm run dev           

即可使用配置好的指令行參數啟動本地開發環境伺服器。

終于可以開始碼農的核心工作了

(demo代碼存放在:

https://github.com/chkui/react-demo

。下載下傳後用 npm install 下載下傳npm依賴即可使用)

前面準備了這麼久,就是為了随後我們可以快樂的編碼。首先我們按照下面這個結建構立工程結構:

/root
--/dev
----/js
------/index
--------/comps
----------component1.jsx
----------main.jsx
--------index.js
----/style
------/index
--------index.css
----index.html           

然後根據工程的結構修改我們的webpack.config.js:

/**
 * Created by Administrator on 2016/11/17.
 */
var path = require('path');
module.exports = {
    entry: ['./dev/js/index/comps/main.jsx'],//定義要引入的js檔案
    output: {
        path: __dirname,
        filename: './dev/js/index/index.js' //定義要輸出的js檔案
    },
    module: {
        loaders: [{
            test: /\.js[x]?$/,
            exclude: /(node_modules|bower_components)/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015','react']
            }
        }, {
            test: /\.css$/,
            loader: 'style!css'
        }, {
            test: /\.(png|jpg)$/,
            loader: 'url?limit=25000' //隻解析小于25000位元組的圖檔
        }]
    }
};           

和前面介紹webpack的例子相比,這裡的配置檔案新增了了一個babel-loader的配置。

test後的正規表達式表示對所有的js或者jsx檔案進行解析;

exclude表示不解析npm安裝目錄下和bower安裝目錄下的檔案;

loader表示使用的解析工具;

query表示擴充參數,這裡的'es2015'和'react'表示啟用babel-preset-es2015和bable-preset-react解析規則。這裡需要注意的是解析的優先級的倒序的,即會先解析‘react’。

然後我們添加編碼内容(所有的例子都分别實作了jsx規範和es2015規範):

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="comp"></div>
    <script src="/dev/js/index/index.js"></script>
</body>
</html>           

main.jsx:

/**
 * Created by chkui on 2016/11/17.
 */

//jsx
/*
var React = require('react');
var ReactDOM = require('react-dom');
var Comp1 = require('./component1.jsx');
require('../../../style/index/index.css');

ReactDOM.render(
    <div className="main">
        react jsx demo:
        <Comp1 />
    </div>,
    document.getElementById('comp')
);
*/

//es2015
import React from 'react';
import ReactDOM from 'react-dom';
import Comp1 from './component1.jsx' /*切記,大寫是變量小寫是标簽*/
import style from '../../../style/index/index.css'

ReactDOM.render(
    <div className="main">
        react es2015 demo:
        <Comp1 />
    </div>
    ,
    document.getElementById('comp')
);
           

component1.jsx:

/**
 * Created by Administrator on 2016/11/17.
 */

//jsx
/*
var React = require('react');
var comp1 = React.createClass({
    render: function () {
        return (
          <div className = "index">
            hello react!
          </div>
        );
    }
});
module.exports = comp1;
*/

//es6
import React from "react"
class Comp1 extends React.Component{
    //構造函數
    constructor(...args){
        super(...args);
    }
    //覆寫父類的渲染方法
    render() {
        return (
            <div className = "index">
                hello react!
            </div>
        );
    }
}
export default Comp1;
           

編碼完畢之後,我們使用我們設定好的腳本運作我們的本地開發環境:

$ npm run dev           

啟動時,所有的文本都會被讀取到記憶體中,我們可以根據輸出來聊天到底添加了哪些依賴的檔案。啟動完成後,浏覽器上輸入 http://localhost:8080/dev/index.html 或 http://localhost:8080/webpack-dev-server/dev/index.html 即可看到我們用react開發的頁面。此時修改js或css檔案,編輯效果都會立刻呈現在浏覽器上。

React浏覽器調試工具

Facebook提供了基于chrome的頁面調試工具,可以看到所有react元件及其效果。

工具安裝:

  1. 首先最重要的是——翻牆-_-。不翻牆chrome的網上商店就别想了。
  2. 然後在chrome網店搜尋“React Developer Tool”。
  3. 找到後添加到chrome。

添加完成後可以發現在chrome中增加了react的圖示。

然後在demo頁面按F12打開開發人員工具,會發現多了一個React欄目。選擇這個欄目後,會顯示出React元件的效果。

繼續閱讀