一、 初試牛刀
1.簡(jiǎn)介
1) 為什么要使用webpack
現(xiàn)今的很多網(wǎng)頁(yè)其實(shí)可以看做是功能豐富的應(yīng)用,它們擁有著復(fù)雜的JavaScript代碼和一大堆依賴包。為了簡(jiǎn)化開發(fā)的復(fù)雜度,前端社區(qū)涌現(xiàn)出了很多好的實(shí)踐方法
? 模塊化,讓我們可以把復(fù)雜的程序細(xì)化為小的文件
? 類似于TypeScript這種在JavaScript基礎(chǔ)上拓展的開發(fā)語(yǔ)言:使我們能夠?qū)崿F(xiàn)目前版本的JavaScript不能直接使用的特性,并且之后還能轉(zhuǎn)換為JavaScript文件使瀏覽器可以識(shí)別
? Scss,less等CSS預(yù)處理器
? ES6 babel
這些改進(jìn)確實(shí)大大的提高了我們的開發(fā)效率,但是利用它們開發(fā)的文件往往需要進(jìn)行額外的處理才能讓瀏覽器識(shí)別,而手動(dòng)處理又是非常繁瑣的,這就為WebPack類的工具的出現(xiàn)提供了需求
2) 什么是webpack
WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語(yǔ)言(Scss,TypeScript等),并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用。將多個(gè)文件打包成一個(gè)文件或者對(duì)項(xiàng)目進(jìn)行優(yōu)化(打包,轉(zhuǎn)化和優(yōu)化)。

2.起步
1) 安裝
參考文獻(xiàn):
https://blog.csdn.net/xiaolinlife/article/details/85058160
https://www.cnblogs.com/aizai846/p/11497508.html
前提條件:在開始之前,請(qǐng)確保安裝了 Node.js 的最新版本。使用 Node.js 最新的長(zhǎng)期支持版本(LTS - Long Term Support),是理想的起步。使用舊版本,你可能遇到各種問題,因?yàn)樗鼈兛赡苋鄙?webpack 功能以及/或者缺少相關(guān) package 包。
要安裝最新版本或特定版本,請(qǐng)運(yùn)行以下命令之一
npm install --save-dev webpack或者npm i webpack --save-dev
npm install --save-dev webpack@<version>
如果你使用 webpack 4+ 版本,你還需要安裝 CLI
npm install --save-dev webpack-cli或者npm i webpack-cli -D
webpack與webpack-cli兩者結(jié)合簡(jiǎn)寫
npm i webpack webpack-cli -D
輸入如下命令,將在項(xiàng)目目錄中自動(dòng)生成package.json文件
npm init -y //不加-y為手動(dòng)生成
補(bǔ)充:
npm install name -save 簡(jiǎn)寫(npm install name -S) 自動(dòng)把模塊和版本號(hào)添加到dependencies
npm install name -save-dev 簡(jiǎn)寫(npm install name -D) 自動(dòng)把模塊和版本號(hào)添加到devdependencies
-D后,安裝包會(huì)在package中的 devDependencies對(duì)象中,簡(jiǎn)稱dev,dev是在開發(fā)環(huán)境中要用到的
-S后,安裝包會(huì)在package中的 dependencies 對(duì)象中,簡(jiǎn)稱dep,dep是在生產(chǎn)環(huán)境中要用到的
舉個(gè)例子:
構(gòu)建工具:gulp和webpack是用來(lái)壓縮代碼,打包等需要的工具,程序?qū)嶋H運(yùn)行的時(shí)候并不需要,就要放在dev中所以要用 -D
項(xiàng)目插件:例如element ui、echarts這種插件要在運(yùn)行中使用的,就要放在dep中所以就用 -S
對(duì)于大多數(shù)項(xiàng)目,我們建議本地安裝。這可以使我們?cè)谝肫茐氖阶兏?breaking change)的依賴時(shí),更容易分別升級(jí)項(xiàng)目。通常,webpack 通過運(yùn)行一個(gè)或多個(gè) npm scripts,會(huì)在本地 node_modules 目錄中查找安裝的 webpack
"scripts": {
"start": "webpack --config webpack.config.js"
}
當(dāng)你在本地安裝 webpack 后,你能夠從 node_modules/.bin/webpack 訪問它的 bin 版本
2) 簡(jiǎn)單使用

const path = require('path')
module.exports = {
mode: 'production',
entry:'./src/js/index.js',
output:{
path:path.join(__dirname,'dist'),
filename:"bundle.js"
},
}
3.初識(shí)webpack
1) webpack打包一個(gè)文件
webpack ./src/index.js --output dist/bundle.js
2) webpack配置文件
module.exports= {
//入口
entry:{},
//出口
output:{},
//loader加載器
module:{
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
//插件
plugins:{},
//開發(fā)服務(wù)器
devServer:{}
}
4) webpack的配置文件名
默認(rèn)的是webpack.config.js。但是不一定必須是這個(gè)
webpack --config config_file_name
5) 配置npm 命令
在package.json文件中具有一個(gè)scripts的設(shè)置項(xiàng)中可以設(shè)置npm的命令
例如:npm run build
“scripts”:{
“build”:“webpack --config config_file_name”
}
"scripts": {
"build": "./node_modules/.bin/webpack --config webpack.config.js"
}
// webpack4.x
“scripts”:{
“build”:“webpack”
}
注意:編譯后的文件在“/”目錄下,在html里引入時(shí)路徑應(yīng)為"/indexbundle.js"
6) 模式
webpack --mode develepment
webpack --mode production
"scripts": {
"build": "./node_modules/.bin/webpack --config webpack.config.js --mode develepment"
}
4.配置文件基本組成結(jié)構(gòu)
1) 入口
入口起點(diǎn)(entry point)指示 webpack 應(yīng)該使用哪個(gè)模塊,來(lái)作為構(gòu)建其內(nèi)部依賴圖的開始。進(jìn)入入口起點(diǎn)后,webpack 會(huì)找出有哪些模塊和庫(kù)是入口起點(diǎn)(直接和間接)依賴的。
可以通過在 webpack 配置中配置 entry 屬性,來(lái)指定一個(gè)入口起點(diǎn)(或多個(gè)入口起點(diǎn))。默認(rèn)值為 ./src。
2) 出口
output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles,以及如何命名這些文件,默認(rèn)值為 ./dist。基本上,整個(gè)應(yīng)用程序結(jié)構(gòu),都會(huì)被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個(gè) output 字段,來(lái)配置這些處理過程:
3) 模式
通過選擇 development 或 production 之中的一個(gè),來(lái)設(shè)置 mode 參數(shù),你可以啟用相應(yīng)模式下的 webpack 內(nèi)置的優(yōu)化
4) loader
loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉(zhuǎn)換為 webpack 能夠處理的有效模塊,然后你就可以利用 webpack 的打包能力,對(duì)它們進(jìn)行處理。
本質(zhì)上,webpack loader 將所有類型的文件,轉(zhuǎn)換為應(yīng)用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。
在更高層面,在 webpack 的配置中 loader 有兩個(gè)目標(biāo):
test 屬性,用于標(biāo)識(shí)出應(yīng)該被對(duì)應(yīng)的 loader 進(jìn)行轉(zhuǎn)換的某個(gè)或某些文件。
use 屬性,表示進(jìn)行轉(zhuǎn)換時(shí),應(yīng)該使用哪個(gè) loader。
5) 插件plugins
loader 被用于轉(zhuǎn)換某些類型的模塊,而插件則可以用于執(zhí)行范圍更廣的任務(wù)。插件的范圍包括,從打包優(yōu)化和壓縮,一直到重新定義環(huán)境中的變量。插件接口功能極其強(qiáng)大,可以用來(lái)處理各種各樣的任務(wù)。
想要使用一個(gè)插件,你只需要 require() 它,然后把它添加到 plugins 數(shù)組中。多數(shù)插件可以通過選項(xiàng)(option)自定義。你也可以在一個(gè)配置文件中因?yàn)椴煌康亩啻问褂猛粋€(gè)插件,這時(shí)需要通過使用 new 操作符來(lái)創(chuàng)建它的一個(gè)實(shí)例。
二、 webpack深入
1.入口
1) 多入口單出口
entry:[‘i.js’,’2.js’]
2) 多入口多出口
entry:{
name1: ‘1.js’,
name2: ’2.js’
},
output:{
path:path.join(__dirname,'dist/'),
filename: ‘[name]bundle.js’
}
2.出口
注意:
1、出口的默認(rèn)路徑
2、出口是絕對(duì)路徑
3、出口的默認(rèn)文件名與main的關(guān)系
3.html-webpack-plugin插件
用于編譯 Webpack 項(xiàng)目中的 html 類型的文件,如果直接將 html 文件置于 ./src 目錄中,用 Webpack 打包時(shí)是不會(huì)編譯到生產(chǎn)環(huán)境中的。因?yàn)?Webpack 編譯任何文件都需要基于配置文件先行配置的。
1) 安裝
npm i html-webpack-plugin -D
2) 引入
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
3) 使用
plugins:[
new HtmlWebpackPlugin({
title:’’,//頁(yè)面標(biāo)題
template:’./src/index.html’ //指定你生成的文件所依賴哪一個(gè)html文件模板,模板類型可以是html、jade、ejs等
});
]
title的使用
<%=htmlWebpackPlugin.options.title%>
注意:依賴 webpack 與webpack-cli
4) 消除緩存
plugins:[
new HtmlWebpackPlugin({
hash:true,
title:’’,//頁(yè)面標(biāo)題
template:’./src/index.html’ //模板文件
}),
]
5) 壓縮輸出
plugins:[
new htmlWebpackPlugin({
hash:true,
minify:{
collapseWhitespace:true, //去除空格
removeComments //去除注釋
minifyCSS
minifyJS
},
template:'./src/index.html',
}),
]
minify 的配置:https://blog.csdn.net/lqlqlq007/article/details/84103859
6) 生成多個(gè)頁(yè)面
plugins:[
new htmlWebpackPlugin({
hash:true,
minfy:{
collapaseWhitespace:true,
},
template:'./src/index.html',
filename: file1
}),
new htmlWebpackPlugin({
hash:true,
minfy:{
collapaseWhitespace:true,
},
template:'./src/nav.html',
filename: file2
})
]
7)多頁(yè)面分離引入
入口文件
entry:{
index:'./src/index.js',
index2:'./src/index2.js'
},
// 出口文件
output:{
path:path.join(__dirname,'dist/'),
filename:'[name]bundle.js'
},
插件配置
new htmlWebpackPlugin({
hash:true,
chunks:[“name1”,”name2”], // chunks主要用于多入口文件,當(dāng)你有多個(gè)入口文件,那就回編譯后生成多個(gè)打包后的文件,那么chunks 就能選擇你要使用那些js文件
minfy:{
collapaseWhitespace:true,
},
template:'./src/index.html',
filename: file1
}),
new htmlWebpackPlugin({
hash:true,
chunks:[name2],
minfy:{
collapaseWhitespace:true,
},
template:'./src/index.html',
filename: file2
})
4.clean-webpack-plugin
1) 下載
npm i clean-webpack-plugin -D
2) 引入
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
3) 使用
在html-webpack-plugin插件使用之前去除已經(jīng)產(chǎn)生的垃圾文件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
/*
入口 多入口單出口使用數(shù)組 ['./public/src/js/index.js','./public/src/js/reindex.js',]
entry:'./src/js/index.js',
*/
/*多入口多出口*/
entry:{
index:'./src/js/index.js',
reindex:'./src/js/reindex.js',
},
// 出口 默認(rèn)的出口目錄是dist
output:{
path:path.join(__dirname,'dist/'),
// filename:'bundle.js',
filename:'[name]bundle.js'
},
// 打包模式
mode:'development',
// 自動(dòng)引入插件
plugins:[
new CleanWebpackPlugin(), // 刪除文件 保留新文件
new HtmlWebpackPlugin({
hash:true, // 清除緩存
chunks:['index','reindex'], // 在壓縮后的html里引入的bundle里的一部分壓縮代碼
filename:'index.html', // ../html/index.html
title:"lalala",
template:'./index.html',
minify:{
collapseWhitespace:true // 去除空格
}
}),
new HtmlWebpackPlugin({
hash:true, // 清除緩存
chunks:['reindex'],
template:'./reindex.html',
filename:'reindex.html'
}),
]
}
5.webpack-devserver
一個(gè)輕量級(jí)的服務(wù)器,修改文件源碼后,自動(dòng)刷新頁(yè)面將修改同步到頁(yè)面上
1) 下載
npm i webpack-devserver webpack-dev-server -D
2) 配置
devServer:{
host:localhost,
port:8090,
contentBase:path.join(__dirname,’dist’)
}
3) 配置啟動(dòng)
npm run dev
“scripts”:{
“dev”:“webpack-dev-server --config config_file_name”
}
scripts:{
“dev”:”webpack-dev-server --config webpack.config.js”
}
// webpack4.x
scripts:{
“dev”:”webpack-dev-server”
}
4) 自動(dòng)打開
devServer:{
host:localhost,
port:8090,
contentBase:path.join(__dirname,’dist’),
open:true
}
5) 熱更新
const webpack = require(“webpack”);
devServer:{
host:localhost,
port:8090,
contentBase:path.join(__dirname,’dist’),
open:true,
hot:true
},
plugins:[
new webpack.HotModuleReplacementPlugin()
]

三、 loader
加載器,轉(zhuǎn)化器
1.打包c(diǎn)ss
1) 安裝
css-loader
style-loader
npm i css-loader style-loader -D
2) 配置
module:{
rules:[
{
test:/\.css$/, //匹配的文件類型
use:['style-loader','css-loader'] //對(duì)應(yīng)要調(diào)用的loader
}
]
}
關(guān)于使用loader的三種寫法:
use:['style-loader','css-loader']
loader:['style-loader','css-loader']
use:[
{loader:style-loader },
{loader:css-loader }
]
2.壓縮代碼(之前)uglifyjs
1) 下載
npm i uglifyjs-webpack-plugin -D
2) 引入
const uglify = require(‘uglifyjs-webpack-plugin’)
3) 使用
new uglify()
3.圖片
1) 下載
npm i file-loader url-loader -D
2) 使用
{
test:/\.(png|jpg|gif|jpeg)/,
use:['url-loader']
}
3) base64轉(zhuǎn)碼
use:[
{
loader:’url-loader’,
options:{
limit:50000 //指定圖片大小,小于limit轉(zhuǎn)為base64
outputPath: 圖片放置目錄
publicPath: 解決圖片路徑
}
}
]
4.分離css代碼 1(已被棄用)
1) 安裝
npm i extract-text-webpack-plugin -D
2) 引入
const extract = require('extract-text-webpack-plugin');
3) 使用
在plugins中添加:
new extract('css/index.css'),
在use中修改
use:extract.extract({
use:'css-loader',
fallback:'style-loader'
})
4) 注意:
npm run build 報(bào)錯(cuò)

npm i extract-text-webpack-plugin@next -D 為4.X
npm i extract-text-webpack-plugin -D 為3.x
5.分離css 2
安裝:
npm i mini-css-extract-plugin -D
使用:
// 在js中引入sass
require('../css/index.css')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '',
// hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
],
},
],
},
};
6.打包less
安裝:
npm i less less-loader -D
使用:
// 在js中引入less
require('../less/index.less')
// 在config里進(jìn)行配置
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
{
test:/\.less$/,
// use:['style-loader','css-loader','less-loader']
// 分離
use:[
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'',
}
},
'css-loader','less-loader'
]
}
7.打包sass
安裝:
npm i node-sass sass-loader -D
使用:
// 在js中引入sass
require('../sass/index.scss')
// 在config里進(jìn)行配置
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
{
test:/\.(sass|scss)$/,
// use:['style-loader','css-loader','sass-loader']
// 分離
use:[
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'',
}
},
'css-loader','sass-loader'
]
}
8.postcss添加css前綴
1) 下載
npm i postcss-loader autofrefixer -D
2) 配置單獨(dú)的配置文件 postcss.config.js
module.exports={
plugins:[
require(‘a(chǎn)utoprefixer’)
]
}
3) 配置loader
use:[‘css-loader',‘postcss-loader’]
9.消除冗余
將項(xiàng)目中沒有用到的css代碼或js代碼過濾掉(注釋掉),不將其打包到文件中
1) 下載
npm i purifycss-webpack purify-css -D
npm i glob -D
2) 引入
const glob = require('glob');
const purify = require(‘purifycss-webpack’)
3) 使用
需要使用到一個(gè)掃描路徑的包 glob
new purify({
paths:glob.sync(path.join(__dirname,’./src/*.html’))
})
10.調(diào)試
4.x
--mode production
3.x
devtool:’source-map’
11.babel
將js由ES5轉(zhuǎn)換成ES6的格式
官方文檔
webpack編譯ES6,ES7,babel-loader的使用
1) 安裝
npm i babel-core babel-loader babel-preset-env -D
2) 使用
{
test: /\.(js|jsx)/,
exclude: /(node_modules|bower_components)/,
use:[ {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}]
}
12.react (jsx)
npm i babel-preset-react -D
npm i react react-dom -D
四、 雜項(xiàng)
1.模塊化的使用
遵循node模塊的引入與導(dǎo)出
2.在webpack中使用json
之前需要json-loader。但是4.x默認(rèn)可以引入json。
const name = require(‘xxx.json’)
3.靜態(tài)資源拷貝(圖片、文字、js等)
1) 下載
npm i copy-webpack-plugin -D
2) 引入
const CopyPlugin = require('copy-webpack-plugin');
3) 使用
new CopyWebpackPlugin([{
from: path.join(__dirname,’src/image’),
to:path.join(__dirname,’dist/image’)
}])
4.使用第三方庫(kù)
1) 下載
2) 引入
3) 使用
4) 第二種方式 (推介)
只有在內(nèi)部使用到模塊的時(shí)候才會(huì)打包
new webpack.providePlugin{{
$:’jquery’,
lodash: ‘lodash’
}}
5) 提取第三方庫(kù)

5.簡(jiǎn)單的打包發(fā)布
"scripts": {
"build": "webpack -p"
}