[React項目總結一] 基於 webpack 搭建前端工程基礎篇

目錄

  1. 技術選型css

  2. webpack 基礎html

    • 安裝 webpack前端

    • webpack 簡介node

    • 使用webpack-dev-server啓動服務器react

  3. 配置 React, ES6 & Babel 6webpack

  4. 使用 ESlint 進行代碼檢查git

  5. 樣式處理es6

  6. 圖片處理github

  7. 區分開發及生產環境web

  8. 構建流程圖

  9. 文件說明

  10. 參考


完整實例代碼

git-repo
github issues

1. 技術選型

最近在一個項目初步嘗試使用了reactJS,開發週期兩週,選用的技術棧大體以下:

JavaScript:

  • Language: ES6

  • Framework: React, Redux

CSS:

  • Language: SCSS

  • Framework: ant-design

Build Tool:

  • Webpack

Dependency manage

  • npm

Git workflow:

  • Gitlab flow

API:

  • JSON


2. webpack 基礎

2.1安裝 webpack

做爲全局變量安裝

$ npm install -g webpack
 $ webpack -v => webpack 1.13.0

做爲項目依賴安裝

$ npm install webpack --save-dev

2.2 webpack 簡介

webpack 的配置項主要包括如下幾點:

webpack_config_js.png

  • entry: 入口,定義要打包的文件

  • output: 出口,定義打包輸出的文件;包括路徑,文件名,還可能有運行時的訪問路徑(publicPath)參數

  • module: webpack將全部的資源都看作是模塊,而模塊就須要加載器;主要定義一些loaders,定義哪些後綴名的文件應該用哪些loader

    • test: 檢測哪些文件須要此loader,是一個正則表達式

    • exclude: 忽略哪些文件

  • resolve: 定義可以被打包的文件,文件後綴名

  • plugins: 定義一些額外的插件

示例用到的 Loaders
  • 處理樣式:sass-loader、style-loader、css-loader,將 sass 轉成 css

  • 圖片處理,url-loader、file-loader、image-webpack-loader, 將圖片轉換成base64 或者 進行壓縮

  • js處理: babel-loader,babel-preset-es2015,babel-preset-react,將es6或更高級的代碼轉成es5的代碼

示例用到的 Plugins
  • 代碼熱替換:HotModuleReplacementPlugin

  • 生成html文件:HtmlWebpackPlugin

  • 報錯但不退出webpack進程:NoErrorsPlugin

  • 代碼壓縮:UglifyJsPlugin

  • 自動打開瀏覽器: OpenBrowserPlugin

  • 設置環境變量: DefinePlugin

2.3 使用 webpack-dev-server 啓動服務器

2.3.1 刷新功能

webpack提供的一個靜態資源服務器,這個傢伙可不太好配置,看官方文檔給看懵了,試驗了好幾回才配成功,後面咱們會根據 NODE_ENV 環境變量分別配置 dev mode server 和 prod mode serve;先來看看其功能:

  • 支持兩種模式的自動刷新(Automatic Refresh)

    • iframe模式

    • inline模式

  • 支持熱更新(Hot Module Replacement)

    注: 自動刷新和熱更新是兩個概念

2.3.2 這裏主要介紹自動刷新 inline 模式的配置,inline模式又分爲兩種配置:
  • 命令行模式: 命令行模式只須要加上 --line選項便可

    $ webpack-dev-server --line
  • Node.js API: 使用node.js api須要手動添加配置

var config = {
   entry: [
     'webpack/hot/dev-server',
     'webpack-dev-server/client?http://localhost:8080',
     path.resolve(__dirname, 'app/index.js')
   ],
 }
2.3.3 配置 Hot Module Replacement

這是webpack最牛逼的特性之一,即模塊熱替換,在前端代碼變更的時候無需整個刷新頁面,只把變化的部分替換掉。使用HMR功能也有兩種配置方式:

  • 命令行方式: 命令行模式只須要加上 --line --hot 選項。 --hot 會自動把 webpack/hot/dev-server 加入到了webpack配置文件中的入口點。若是執行正確,能夠在瀏覽器的控制檯看到如下信息。

    [HMR] Waiting for update signal from WDS...
    [WDS] Hot Module Replacement enabled.
  • Node.js API: 手動配置須要作三件事情:

    • webpack/hot/dev-server 加入到webpack配置文件的entry項

    • new webpack.HotModuleReplacementPlugin() 加入到webpack配置文件的plugins項

    • hot:true 加入到webpack-dev-server的配置項裏面

2.3.4 完整配置,主要分爲三部分:
  • webpack.config.js: webpack常規配置,配置入口文件,輸出文件,loaders等等

  • server.js: 將server部分分離到一個單獨到的文件配置

  • package.json: 自定義啓動命令

<!-- webpack.config.js -->
 var webpack = require('webpack');
 var path = require('path');
 var config = {
   entry: [
     path.resolve(__dirname, 'app/index.js')       // 定義入口文件
   ],
   output: {                                       // 定義出口目錄
     path: path.resolve(__dirname, 'build'),
     filename: 'bundle.js',
     publicPath: '/'
   },
   resolve: {                                      // resolve 指定能夠被 import 的文件後綴
     extensions: ['', '.js', '.jsx']
   },
   module: {
   },
   plugins: [
     new webpack.HotModuleReplacementPlugin()
   ]
 }

 module.exports = config;
<!-- server.js -->
var webpack = require('webpack');
var webpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config.js');

var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
  historyApiFallback: true,
  hot: true,
  inline: true,
  progress: true,
  contentBase: './app',
  stats: { colors: true }
});

config.entry.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");

server.listen(8080, "localhost", function(err) {
  if(err) {
    console.log(err);
  }
  console.log('Listening at localhost:8080...');
});
<!-- package.json -->
"scripts": {
  "start": "node server.js"
}

如今你能夠經過運行 npm start 啓動服務器來。

hrm


3. 配置 React, ES6 & Babel 6

ES6 和 JSX 轉換

在最新的babel 6.x 版本中,在指定哪些代碼轉換器將被啓用時,須要配置 presets 。最簡單配置的方法就是項目根目錄下建一個 .babelrc 文件:

// .babelrc
{
  "presets": [
    "es2015",
    "react"
  ]
 }

配置好以上代碼,你就能夠開始用 es2015, jsx 了,相關的依賴包

* babel-loader: 轉換JSX
  * babel-core: 即babel的包
  * babel-preset-es2015: es2015的babel預設

4. 使用 ESlint 進行代碼檢查

特色:

  • 默認規則包含全部 JSLint、JSHint 中存在的規則,易遷移

  • 規則可配置性高:可設置「警告」、「錯誤」兩個 error 等級,或者直接禁用;

  • ESLint 支持 JSX, 不過目前爲 alpha 版本,正式版發佈以前能夠先使用 eslint-plugin-react 替代

配置:

能夠經過如下三種方式配置 ESLint:

  • 使用 .eslintrc 文件(支持 JSON 和 YAML 兩種語法)

  • package.json 中添加 eslintConfig 配置塊

  • 直接在代碼文件中定義

下面主要演示經過 .eslintrc 配置的步驟:

4.1 在項目根目錄下面新建 .eslintrc 文件
$ touch .eslintrc
4.2 Specifying Parser Options
{
  "parserOptions": {
    "ecmaVersion": 6,  // 指定ECMAScript 版本
    "sourceType": "module", // 設置爲 "script" (默認) 或 "module"(若是你的代碼是 ECMAScript 模塊)
    "ecmaFeatures": { 
        "jsx": true // 啓用 JSX
    }
  }
}
4.3 Specifying Environments
{
  "env": {
    "browser": true,
    "node": true,
    "es6": true,
    "mocha": true
  }
}
4.4 Configuring Plugins
"plugins": [
  "plugin1",
  "eslint-plugin-plugin2"
]
4.5 Configuring Rules
{
  "rules": {
      "eqeqeq": "off",
      "curly": "error",
      "quotes": ["error", "double"]
  }
}
4.6 Extending Configuration Files
  • extends 屬性值能夠是:

    • 在配置中指定的一個字符串

    • 字符串數組:每一個配置繼承它前面的配置

*rules 屬性能夠作下面的任何事情以擴展(或覆蓋)規則:
參數:0 關閉,1 警告,2 錯誤

  • 啓用額外的規則

  • 覆蓋基礎配置中的規則的默認選項

  • 禁用基礎配置中的規則

4.7 如下是eslint配置文件常見的格式
{
  "parserOptions": { //EsLint經過parserOptions,容許指定校驗的ecma的版本,及ecma的一些特性
    "ecmaVersion": 6, //指定ECMAScript支持的版本,6爲ES6
    "sourceType": "module", //指定來源的類型,有兩種」script」或」module」
    "ecmaFeatures": { // ecmaFeatures指定你想使用哪些額外的語言特性
        "jsx": true //啓動JSX
    }
  },
  "parser": "babel-eslint", // EsLint默認使用esprima作腳本解析,也能夠切換成babel-eslint解析
  "env": { // Environment能夠預設好的其餘環境的全局變量,如brower、node環境變量、es6環境變量、mocha環境變量等
    "browser": true,
    "node": true,
    "es6": true,
    "mocha": true
  },
  "plugins": [ // EsLint容許使用第三方插件
    "react"
  ],
  extends: [ // Extends是EsLint默認推薦的驗證你可使用配置選擇哪些校驗是你所須要的
    "eslint:recommended"
  ],
  rules: [ // 自定義規則
  ],
  "globals": { // 即插件在執行過程當中用到的其它全局變量
  }
}
4.8 Ignoring Files and Directories

經過在項目根目錄建立一個 .eslintignore 文件告訴 ESLint 去忽略特定的文件和目錄。

4.9 在Sublime中安裝插件:
SublimeLinter
SublimeLinter-contrib-eslint
4.10 相關插件
  • babel-eslint: ESLint 是前端JS代碼檢測利器。而 babel-eslint 則容許你檢測全部的 Babel 代碼

  • eslint: JavaScript 語法檢測利器:分析出你代碼潛在的錯誤和非標準用法

  • eslint-plugin-react: ESLint 中關於 React 語法檢測的插件

4.11工做流集成

  • 編輯器

  • 構建工具

4.12 更多參考

4.13 運行 "eslint app

eslint


5. 樣式處理

主要使用sass預處理器編寫樣式,須要先經過sass-loader處理成css,而後再經過css-loader加載成css模塊,最後由style-loader加載器對其作最後的處理,從而運行時能夠經過style標籤將其應用到最終的瀏覽器環境。

$ npm install css-loader style-loader sass-loader node-sass --save-dev

安裝好依賴後,經過如下簡單的配置就可使用sass;這裏須要注意的一點是須要開啓 sourceMap 功能,便於調試。

devtool: "source-map",
module: {
 loaders: [
   {
     test: /(\.css|\.scss)$/,
     loaders: ["style", "css?sourceMap", "sass?sourceMap"]
   }
 ]
}

6. 圖片處理

圖片處理常見的loader有如下三種:

  • file-loader: 默認狀況下會根據圖片生成對應的 MD5 hash 的文件格式

  • url-loader: url-loader相似於file-loader,可是url-loader能夠根據自定義文件大小或者轉化爲 base64 格式的 dataUrl,或者單獨做爲文件,也能夠自定義對應的 hash 文件名

  • image-webpack-loader: 提供壓縮圖片的功能

// url-loader 配置
module: {
  loaders: [
    {
      test: /\.(jpe?g|png|gif|svg)$/i,
      loaders: [
        'url?limit=10000&name=img/[hash:8].[name].[ext]', // 圖片小於8k就轉化爲 base64, 或者單獨做爲文件
        'image-webpack' // 圖片壓縮
      ]
    }
  ]
}
// file-loader 配置
module: {
  loaders: [
    test: /\.(jpe?g|png|gif|svg)$/i,
    loaders: [
      'file?hash=sha512&digest=hex&name=[hash].[ext]', // 生成 md5 hash 格式的文件名
      'image-webpack' // 圖片壓縮
    ]
  ]
}

對於小質量的圖片資源,能夠由 url-loader 實現將其進行統一打包,代碼中 url-loader?limit=8192 的含義就是對於全部小於 8kb 的圖片資源轉換成base64 格式。這在必定程度上能夠替代CSS Sprites方案,用於減小對於小圖片資源的HTTP請求數量。


7. 配置生產環境

7.1 前端開發環境一般分爲兩種:
  • 開發環境: 須要日誌輸出,sourcemap ,錯誤報告等等

  • 生產環境:須要作代碼壓縮,對文件名進行 hash 處理等等

爲了區分咱們能夠建立兩個文件分別進行不一樣環境下的配置:

  • webpack.config.dev.js // 開發環境

  • webpack.config.prod.js // 生產環境

7.2 區分環境

webpack 提供了 DefinePlugin 設置環境變量,後面會根據設置的不一樣環境變量決定是否打包壓縮,仍是啓動dev server 或者是 prod server

plugins: [
    ...
    new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production') // or development
    }),
]

判斷當前環境是不是生產環境

var isProduction = function () {
  return process.env.NODE_ENV === 'production';
};

set node env

7.3 代碼壓縮

webPack 提供了內建插件,直接配置如下代碼便可壓縮代碼

new webpack.optimize.UglifyJsPlugin({
  compress: {
    warnings: false
  }
})
7.4 添加 Hash 緩存
  • 對於沒有修改的文件,從緩存中獲取文件

  • 對於已經修改的文件,不要從緩存中獲取

output: {
    ...
    filename: '[chunkhash:8].bundle.js' // chunkhash 默認是16位,可自定義配置
    ...
  },
7.5 自動生成頁面

文件名帶上 hash 值後,這個值在每次編譯的時候都會發生變化,都須要在 html 文件裏手動修改引用的文件名,這種重複工做很瑣碎且容易出錯,這裏咱們可使用 html-webpack-plugin 來幫咱們自動處理這件事情, 用來簡化建立服務於 webpack bundle 的 HTML 文件,流程以下:

// 在 app 目錄下建一個 index.tpl.html 做爲鉤子
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
// 在 webpack.config.dev.js 和 webpack.config.prod.js 添加配置代碼,便可生成相對應的 index.html
plugins: [
  new HtmlWebpackPlugin({
    template: 'app/index.tpl.html',
    inject: 'body',
    filename: 'index.html'
  })
]

8 構建流程圖

最終實現的構建流程以下圖所示:

webpack-build-process

Configuration tasks

  • npm start: 啓動開發模式下的server

  • npm run start:prod: 啓動生產模式的server

  • npm run build: 打包生產模式的代碼

  • npm run lint: eslint 代碼檢查

  • npm run lint:watch: eslint 監視

  • npm run remove:build: 刪除dist目錄

  • npm run clean:build : 清除dist目錄


9. 文件說明

  • .babelrc: 配置 es2015,react 解析器

  • .eslintrc: 配置 eslint 代碼檢查

  • server.js: 配置本地 server (包含 dev server 和 prod server )

  • webpack.config.dev.js: 開發模式相關配置

  • webpack.config.prod.js: 生產模式相關配置


10. 參考

相關文章
相關標籤/搜索