平常工做webpack必備姿式(二)

前言

在深刻看下面內容以前,但願你們閱讀了我上一篇文章平常工做webpack必備姿式(一),本篇宗旨是進一步探討webpack的平常使用,而不是入門教學。html

打包多頁應用

webpack一般是配合諸如VUE框架打包單頁面應用的,若是你想用他打包多頁面應用,那咱們如何實現這個騷操做呢?java

思路以下:node

  1. 打包頁面,動態在頁面中插入js必須依賴的插件是HtmlWebpackPlugin,同時指定動態插入頁面的js入口文件。
  2. 入口文件由一個入口變成多個,指定入口文件的方式也從字符串變成對象
  3. 出口文件從一個出口變成多個出口

基於上述思路咱們來看一下webpack配置文件的最終配置:webpack

let path =  require('path'); //webpack是node寫出來的,path是node的語法
let HtmlWebpackPlugin = require('html-webpack-plugin'); //HTML編譯插件

module.exports = {    

    mode:'development', //編譯環境改爲是development(開發模式)
    entry:{
        aaa:'./src/aaa.js',    //第一個入口文件
        bbb:'./src/bbb.js'    //第二個入口文件
    },

    output:{                    //編譯後的目錄
        filename:'[name].js',    //編譯後的文件名稱,name動態有入口js文件生成
        path:path.resolve(__dirname,'dist'),    //編譯後的路徑,必須是絕對路徑        
    },

    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html', //須要編譯的html源文件,一個足以,由於內容是入口js渲染而成
            filename:'aaa.html',    //編譯後的文件名        
            chunks:['aaa']        //入口js文件         
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html', //須要編譯的html源文件
            filename:'bbb.html',    //編譯後的文件名        
            chunks:['aaa','bbb']    //能夠指定多個入口js文件      
        }),
    ],    
    
}

在咱們的項目中新建入口文件aaa.js和bbb.js文件後進行測試。最終編譯的效果如圖所示:
企業微信截圖_20200315140957.pngweb

source-map的做用

在剛開始用webpack的時候有沒有遇到過代碼運行出錯,卻沒有辦法追尋到源碼出錯的點?這個時候source-map就發揮做用了。source-map意思是"源碼映射",顧名思義它的做用是就是能幫助咱們找到源碼出錯的地點。npm

//在webpack配置文件中添加這麼一行就起到做用了
devtool:'eval-cheap-source-map',

在實際項目使用中,通常開發環境會配置該選項,但部署的時候就得去掉。由於source-map文件比較大,嚴重影響網頁傳輸效率。和source-map相對應的eval-source-map相對於source-map而言並不會單獨產生一個source-map相關的文件,可是也能找到出錯點。其它的可配置項諸如cheap-source-map和eval-cheap-source-map則不多用到。json

webpack經常使用插件

  1. clean-webpack-plugin插件:每次編譯配置設置爲生成新的文件(避免緩存),而之前編譯後文件還須要手動刪除太麻煩了,有了它就能自動刪除以前編譯目錄的文件。
  2. copy-webpack-plugin插件:假如咱們有文檔但願每次更新後也能編譯到輸出目錄,幫咱們作一個拷貝,用這個就能夠。
  3. BannerPlugin是webpack內置功能:咱們看別人文章老是會加一個出處說明,用BannerPlugin能自動幫助咱們在每一個打包的文件開頭添加說明字符

首先安裝依賴包segmentfault

//BannerPlugin是webpack內置功能,不須要安裝
npm install --save-dev clean-webpack-plugin
npm install copy-webpack-plugin --save-dev

webpack配置文件(3個插件的相關配置)後端

let path =  require('path'); //webpack是node寫出來的,path是node的語法
let HtmlWebpackPlugin = require('html-webpack-plugin'); //HTML編譯插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
let webpack = require('webpack');


module.exports = {   
    mode:'development', //編譯環境改爲是development(開發模式)
    entry:'./src/index.js',    //須要編譯的源文件目錄
    output:{                //編譯後的目錄
        filename:'bundle.[hash].js',    //編譯後的文件名稱
        path:path.resolve(__dirname,'dist'),    //編譯後的路徑,必須是絕對路徑
    },
    devtool:'eval-cheap-source-map',
    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html', //須要編譯的html源文件
            filename:'index.html',         //編譯後的文件名            
        }),
        new CleanWebpackPlugin(),
        new CopyPlugin([
          { from: 'doc', to: '' }
        ]),
        new webpack.BannerPlugin('說明字符')
    ],   
}

最終運行效果:
企業微信截圖_20200315160918.pngapi

跨域解決方案

webpack能夠經過代理的方式解決跨域,僅須要配置以下:

//以'/api'的開頭的請求都會從新代理到新的域下
devServer: {
        proxy:{
            '/api':'http://***'
        }
    },
    
//假如後端路徑不帶有'/api',能夠經過pathRewrite將它更改(這裏是將它替換)
devServer: {
        proxy:{
            '/api':{
                target:'http://***',
                pathRewrite:{'/api':''}
            }
        }
    },

上述方案(包括網上的用webpack模擬後端數據等)只是在開發階段試用的跨域方案,部署到線上仍是須要後端來解決跨域問題的。以下列舉一下java語言的跨域解決方案:

public class CorsInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler) throws Exception {
        if (request.getHeader(HttpHeaders.ORIGIN) != null)
        {
            //跨域解決方案
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
            response.addHeader("Access-Control-Max-Age", "3600");
        }
       return true;
    }
}

定義環境變量和區分環境

webpack中的定義插件能夠幫咱們定義一些全局變量,用於區分當前環境是線上仍是線下,用法以下:

new webpack.DefinePlugin({
          'env': JSON.stringify('development')
        })
//錯誤的用法以下所示:
new webpack.DefinePlugin({
          'env': 'development'
        })
//在實際獲取變量env的地方直接使用env而無需引用;
//上述錯誤在於獲取env獲得的是變量development而不是字符串;
//將development改爲字符串也可正常運行(以下),只是感受很奇怪
new webpack.DefinePlugin({
          'env': "'development'"
        })

上述咱們雖然能夠定義一些環境變量,可是實際中想要區分線上環境和線下環境還須要藉助於webpack-merge

通常在實際開發中區分線上環境和開發環境的作法是定義三個文件:

  1. webpack.base.js 該文件的做用是定義線上和開發環境公共的配置項內容
  2. webpack.prod.js 該文件的做用是定義線上專屬的屬性好比:將mode定義爲'production',定義一些壓縮代碼的優化項之類的。
  3. webpack.dev.js 該文件的做用是定義開發環境的屬性好比,source-map屬性,devServer等等。

文件內容參考以下:

//webpack.base.js文件
let path =  require('path'); //webpack是node寫出來的,path是node的語法
let HtmlWebpackPlugin = require('html-webpack-plugin'); //HTML編譯插件
let webpack = require('webpack');


module.exports = { 
    entry:'./src/index.js',    //須要編譯的源文件目錄
    output:{                //編譯後的目錄
        filename:'bundle.[hash].js',    //編譯後的文件名稱
        path:path.resolve(__dirname,'dist'),    //編譯後的路徑,必須是絕對路徑
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html', //須要編譯的html源文件
            filename:'index.html',         //編譯後的文件名            
        }),
       new webpack.DefinePlugin({
          'env': "'development'"
        })
    ],   
}

//webpack.prod.js文件
var base = require('./webpack.base.js');
var merge = require('webpack-merge');
module.exports = merge(base,{     
    mode:'production'
    //其它優化項
})

//webpack.dev.js文件
var base = require('./webpack.base.js');
var merge = require('webpack-merge');
module.exports = merge(base,{     
    mode:'development', 
    //其它開發配置項內容
})

在package.json文件中經過調用不一樣的配置文件來區分線上和開發環境。

scripts: {
    "build": "webpack --config webpack.prod.js",
    "dev": "webpack --config webpack.dev.js"
  },

webpack自帶優化

webpack在開發環境下會自動幫助咱們作不少代碼優化,須要注意的是必定是production環境才能看到優化效果。咱們來看下如下兩個例子:

tree-shaking

tree-shaking意思是樹木只要一搖晃,無用的或者枯黃的葉子就會離開,也就暗示咱們代碼中無效的代碼就會自動被優化掉。來看一下案例:

//在一個文件裏建立如下兩個函數
//bb.js
let sum = function(a,b){
    return a+b+" ssssssssss";  //ssssssssss是爲了在測試的時候搜索驗證效果
}

let minus = function(a,b){
    return a-b+"mmmmmmmm";  //同理mmmmmmmm是爲了在測試的時候搜索驗證效果
}

export default{
    sum,minus
}
//在另外一個文件中引用上面文件,而且在production環境打包
import calc from './bb.js'
console.log(calc.sum(12,23));

打包結果爲只有bb.js文件裏面的sum函數,卻沒有minus函數。緣由是由於咱們的代碼裏面只用到了sum函數,minus函數由於沒有用到就自動幫咱們去除了。

做用域提高

webpack他能自動作一些計算上的優化處理,例如如下案例:

let a=1;
let b=2;
let c=3;
console.log(a+b+c+"做用域提高") //"做用域提高"是爲了在測試的時候搜索驗證效果

通過編譯後最終的代碼效果是:

console.log("6做用域提高")

結束語

webpack經常使用的知識暫且介紹到這裏,後續將會根據webpack版本的更新,帶來續更!!

相關文章
相關標籤/搜索