從0到1教你學習並配置webpack

抓住2019年的尾巴,迎接2020年的到來~javascript

給本身的2019年畫上一個完美的句號。css

引言

webpack 對於如今的前端開發的你來講,不算陌生,你或許沒有真正去了解過它是如何使用的,但你的項目中確實使用過它,由於你項目的打包編譯都跟他息息相關~html

前陣子恰好在研究webpack以及其源碼相關的知識,若是你跟我同樣,好奇webpack又是怎麼工做的?那些奇奇怪怪的配置都是什麼東西?分別表明什麼意思?前端

那你不妨花幾分鐘閱讀一下,跟我一塊兒學習回顧一下如何從0到1去了解webpack的知識, 配置你項目須要的webpack~java

pass:本文以 webpack4 爲例~node

什麼是webpack?

什麼是 webpackwebpack

官方文檔 是這麼說:es6

webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundleweb

其實,它就是一個模塊化打包工具,它所作的事情就是分析你的項目結構,找到JavaScript模塊並對其進行代碼轉換(scss 轉換爲cssTypescript 轉換爲 Javscript),文件優化(壓縮JavaScriptCSSHTML、圖片等),模塊合併 (把模塊分類合併成一個文件)等一系列的操做,最終打包爲合適的格式在讓你的項目能夠在瀏覽器中運行~正則表達式

盜用官網的一張圖,其主要工做原理就以下圖所示~

核心概念

在真正上手 webpack 以前,咱們須要對其幾個 核心概念 有所瞭解

  • Entry:入口路徑,webpack執行構建的第一步的輸入文件。

  • Module:模塊,在 webpack 裏一切皆模塊,一個模塊對應着一個文件,webpack 會從配置的 Entry 開始遞歸找出全部依賴的模塊。

  • Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。

  • Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容,例如scsscss的轉換等,構建模塊的第一步就是使用loader來加載並處理模塊內容

  • Plugin:擴展插件,webpack 的重要組成部分,其 webpack 源碼的不少核心功能也都是插件實現的,因爲webpack提供了在不一樣的生命週期內提供了不少不一樣的hooks鉤子函數,插件的工做原理就是在 webpack 構建流程中的不一樣的(hooks)時機注入擴展邏輯來改變構建結果或作個性化操做。

  • Output:輸出結果,在 webpack 通過一系列處理後最終代碼後輸出配置。

整個流程串起來大概就是:

webpack啓動後會從Entry裏配置的Module開始遞歸解析 Entry 依賴的全部 Module。 每找到一個 Module,就會根據配置的Loader去找出對應的轉換規則,對 Module 進行轉換後,再解析出當前 Module 依賴的 Module

這些模塊會以 Entry 爲單位進行分組,一個 Entry 和其全部依賴的 Module 被分到一個組也就是一個Chunk。最後 webpack 會把全部 Chunk 轉換成文件輸出,在這整個流程中 webpack 會在不一樣的生命週期內執行配置的 Plugin 裏定義的邏輯。

瞭解了上面的一些概念和流程以後,接下來,咱們一步步來配置,打包咱們的項目~

初始化項目

建立文件夾

首先,咱們建立一個你喜歡的文件夾,並經過 npm init -y 來初始化項目配置,並在其目錄下建立一個咱們源代碼的目錄src和一個打包後的文件輸入目錄dist

建立入口文件 index.js

而後咱們在 src 目錄下建立一個 index.js 文件,做爲咱們的打包入口文件,並寫上咱們熟悉的 console.log('hello world'); 做爲打包內容。

安裝webpack

webpack4 以後將 webpackcli 分紅了兩個包,咱們須要經過 npm install webpack webpack-cli -D 安裝咱們所需的 webpack 依賴。

ok~ 準備就緒!

遺憾的是,你仍是不能直接進行打包,由於咱們的 webpack 是在項目下安裝的,因此不能直接運行,想要正確運行webpakc咱們能夠有下面2種方式:

  • 使用 npx 命令,能夠直接運行 node_modules/.bin 目錄下的命令
  • 經過配置 package.json 中的 scripts 腳本命令進行執行

爲了貼近咱們的項目,這裏咱們選擇第二種方式

配置package.json腳本

咱們打開package.json文件,並在 scripts 中配置下面的代碼:

"dev" : "webpack --mode development",
    "build" : "webpack --mode production",
複製代碼

dev 表示開發模式,build 是生產模式,不一樣在於 dev 會有不少方便咱們開發調試的功能,好比代碼不壓縮混淆,有開發服務器之類的,咱們學習階段採用 dev 便可~

建立配置文件

這時候,咱們已經能夠經過 npm run dev 命令打包咱們的代碼,並在dist目錄下看到咱們打包後的 main.js 文件了~

你可能很詫異的蹦出一句:

由於到此,你發現本身什麼都還沒配置,咋就能夠打包了!!

這是由於 webapck4 爲了簡化咱們開發人員繁瑣的配置工做,在內部寫好了一套配置,驚不驚喜,意不意外!!

那我這確定不能答應了,否則不就打我臉了麼!

要想加載本身的配置,咱們須要在咱們的項目根目錄下建立 webpack.config.js 文件,並建立咱們的基礎配置。

//path
const path = require('path');

//配置信息
module.exports = {
    //入口文件
    entry : './src/index.js' ,
    //出口文件
    output : {
    	//打包後路徑,只能寫絕對路徑
    	path : path.resolve(__dirname,'dist'),
    	//打包後文件名
    	filename : '[name].[hash].js'
    },
    //模塊轉換規則
    module : {
    
    },
    //插件
    plugins : [
    
    ],
    //開發服務器
    devServer : {
    
    }
}
複製代碼

咱們注意到 output 中的 filename 中有一個 [name][hash],其中nameentry 的名字,默認是 mainhash 是打包根據內容後計算出的一個 hash值,保證文件的惟一性,能夠經過[hash:8] 表示取其前8位。

如今運行 npm run devdist 目錄下就會打包出相似 main.47bfc309d4ba9b75d346.js 的文件。

這裏,咱們爲了方便,先將其改爲 main.js

建立index.html文件

爲了方便咱們在瀏覽器測試,咱們在咱們的 dist 目錄建立一個 index.html ,並引入咱們編譯好的main.js文件,以下:

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>webpack</title>
</head>
<body>
<div id="app">webpack</div>
<script src="main.js"></script>
</body>
</html>

複製代碼

咱們在 index.js 文件下加上這麼一句話:

document.querySelector('#app').style.color='red';

測試一下打包後的文件好很差使。

運行 npm run dev,打開咱們的 index.html 預覽,不出意外的話,結果應該和我同樣,頁面的 webpack 文字變紅,控制檯輸出 hello world

至此,咱們纔將咱們的項目基礎配置搞定~

加載css

若是咱們如今想加入 css 文件,優化個人樣式,首先在 src 目錄下建立 stylesheets 目錄,並添加 index.css 文件,咱們就先以 body { background : #f2f2f2; } 爲例,以後在 index.js 中經過 import './stylesheets/index.css' 的方式導入樣式文件。

若是如今咱們直接進行打包確定會報錯,由於 css 文件並非 js 模塊,webpack 在打包的時候無法直接處理,須要藉助轉換工具,這轉換工具就是 Loader

  • 什麼是 Loader

Loader 就是文件轉換器,經過使用不一樣的Loaderwebpack就能夠把不一樣的文件都轉成js文件,好比CSSES6/7JSX等,它一般有下面幾個配置項:

  • test:匹配處理文件的擴展名的正則表達式
  • useloader名稱,就是你要使用模塊的名稱
  • include/exclude:手動指定必須處理的文件夾或屏蔽不須要處理的文件夾
  • query:爲loaders提供額外的設置選項

接下來,咱們來使用 style-loadercss-loader 來處理咱們的 css 文件。

執行 npm install style-loader css-loader -D 進行安裝 loader

webpack.config.js 中的module下面添加解析規則:

module : {
    rules : [{
    	test : /\.css$/,
    	use : ['style-loader','css-loader']
    }]
},
複製代碼

一般來講,loader有下面三種書寫方式,上面是經過 use 方式,還有兩種方式分別是 直接使用 loader 和使用 use + loader

//直接使用loader

module: {
    rules: [{
        test: /\.css/,
        loader:['style-loader','css-loader']
    }]
}
複製代碼
//use + loader 的方式

module: {
    rules: [{
        test: /\.css/,
        include: path.resolve(__dirname,'src'),
        exclude: /node_modules/,
        use: [{
            loader: 'style-loader',
            options: {
                insert:'top'
            }
        },'css-loader']
    }]
}
複製代碼

要注意的是配置多個 loader有順序 的,webpack 會安裝配置的 loader 順序 從右向左 執行的,配置的時候要格外注意!

拿咱們上面的 style-loadercss-loader 來講,兩個loader配置的順序不可調換,由於 css-loader是解析處理css裏的url路徑,並將css文件轉換成一個模塊,style-loader是 將css文件變成style標籤插入到head中的。

如今咱們 npm run dev 試試,打包沒有報錯,預覽 index.html 也成功生效,很贊!

配置開發服務器

到此你有沒有發現,咱們在平時的開發過程當中,怎麼沒有遇到說讓我每次經過預覽dist下的 index.html來看咱們打包效果的,這是因爲咱們平時的開發中會在本身本地起一個服務器,來幫咱們作這件事。

如今,咱們也來試試~

  • 經過 npm i webpack-dev-server –D 安裝咱們的開發服務器依賴
  • 修改咱們的啓動腳本,將原來的 package.json 中的 dev 腳本修改成 webpack-dev-server --open ,其中 --open 是自動打開瀏覽器的意思

此時,直接運行 npm run dev 是看不到咱們預期的效果的,由於咱們尚未對咱們的服務器進行配置。

咱們在 webpack.config.jsdevServer 下添加以下配置:

devServer : {
    contentBase : path.resolve(__dirname,'dist'),
    host : 'localhost' ,
    port : 8000 ,
    compress : true
}
複製代碼
  • contentBase 配置開發服務運行時的文件根目錄,也就是靜態資源訪問地址
  • host 開發服務器監聽的主機地址
  • port 開發服務器監聽的端口,默認是 8080
  • compress 開發服務器是否啓動gzip等壓縮

ok,運行 npm run dev ,是否是效果很是棒!

要注意的是,webpack dev server 產生的打包文件是在 內存中!,是 內存中!,硬盤是訪問不到的,怎麼驗證這一點呢?

很簡單,你能夠刪除掉你dist目錄下的 main.js ,從新運行 npm run dev ,你能夠看到 dist 目錄下並無 main.js,但你訪問 localhost:8000 確實能正確訪問,而且訪問 http://localhost:8000/main.js 也能看到打包後的源碼,證實它產生的打包文件確實是在你的 內存中

注意,咱們這裏打包出來的只有一個 main.js 文件和一個index.css文件,index.html 文件是咱們手動添加進去的,不是打包產生的,若是刪掉 index.html 是沒法正確訪問頁面的,內存裏可沒有 index.html 文件。

咱們能夠在終端看到如下這些內容:

這些都是咱們在啓動開發服務器的時候 webpack 給咱們的頁面注入的 websocket 鏈接,你能夠在你的頁面調試器的 network 中的 ws 裏看到,

其重要做用就是,監控你文件的變化,能夠幫助你從新刷新頁面,讓你看到更改後的效果,你能夠修改一下 index.js 文件試試~

自動生產HTML文件

咱們以前是在 dist 目錄下寫好了 index.html 文件,並在裏面經過 script 標籤引入咱們打包後的內容,即 main.js ~

還記得咱們以前打包後的 filename 中能夠加入一個 hash 值也區別不一樣的文件,若是 hash 值發生變化了,咱們的 index.html 豈不是找不到資源了?因此咱們但願自動能產出HTML文件,並在裏面引入產出後的資源,這樣就沒必要爲上面的問題擔憂了。

咱們刪除掉 dist 目錄下的 index.html 文件,並在 src 目錄下建立一個 index.html 文件,咱們稱它爲模板,以它爲模板產生 html 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>webpack</title>
</head>
<body>
    <div id="app">webpack</div>
</body>
</html>
複製代碼

這時,咱們須要接觸到第一個插件 html-webpack-plugin!

以前也說了,插件在 webpack 中有很重要的做用,在 webpack 的構建流程中,plugin 用於處理更多其餘的一些構建任務,模塊代碼轉換的工做由 loader 來處理,除此以外的其餘任何工做均可以交由 plugin 來完成。

  • 首先咱們須要經過 npm install html-webpack-plugin -D 去安裝它。
  • 而後在 webpack.config.jsplugins 下去配置它(須要先經過 require 引入)
//自動產出HTML模版
new HtmlWebpackPlugin({
    template: './src/index.html',
    filename: 'index.html',
    hash: true,
    minify: {
    	removeAttributeQuotes: true,
    	removeComments: true 
    }
})
複製代碼

其中 template 是指定模板文件,filename 是指定產出後的文件名,hash 是爲了不緩存,能夠在產出的資源後面添加hash值,minify 是 壓縮相關的配置,minify.removeAttributeQuotes 是爲了去掉屬性的雙引號,minify.removeComments 是爲了壓縮文件,刪除模板中的註釋。

此時,咱們運行 npm run dev 訪問 localhost:8000 發現已經能夠正常訪問了,可是 dist 目錄下卻沒有任何東西,由於咱們以前提到了,開發服務器打包的文件是寫入內存中的,不是硬盤裏。

爲了方便咱們看效果,咱們在 package.json 中的 scripts 中在增長一行 "dev-build": "webpack --mode development" 用來打包咱們開發環境的代碼。

運行 npm run dev-build 腳本,完成以後能夠發現 dist 目錄已經打包出來了 index.html 文件 和 main.[hash].js 文件,打開 index.html 文件能夠發現標籤的雙引號已經沒去掉了,而且引入的腳本也自動加上了 ?[hash] 值。

<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=UTF-8>
    <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
    <title>Title</title>
</head>
<body>
    <div id=app>webpack</div>
<script type=text/javascript src=main.e6570abab6c2814d1608.js?e6570abab6c2814d1608></script></body>
</html>
複製代碼

預覽 index.html 文件,一切也都正常。

passwebpack4之後,若是你看到終端輸入有下面這麼怪異的一行,

而正巧你又是一個 強迫症患者,在 webpack.config.js 中添加 stats: { children: false } 便可。

支持圖片

前端項目中確定少不了圖片資源,若是咱們直接在 css 或者 js 文件中引入圖片資源去打包,那麼確定是通不過了,由於 webpack 沒法識別圖片資源,由於圖片也不是一個有效的模塊。

此時,咱們須要引入這個兩個 loader 去解決它, file-loader url-loaderfile-loader 解決CSS等文件中的引入圖片路徑問題,url-loader 當圖片小於limit的時候會把圖片base64編碼,大於limit參數的時候仍是使用file-loader 進行拷貝

  • 經過 npm install file-loader url-loader -D 下載依賴
  • src目錄下建立一個 images 文件夾,存放幾張你喜歡的圖片
  • index.jsindex.css 中引入圖片,並將其插入到頁面中去(我這裏以本地的 avatar.jpgscene.jpg 爲例)
//index.js
import Avatar from './images/avatar.jpg'

let img = new Image();

img.src = Avatar;

document.body.appendChild(img);
複製代碼
//index.css

body{
    background-color: #f2f2f2;
    background-image: url("../images/scene.jpg");
    background-repeat: no-repeat;
}
複製代碼
  • webpack.config.js中的module下面添加以下配置
{
    test:/\.(png|jpg|gif|svg|bmp)$/,
    use:{
    	loader: 'url-loader',
    	options: {
            limit: 10 * 1024,
            outputPath: 'images/'
    	}
    }
}
複製代碼

options 中的 limit 就是圖片的限制,這裏我指定的是 10kb ,小於 10kb 的圖片會以 base64 編碼輸出,outputPath 指定了拷貝文件輸出目錄,默認是dist目錄下。

如今咱們 npm run dev-build 走一波~

也不報錯,運行 index.html 文件,也很正常!

編譯less 和 sass

如今開發過程當中,爲了簡化咱們書寫 css 的過程,咱們通常項目中引入了 lesssass 這樣的預加載器~

一樣的你不處理以前 webpack 是不認識 lesssass 文件的,畢竟它不是一個 js 模塊,咱們經過須要藉助 less-loadersass-loader 來處理這些文件~

  • 經過運行 npm install less less-loader -D npm install node-sass sass-loader -D 分別安裝 loader
  • webpack.config.js中添加loader解析規則
{
    test: /\.less/,
    use: ['style-loader', 'css-loader', 'less-loader']
}, {
    test: /\.scss/,
    use: ['style-loader', 'css-loader', 'sass-loader']
}
複製代碼

這樣,你就能夠放心在你的項目裏引入 css 預處理了~

分離css

由於CSS的下載和js能夠並行,當一個HTML文件很大的時候,那麼頁面加載確定會很是慢,那麼咱們但願能夠把CSS單獨提取出來加載,爲每一個包含 CSSJS 文件建立一個 CSS 文件,按需加載。

咱們須要 mini-css-extract-plugin 這麼一個插件

  • 經過 npm install mini-css-extract-plugin -D 安裝模塊依賴
  • webpack.config.jsplugins 下去配置一下
new MiniCssExtractPlugin({
    filename: 'css/[name].[hash].css',
    chunkFilename: "css/[id].css"
})
複製代碼

除此以外,咱們的還須要作一個操做就是將咱們以前處理cssstyle-loader 改寫成下面這種形式:

{
    test: /\.css$/,
    use: [{
    	loader: MiniCssExtractPlugin.loader
    }, 'css-loader']
},{
    test: /\.less/,
    use: [{
    	loader: MiniCssExtractPlugin.loader
    }, 'css-loader', 'less-loader']
}, {
    test: /\.scss/,
    use: [{
    	loader: MiniCssExtractPlugin.loader
    }, 'css-loader', 'sass-loader']
}
複製代碼

趁熱打鐵,趕忙來試試,npm run dev-build 進行打包~

預覽 index.html 頁面,打開控制檯network能夠發現下載文件的時候多出了一個 main.css 文件,而且咱們 htmlhead 頭,已經換成了 link 方式,而且你的 dist 目錄下會多出一個 css 的文件夾,裏面存放打包後的 css 文件。

tips: 若是你在外部的css 文件中文件中引入圖片,而圖片放在了images目錄下,那麼打包上線後的圖片會出現 404 的狀況,你能夠查看打包後的 css 文件,就能夠反向是路徑的問題,須要配置一下 publicPath 便可~

{
    loader: MiniCssExtractPlugin.loader,
    options: {
        publicPath: '/'
    }
}
複製代碼

注意,這個通常是在 服務器 上會出現,本地打包後沒有起服務也是看不到的。

處理CSS3屬性前綴

咱們在書寫 css 的時候,爲了瀏覽器的兼容性,有時候咱們必須加入-webkit-ms-o-moz這些瀏覽器前綴,但咱們又不想去書寫這些繁瑣的東西,這時候能夠交給咱們 postcss 來處理~

postcss的主要功能只有兩個:

  • 第一個就是前面提到的把 CSS 解析成 JavaScript 能夠操做的 抽象語法樹結構(Abstract Syntax Tree,AST)
  • 第二個就是調用插件來處理 AST 並獲得結果

咱們首先經過 npm install postcss-loader autoprefixer -D 來安裝依賴

想要這個 postcss 正常工做,咱們須要配置兩個東西

  • 在根目錄下建立 postcss.config.js 配置文件,表示使用 autoprefixer 來進行補全
module.exports={
    plugins:[require('autoprefixer')]
}
複製代碼
  • webpack.config.js 中修改並添加對css處理的 loader
{
    test: /\.css$/,
    use: [{
    	loader: MiniCssExtractPlugin.loader
    }, 'css-loader', 'postcss-loader'],
    include: path.join(__dirname, './src'),
    exclude: /node_modules/
}
複製代碼

這裏我在個人 index.css 中添加了以下測試代碼:

//index.css
::placeholder {
    color: orange;
}
複製代碼

並在個人 index.js 中建立了一個 input 控件:

//index.js

let input = document.createElement('input');
document.body.appendChild(input);
複製代碼

運行 npm run dev-build 打包,預覽 index.html ,打開調試工具的的 sources板塊,查看 main.css , 發現對應的前綴已添加,而且我頁面的 input 已經變成了 orange~

轉義ES6/ES7

雖然 es6es7 的代碼咱們已經或多或少都在項目中,可是大部分瀏覽器對於 es6es7 代碼的支持度並不高,很大部分的瀏覽器仍是隻能解析 es5 的代碼,爲了讓咱們能正常使用 es6es7的代碼,咱們須要藉助 webpack 對其進行轉義,轉成 es5 代碼。

咱們須要藉助 babel 這個工具,它是一個編譯JavaScript的平臺,能夠把ES6/ES7的代碼轉義爲ES5代碼。

  • 經過 npm install babel-loader @babel/core @babel/preset-env -D 安裝依賴
  • webpack.config.js 中添加 babel-loader ,由於 babel-loader只是告訴了 webpack 怎麼處理 ES6ES7 代碼,但它並不會將 ES6ES7 代碼翻譯成向後兼容版本的代碼,所以須要指定一個 preset,它包含了代碼轉換的規則
{
    test: /\.js$/,
    loader : 'babel-loader' ,
    exclude:'/node_modules/'
}
複製代碼
  • 在咱們的項目根目錄建立一個 .babelrc 的文件來配置,用來配置咱們的 babel 相關
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [
            "> 1%",
            "last 2 versions"
          ]
        },
        "debug":true //調試使用
      }
    ]
  ]
}
複製代碼
  • 咱們在 index.js 文件中添加如下代碼測試一下,並打包測試一下:
const test = (n)=> {
    return new Promise(function (resolve) {
    	setTimeout(()=>{
    		resolve([1,2,3,4].map(v=>v * v ))
    	},n*1000)
    }).then(res=>{
    	console.log(res);
    })
}

console.log(test)
複製代碼

查看打包後的文件,發現轉換的不夠完全,只能針對語法進行了轉換,對於 Promisemap 這些高級用法並無被轉換,這確定是不行的,咱們還要想辦法把這些新的特性,兼容到低版本的瀏覽器裏。

咱們還須要 babel 提供的另外一個工具—— polyfill

  • npm install @babel/polyfill -D 安裝它
  • 在咱們的入口文件 index.js 最頂部添加 import '@babel/polyfill'
  • 運行 npm run dev-build 編譯打包,雖然控制檯好想沒啥變化,可是咱們的打包的文件 main.js 發生了很大變化,很明顯的一點,體積大了好幾十倍

這是因爲爲了兼容低版本瀏覽器,polyfill 裏面添加了不少輔助代碼來幫助實現好比 Promisemap 這些新特性,默認狀況下會被添加到每個須要它的文件中,而且會全局注入,形成全局污染,若是咱們在開發框架之類的,可能會發生衝突。

咱們加了 debug 能夠在終端看到,確實是加入了很多插件:

爲了解決這個問題,咱們引入 @babel/runtime 這個模塊,來避免重複導入的問題 若是是寫第三方庫或者框架

  • 運行 npm install @babel/runtime @babel/plugin-transform-runtime -D安裝模塊依賴
  • 配置@babel/runtime,並修改一下 preset-env的配置,加上 useBuiltIns: 'usage' ,表示會根據業務需求自動轉換須要轉換的新語法
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "targets": {
          "browsers": [
            "> 1%",
            "last 2 versions"
          ]
        },
        "debug":true //調試使用
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": false,
        "helpers": true,
        "regenerator": true,
        "useESModules": true
      }
    ]
  ]
}
複製代碼
  • 配置完成,ok,咱們再來運行 npm run dev-build 打包一次試試

終端日誌能夠看到注入的輔助代碼大幅度較少,文件的大小也大幅度減小,贊!

拷貝靜態文件

咱們有些項目中的文件,不是 js ,也不是 css , 圖片之類的,好比 README.md這些靜態資源,我也但願能打包到個人項目裏,怎麼辦呢?

其實就是文件的拷貝操做,咱們只須要將這些文件拷貝到目標目錄下便可,咱們能夠利用 copy-webpack-plugin 這個插件

  • 運行 npm run copy-webpack-plugin -D 安裝插件
  • 在項目目錄下建立一個 static/README.md 的測試文件
  • 修改 webpack.config.js , 將插件添加到配置裏去
new CopyWebpackPlugin({
    from: path.resolve(__dirname,'src/static'),
    to:path.resolve(__dirname,'dist/static') 
})
複製代碼

from 是靜態資源目錄源地址,to是要拷貝文件的目標地址,so easy~

npm run dev-build 打包運行!

能夠發現咱們的 dist 目錄已經將 src/static 的文件拷貝到了 dist/static

打包前清空

咱們修改了文件以後,每次打包都會在 dist 目錄下產生一個新的 main.[hash].js , 隨着咱們打包次數的增長,dist 目錄下會生產出一堆的 main.[hash].js,不出意外,你的dist目錄應該已經有很多了~

爲了保證咱們每次看到的都是最新的打包資源,而不受以前打包文件的干擾,這裏咱們須要引入另外一個插件—— clean-webpack-plugin

  • 經過 npm install clean-webpack-plugin -D 下載插件
  • webpack.config.jsplugins 下去配置它
plugins:[
    new CleanWebpackPlugin()
]
複製代碼

pass:該插件引入方式是稍微有點不一樣,經過如下這種方式引入:

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

如今,每次打包前都會先清空 dist 目錄下的文件,而後才產出打包後的文件,這樣看起來就清晰多了!

服務器代理

咱們在開發時,有時候但願在同域名下發送 API 請求 ,那麼代理某些 URL 會頗有用,代理 API 的配置對於 webpack來講,配置就很是簡單了,只須要在 proxy 中添加代理規則便可

proxy :  {
    "/api/test": {
     target: 'http://lohost:3000/', 
     secure: false,  
     changeOrigin: true, 
     pathRewrite: {
       '^/api/test': '/test'
    }
}

複製代碼

上面這行配置,就能夠將 /api/test 開頭的接口地址,會被代理到 http://localhost:3000/test 下,若是是https接口,須要配置 secure 這個參數 爲 true ,若是接口跨域,須要配置changeOrigin這個參數爲 true

壓縮JS和CSS

咱們如今打包出來的文件不管是 jscss 都是源文件,咱們但願在打包的時候壓縮咱們的代碼,一來是爲了安全,二來是能夠減小咱們打包文件的體積。

咱們選擇使用terser-webpack-plugin來壓縮js文件,替換掉以前的 uglifyjs-webpack-plugin,解決uglifyjs不支持es6語法問題,使用 optimize-css-assets-webpack-plugin 來壓縮 css 文件

  • 運行 npm install terser-webpack-plugin optimize-css-assets-webpack-plugin -D安裝插件
  • webpack.config.js 中引入並配置插件
new TerserPlugin({
    parallel: true,
    cache: true
}),
new OptimizeCSSAssetsPlugin({
    assetNameRegExp:/\.css$/g,
    cssProcessor:require('cssnano')
})
複製代碼

TerserPlugin 中的 parallel 表明開啓多進程,cache 表明設置緩存,OptimizeCSSAssetsPlugin 中加載了一個 cssnano 的東西, cssnanoPostCSSCSS優化和分解插件,會自動採用格式很好的CSS,並經過許多優化,以確保最終的生產環境儘量小。

如今咱們在繼續打包一次!

查看咱們打包後的文件,能夠發現 jscss 文件都沒打包成了一行,搞定!

結語

ok~ 看到這裏,想必你對 webpack 已經有了一個比較完善的認識,對常見的一些配置打包的 loader 或者 plugin 都有必定的瞭解了,總結會發現,套路基本都差很少,須要什麼 loaderplugin 只要去對應去查找便可~

emmm,其實 webpack 的功能很是強大,配置也是至關的多樣化,這裏只是列舉了一些比較常見的功能,對你來講也只是一個拋磚引玉的做用,它的內部實現也是至關的複雜,想要真正弄懂 webpack ,仍是須要多下一番苦功夫的~

對了,2019年還有幾個小時就結束了~

2020年,加油~

相關文章
相關標籤/搜索