TCM的webpack配置與經常使用插件

0 前言

本文是針對TCM項目所作的WebPack配置文件總結,主要概述了一些經常使用配置選項和插件使用,對之後的項目有指導意義。
TCM的webpack配置文件包括webapck.config.base.js、webapck.config.dev.js、webapck.config.prod.js三個基本文件, webpack.config.base.js是基本配置文件,webpack.config.dev.js是開發配置,webpack.config.prod.js是產品配置文件,webpack.config.base.js包含一些webpack.config.prod.js和webpack.config.base.js共有的基本配置,而webpack.config.prod.js和webpack.config.base.js在webpack.config.base.js的基礎上添加了一些必要配置。爲了引入Node的express API,經過dev.js和prod.js對頂層配置進行定義,所以,package.json文件的scripts部分定義了採用不一樣配置進行開發的npm指令:
圖片描述css

如下較多內容是對《入門Webpack,看這篇就夠了》作的總結,加入不少網上收集的資料,目的是爲了更深的瞭解TCM中的WebPack配置。html

1 爲何用webpack?

Node.js的發展使各類依賴普遍涌現,這些依賴包含各類插件、加載器,能夠簡化開發流程。模塊化是前端發展的一大趨勢,基於React的單頁應用完美詮釋了模塊化的概念,經過組件的方式進行開發,組件之間互相引用,而且引用外部依賴。爲了打包外部依賴以及本地JavaScript模塊、SCSS模塊、圖片等,打包工具應運而生,以WebPack最爲著名,相似的還有Gulp/Grunt等。webpack的優勢之一就是把全部文件,包括CSS、HTML、圖片、JavaScript代碼等都視爲模塊處理,只要配置中包含相應的loader就能夠進行處理打包。前端

1.1 WebPack和Grunt以及Gulp相比有什麼特性?

其實Webpack和另外兩個並無太多的可比性,Gulp/Grunt是一種可以優化前端的開發流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優勢使得Webpack能夠替代Gulp/Grunt類的工具。
Grunt和Gulp的工做方式是:在一個配置文件中,指明對某些文件進行相似編譯,組合,壓縮等任務的具體步驟,這個工具以後能夠自動替你完成這些任務。
圖片描述node

Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個瀏覽器可識別的JavaScript文件。
圖片描述react

2 webpack配置文件經常使用配置項

webpack有一個默認的配置文件webpack.config.js(官方文檔),位於項目根目錄,也能夠根據須要建立多個配置文件,TCMngr配置了三個文件:webpack.base.conf.js/webpack.dev.config.js/webpack.prod.conf.js。在package.json的scripts中添加不一樣的命令設置不一樣的配置文件,在TCMngr的package.json中有jquery

"scripts": {
    "start": "cross-env NODE_ENV=development node build/dev.js",
    "build": "cross-env NODE_ENV=production node build/prod.js"
  },

能夠看到此處使用了cross-env依賴包,這個包容許以UNIX的方式設置環境變量,並在windows上正常運行。安裝命令:webpack

npm install cross-env --save-dev

webpack配置文件本質就是一個JavaScript module,可使用JavaScript語言,文件會導出一個配置對象,格式以下:git

mudule.exports = {};

全部的配置信息都在這個對象中體現,包括:
entry:打包的入口文件,可使一個字符串或一個對象,若是隻有一個須要打包的模塊,使用這種形式;若是是一個對象,對象對應的全部文件都被打包,該對象能夠是包含多個打包模塊的數組,依賴較強的排在前面,也能夠是鍵值對,分別對應不一樣的輸出包,包名就是鍵名;TCM的webpack.base.conf.js指出了須要打包的文件,包含框架、類庫以及入口源碼。
圖片描述github

resolve:影響模塊解析的設置,是一個對象,包含如下屬性。web

resolve.extensions:自動識別的文件擴展名,若是你想請求一個js文件可是在請求時不帶擴展        
(如:require('index')),那麼就須要將'.js'添加到數組中。並非必須配置這一選項,不配
置時會使用默認值["", ".webpack.js", ".web.js", ".js"],手動設置會致使默認值被覆
蓋。若是想要每一個模塊都能按照本身的擴展名解析,要加上空字符串。
resolve.modulesDirectories:目錄名組成的數組,會在該目錄以及該目錄的頂層目錄尋找依賴
模塊,默認值是Default: ["web_modules", "node_modules"]。
resolve.root:包含依賴模塊的絕對路徑,多是目錄數組

圖片描述

resolveLoader:設置和resolve設置相似,只不過是針對loaders設置。
圖片描述

output:打包的輸出結果,是一個對象,包含如下屬性:

filename:輸出文件名,filename裏面的[name]會由entry中的鍵替換;
path:輸出路徑;
publicpath:經過瀏覽器訪問時的公共URL地址。

圖片描述

module:定義對模塊的處理邏輯,是一個對象;
loaders:定義一系列自動加載的loader,是一個對象數組;

[
        {
            test:正則表達式,用於匹配處理的文件
            loader/loaders:字符串或數組,表示用到的加載器,loader:string表示用!分隔的loader,loaders:[]表示用到的加載器數組。
            include:包含的文件夾
            exclude:排除的文件夾
        }
    ]

plugins:定義插件,一個數組,定義全部用到的插件。
圖片描述

externals:當咱們想在項目中require一些其餘的類庫或者API,而又不想讓這些類庫的源碼被打包時,這在實際開發中頗有必要。此時咱們就能夠經過配置externals參數來解決這個問題:
圖片描述

這樣咱們就能夠放心的在項目中使用這些API了:var jQuery = require(「jquery」);

devtool:選擇調試工具,經常使用eval-source-map

//實例
{
    devtool: "#inline-source-map"
}

3 插件(Plugins)和一些工具包

插件(Plugins)是用來拓展Webpack功能的,它們會在整個構建過程當中生效,執行相關的任務。Loaders和Plugins經常被弄混,可是他們實際上是徹底不一樣的東西,能夠這麼來講,loaders是在打包構建過程當中用來處理源文件的(JSX,Scss,Less..),一次處理一個,插件並不直接操做單個文件,它直接對整個構建過程其做用。要使用某個插件,咱們須要經過npm安裝它,而後要作的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例(plugins是一個數組)。

3.1 webpack-dev-server

通常安裝在devDependency中:
npm install webpack-dev-server --save-dev
安裝後使用webpack-dev-server便可在瀏覽器窗口觀察輸出,瀏覽器會自動打開項目根目錄的index.html文件,默認端口號是8080,完整地址是http://localhost:8080/。使用命令webpack-dev-server --hot --inline完成自動刷新,爲了簡寫命令,在package.json的scripts中添加以下語句:

「build」 : 「webpack-dev-server --hot --inline --config ‘webpack-dev-config.js’」

--config設置默認的webpack配置文件。
devserver做爲webpack配置選項中的一項,具備如下配置選項
圖片描述

在webpack.config.js中體現爲:

devServer: {
    contentBase: "./public",//本地服務器所加載的頁面所在的目錄
    colors: true,//終端中輸出結果爲彩色
    historyApiFallback: true,//不跳轉
    inline: true//實時刷新
  }

3.2 Source Maps(使調試更容易)

WebPack生成source maps,能夠對應編譯文件和源文件,使得編譯後的代碼可讀性更高,更容易調試。配置source maps,須要配置devtool,它有如下四種不一樣的配置選項,各具優缺點,描述以下:
圖片描述

上述選項由上到下打包速度愈來愈快,不過同時也具備愈來愈多的負面做用,較快的構建速度的後果就是對打包後的文件的的執行有必定影響。

在學習階段以及在小到中性的項目上,eval-source-map是一個很好的選項,不過記得只在開發階段使用它,以下配置

module.exports = {
  devtool: 'eval-source-map',//配置生成Source Maps,選擇合適的選項
  entry:  __dirname + "/app/main.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  }
}

3.3 Babel:編譯ES6和JSX

Babel工具包括babel-core/babel-loader/babel-preset-es2015/babel-preset-react,若是使用命令行還要安裝babel-cli。
Babel的配置較爲複雜,反映在webpack.config.js與.babelrc中,webpack.config.js會自動調用.babelrc中的配置選項。webpack.config.json會包含如下配置

//webpack.config.js
{
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      }

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

3.4 CSS-loader

webpack提供兩個工具處理樣式表,css-loader 和 style-loader,兩者處理的任務不一樣,css-loader使你可以使用相似@import 和 url(...)的方法實現 require()的功能,style-loader將全部的計算後的樣式加入頁面中,兩者組合在一塊兒使你可以把樣式表嵌入webpack打包後的JS文件中。
Sass 和 Less之類的預處理器是對原生CSS的拓展,它們容許你使用相似於variables, nesting, mixins, inheritance等不存在於CSS中的特性來寫CSS,CSS預處理器能夠這些特殊類型的語句轉化爲瀏覽器可識別的CSS語句,在webpack裏使用相關loaders進行配置就可使用了,經常使用的CSS 處理loaders包括Less Loader、Sass Loader、Stylus Loader。

// TCM中開發環境下直接內嵌 CSS 以支持熱替換
// autoprefixer自動添加前綴的插件
config.module.loaders.push({
  test: /\.css$/,
  loader: 'style!css!autoprefixer'
}, {
  test: /\.less$/,
  loader: 'style!css!less!autoprefixer'
}, {
  test: /\.scss$/,
  loader: 'style!css!sass!autoprefixer'
});

3.5 瀏覽器實時同步插件

var   BrowserSyncPlugin = require('browser-sync-webpack-plugin');
config.plugins.push(
  new BrowserSyncPlugin({
    host: '127.0.0.1',
    port: 9090,// 瀏覽器監聽地址
    proxy: 'http://127.0.0.1:9000/',
    logConnections: false,
    notify: false
  }, {
    reload: false
  })
);

3.6 webpack的進度條插件

使用該插件須要在webpack配置中增長如下聲明:

var NyanProgressPlugin = require('nyan-progress-webpack-plugin');
plugins: [
  new NyanProgressPlugin()  
]

效果以下:
圖片描述

3.7 HtmlWebpackPlugin:自動生成HTML插件

這個插件的做用是依據一個簡單的模板,幫你生成最終的Html5文件,這個文件中自動引用了你打包後的JS文件。每次編譯都在文件名中插入一個不一樣的哈希值。

//安裝
npm install --save-dev html-webpack-plugin
//webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
config.plugins.push(
new HtmlWebpackPlugin({
    filename: 'index.html',
    template: config.commonPath.indexHTML, //載入文件
    chunksSortMode: 'auto'
  })
);

該插件的設置參數不少:
title: 設置title的名字
filename: 設置這個html的文件名
template:要使用的模塊的路徑
inject: 把模板注入到哪一個標籤後 'body',
favicon: 給html添加一個favicon './images/favico.ico',
minify:是否壓縮 {...} | false
hash:是否hash化 true false ,
cache:是否緩存,
showErrors:是否顯示錯誤,
chunks:目前沒太明白
xhtml:是否自動畢業標籤 默認false

3.8 Hot Module Replacement

Hot Module Replacement(HMR)也是webpack裏頗有用的一個插件,它容許你在修改組件代碼後,自動刷新實時預覽修改後的效果。在webpack中實現HMR也很簡單,只須要作兩項配置:在webpack配置文件中添加HMR插件;在Webpack Dev Server中添加「hot」參數。不過配置完這些後,JS模塊其實仍是不能自動熱加載的,還須要在你的JS模塊中執行一個Webpack提供的API才能實現熱加載,雖然這個API不難使用,可是若是是React模塊,使用咱們已經熟悉的Babel能夠更方便的實現功能熱加載。Babel有一個叫作react-transform-hrm的插件,能夠在不對React模塊進行額外的配置的前提下讓HMR正常工做。

//webpack中的配置
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
config.plugins.push(
plugins: [
    new webpack.HotModuleReplacementPlugin()//熱加載插件
  ]
);

//安裝react-transform-hmr
npm install --save-dev babel-plugin-react-transform react-transform-hmr
//Babel中的配置
{
  "presets": ["react", "es2015"],
  "env": {
    "development": {
    "plugins": [["react-transform", {
       "transforms": [{
         "transform": "react-transform-hmr",
         "imports": ["react"],
         "locals": ["module"]
       }]
     }]]
    }
  }
}

3.9 優化插件

OccurenceOrderPlugin :爲組件分配ID,經過這個插件webpack能夠分析和優先考慮使用最多的模塊,併爲它們分配最小的IDUglifyJsPlugin:壓縮JS代碼;ExtractTextPlugin:分離CSS和JS文件

相關文章
相關標籤/搜索