Webpack多入口文件、熱更新等體驗

Webpack現今流行的前端打包工具,今兒本人也來分享下本身學習體驗。css

1、html-webpack-plugin

實現html模板文件的解析與生成html

  • 在plugins加入HtmlWebpackPlugin的配置,若是是多個入口文件,則須要對應加入多個HtmlWebpackPlugin功能。
var HtmlWebpackPlugin = require('html-webpack-plugin');
entry:{
    ma: './src/ma', /** .:必需要,表示運行時的根目錄,不然找不到文件,且不報錯 */
    mb: './src/mb'
},
output: {
    path: './dist',
    filename: '[name].js'
},
plugins: [
    new HtmlWebpackPlugin({ //能夠模板,直接引用files對象,是webpack中state對象
        title: '模板A',
        chunks: ['ma']
    }),
    new HtmlWebpackPlugin({
        filename: 'mb.html',
        title: '模板B',
        chunks: ['mb']
    })
]

如上代碼所示:前端

  • 兩個入口文件,ma與mb,因此配置了兩個HtmlWebpackPlugin實例
  • HtmlWebpackPlugin實例配置項:
    • title:模板title
    • filename:輸出的html文件名稱
    • chunks:包含的文件,能夠entry和其餘模塊chunk的模塊,插件導入到 模板時 沒有排序,但都是。
    • excludeChunks:被排除的模塊
    • chunksSortMode:添加到頁面時模塊的排序 none|default|function
    • template:模板文件路徑所在位置
    • templateContent:一個函數,使用編程語言建立模板
    • inject:js插入位置:body, head
    • 模板能夠訪問的配置項
      • files:爲webpack的stats項,能夠在模板文件中使用或者
      • webpackConfig:webpackConfig的配置項
      • options:在模板文件中能夠獲取的webpack配置項。
  • HtmlWebpackPlugin的事件使用:
事件名稱 時機 同步/異步
html-webapck-plugin-before-html-generation 生成htmlPluginData以前觸發 async
html-webpack-plugin-before-html-processing htmlPluginData插入到html模板以前觸發 async
html-webpack-plugin-alert-asset-tags 驗證資源,以及爲資源作標記時觸發 async
html-webpack-plugin-after-html-processing htmlPluginData插入到html模板以後觸發 async
html-webpack-plugin-after-emit 生成html目標文件後觸發 async
html-webpack-plugin-alert-chunks 驗證資源塊信息 sync
var compile = webpack(config);
compile.plugin('compilation', function( compilation, callbak) {
    console.log('compilation');
    compilation.plugin('html-webpack-plugin-before-html-processing', function (htmlPluginData, callbak) {
        console.log(htmlPluginData)
        callbak()
    })
})

注意:node

  • 必需要監測compile的compilation事件
  • 而後在回調compilation事件時,對compilation參數進行plugin的事件的註冊 。

2、webpack.optimize.CommonsChunkPlugin

抽取公共模塊爲一個獨立的文件,一是指定的多個模塊打成一個包;二是在指定的chunks中抽取公共模塊jquery

參數名稱 說明
name 能夠是字符串,或者是數組,若是指定爲entry中一個名稱,則只產生此vendor,也能夠是一個入口文件列表
filename 輸出文件名
minChunks 單獨文件最小引用數,如設置3,表示同一個模塊只有被3個之外的頁面引用時纔打包
children 返回,把第三方的vendor包,分解到業務包中
chunks 數組,從指定的源模塊提供共用vendor包

1. vendor打成一個包:webpack

entry:{
        vendor: ['./src/vendor-jquery', 'bootstrap']
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor'
        })
    ]

2. CommonsChunkPlugin正確的引入方式css3

3. 用manifest實現js庫的增量更新web

若是輸出文件名包含hash值,須要引入如下兩個插件:編程

  • HashedModuleIdsPlugin:算hash值
  • 利用CommonsChunkPlugin配置,他是manifest配置模塊全部的依賴抽象,若是mainfest不更新,則html會找不到js文件。
new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  chunks: ['vendor']
})

3、webpack 樣式打包

這其中就包含對css文件、靜態資源以及css所包含的資源文件等處理。bootstrap

  • css-loader:解析css代碼
  • style-loader:css代碼寫入到js文件中
  • 配置代碼以下:
loaders:[
    {
        test:/\.css$/, /*不能加引號*/
        loader: 'style-loader!css-loader'
    }
]

注意:test後面不能加引號,因這個是正則式

1. 樣式文件單獨存在,但不能處理靜態資源

extract-text-webpack-plugin:抽取樣式爲單獨的文件

  • 參數配置說明
  • ExtractTextPlugin.extract(arg1,arg2,arg3)
    • arg1: 可選參數,傳入一個loader,當css沒有被抽取的時候可使用該loader
    • arg2:必填參數,用於編譯解析css文件的loader
    • arg3:額外選,暫只可傳publicPath,表示當前loader的路徑
  • ExtactTextPlugin在Plugins中構造時,至少須要傳入一個文件名參數

filename文件名,能夠指定一個固定的,也可用[name].[id].[contenthash]來指定文件名,[name]:與entry中的chunk名稱一致,[id]:將entry的chunk的id一致;[contenthash]:根據內容生成hash值

參數名稱 說明
id 可先參數,插件實例的唯一標識,缺省會自動生成

filename

文件名,能夠指定一個固定的,也可用[name].[id].[contenthash]來指定文件名,[name]:與entry中的chunk名稱一致,[id]:將entry的chunk的id一致;[contenthash]:根據內容生成hash值
options allchunks:是否將全部額外的chunk都壓縮一個文件;disable:禁止使用此插件

代碼以下(webpack2.x):

var ExtractTextPlugin = require('extract-text-webpack-plugin');
module:{
    loaders:[
        {
            test:/\.css$/,
            loader: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: 'css-loader'
            })
        }
    ]
},
plugins: [
    new ExtractTextPlugin('[name].css')
]

2. file-loader實現css中圖片或web字體文件打包

var ExtractTextPlugin = require('extract-text-webpack-plugin');
module:{
    loaders:[ 
        {
            test:/\.css$/,
            loader: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: ['css-loader','postcss-loader']
            })
        },
        {
            test: /\.(eot|svg|ttf|woff|woff2)$/,
            loader: 'file-loader?name=fonts/[name].[ext]'
        }
    ]       
}

參數說明:

參數名稱 說明
name 配置輸出文件名,例如:name=[name].[hash].[ext]
name子節點配置說明
[ext] 擴展名
[name] 文件名
[path] 相對於上下文的路徑
[hash] hash值
輸出配置參數
publicPath 公共資源路徑(也能夠說是靜態資源,就是不參與打包的編譯過程的資源)
outputPath 輸出資源路徑(也能夠說是靜態資源,就是不參與打包的編譯過程的資源)

publicPath和outputPath使用示例代碼:

use: "file-loader?name=[name].[ext]&publicPath=assets/foo/&outputPath=app/images/"

3. postcss實現瀏覽器兼容

代碼以下(webpack2.x):

var autoprefixer = require('autoprefixer');
module:{
    loaders:[
        {
            test:/\.css$/,
            loader: ExtractTextPlugin.extract({
                use: ['css-loader','postcss-loader']
            })
        }
    ]       
},
plugins: [
    new webpack.LoaderOptionsPlugin({
        options:{
            postcss:[autoprefixer()]  
        }
    })
]
  • webpack2.x不支持自定義配置節點,須要用webpack.LoaderOptionsPlugin加入自定義的插件配置節點。
  • autoprefixer:一個postcss的插件,用於css3的兼容前端處理
    • browsers:配置瀏覽器的版本,如:browsers:['last 2 versions']

4、熱更新

  • 安裝 webpack-dev-server
  • 熱更新的概念

利用websocket實現,websocket-server識別到html、css和js的改變,就向websocket-client發送一個消息,websocket-client判斷若是是html和css就操做dom,實現局部刷新,若是是js就總體刷新。

  • 配置:
var config = require('./webpack.base.conf');
var webpack = require("webpack");
var WebpackDevServer = require('webpack-dev-server');
var compile = webpack(config);
compile.plugin('compilation', function( compilation, callbak) {
    compilation.plugin('html-webpack-plugin-before-html-processing', function (htmlPluginData, callbak) {
        callbak()
    })
})
var isProc = true;
if(isProc){
    compile.run(function(err,state){
        console.log(err);
    })
}else{
    var server = new WebpackDevServer(compile,{
        contentBase: './build',
        hot: true,
        inline: true, /*無效*/
        historyApiFallback: true
    });
    server.listen(8080);
}

說明:

  • hot:啓動熱更新
  • inline:是不會自動刷新網頁的,由於此參數只能在cli環境下用
  • 在cli下實現頁面自動刷新
webapck-dev-server --hot --inline --config=配置文件

無--inline時,只能在iframe模式下自動刷新:http://localhost:8080/webpack-dev-server/index.html
有--inline時,能夠直接訪問http://localhost:8080/index.html進行自動刷新

5、cross-env

實現環境變量的定義

"prod": "cross-env NODE_ENV=prod node ./build/dev-server.js",
"dev": "cross-env NODE_ENV=dev node ./build/dev-server.js"

6、示例代碼結構說明

前五節說了這麼多,也許讓你聽得雲裏霧裏的。沒有代碼來講明程序是多麼枯燥啊(聲明:此代碼還包含後一章節的單元測試和e2e測試的配置)。代碼結構圖以及源碼下載地址

  • build:打包配置文件
    • dev-server.js:打包運行入口
    • webpack.base.conf.js:打包plugins節點的配置
    • webpack.core.conf.js:打包module以及entry的基本配置
  • src:源碼目錄
  • test:測試目錄
    • e2e:點到點測試
    • unit:單元測試
    • mocks:mockjs模擬數據
相關文章
相關標籤/搜索