總結(jié)WebPack基礎(chǔ)配置,流程圈暗,原理泽铛。
WebPack是什么
定義:WebPack是模塊打包工具。
原理:分析項(xiàng)目結(jié)構(gòu)北发,找到JavaScript模塊以及其他瀏覽器不能直接運(yùn)行的模塊(Scss纹因,TypeScript等),轉(zhuǎn)換并打包為瀏覽器可以識(shí)別并運(yùn)行的格式琳拨,讓瀏覽器使用瞭恰。
工作流程:
1、通過(guò)配置找到給定的入口文件(如index.js)
2狱庇、從入口文件開(kāi)始分析并處理項(xiàng)目所有的依賴(lài)模塊惊畏,并遞歸地構(gòu)建一個(gè)依賴(lài)關(guān)系圖(dependency graph)恶耽。webpack把所有的文件都當(dāng)做模塊。
* JavaScript模塊:webpack自己本身就可以識(shí)別并處理
* 其他模塊:通過(guò)使用loaders來(lái)分析和轉(zhuǎn)譯瀏覽器不認(rèn)識(shí)的模塊為瀏覽器認(rèn)識(shí)的格式
3颜启、把所有的模塊打包為一個(gè)或多個(gè)瀏覽器可識(shí)別的JavaScript文件偷俭,默認(rèn)叫做bundle.js(也可以自己改名),根據(jù)給定的輸出地址缰盏,輸出到指定目錄涌萤,一般叫做dist。
webpack是基于node的口猜,所以把靜態(tài)文件都看成模塊负溪,通過(guò)模塊化語(yǔ)言(esmodule,commonjs,require語(yǔ)法)識(shí)別模塊的引入,當(dāng)遇到模塊引入時(shí)暮的,webpack就知道這是一個(gè)依賴(lài)模塊了笙以。
官網(wǎng)鏈接:
英:https://webpack.js.org/ 【較新,webpack相關(guān)更新都會(huì)比較及時(shí)】
中:https://www.webpackjs.com/
WebPack使用
下面通過(guò)一系列詳細(xì)實(shí)例來(lái)解析webpack配置冻辩。
安裝
新建目錄猖腕,在目錄下執(zhí)行命令:
npm init -y #初始化一個(gè)package.json
npm install webpack webpack-cli -D #本地安裝最新版`webpack`,`webpack-cli`
npm info webpack #查看webpack歷史版本信息(當(dāng)要安裝特定版本時(shí))
webpack打包Js模塊
由于最新版的webpack是支持零配置,默認(rèn)的入口文件是src/index.js恨闪,因此我們新建一個(gè)src文件夾倘感,新建兩個(gè)js文件,一個(gè)默認(rèn)的入口文件index.js
咙咽,一個(gè)a.js
:
//index.js
import a from "./a"
a()
//a.js
function a(){
console.log("hello,我是a");
}
export default a;
新建一個(gè)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>Document</title>
</head>
<body>
<script src="./src/index.js"></script>
</body>
</html>
目錄現(xiàn)在如下:
這時(shí)候打開(kāi)在瀏覽器打開(kāi)html老玛,瀏覽器是不識(shí)別import的,會(huì)報(bào)錯(cuò)钧敞,因此我們使用webpack來(lái)解析并打包js模塊蜡豹,運(yùn)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功,用時(shí) 4.878 秒
'prefix' 不是內(nèi)部或外部命令溉苛,也不是可運(yùn)行的程序
或批處理文件镜廉。
Hash: b14a40261c3e17ea5995
Version: webpack 4.31.0
Time: 355ms
Built at: 2019-05-19 15:42:16
Asset Size Chunks Chunk Names
main.js 976 bytes 0 [emitted] main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 97 bytes {0} [built]
| ./src/index.js 24 bytes [built]
| ./src/a.js 73 bytes [built]
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set
'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
webpack命令行打包的命令:
webpack #打包,默認(rèn)入口文件為src/index.js webpack index.js #打包愚战,指定入口文件路徑
可以看到webpack把js模塊打包了并輸出了一個(gè)main.js
娇唯,現(xiàn)在目錄下多了一個(gè)dist文件夾:
把index.html里引入的js路徑修改為dist/main.js,在瀏覽器打開(kāi)寂玲,就可以看到j(luò)s正確執(zhí)行結(jié)果:
在運(yùn)行npx webpack時(shí)塔插,我們可以看到有一個(gè)警告:
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set
'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
意思是說(shuō)我們沒(méi)有設(shè)置mode選項(xiàng),這是webpack的打包模式拓哟,默認(rèn)是“production”就是生產(chǎn)打包選項(xiàng)想许,production模式會(huì)自自動(dòng)壓縮打包后的文件,我們可以把mode設(shè)置為其他模式,設(shè)置為開(kāi)發(fā)模式(development):
const path = require('path');
module.exports = {
mode:"development"
}
再次運(yùn)行時(shí)伸刃,可以看到輸出的文件不再是壓縮后的文件谎砾。
webpack配置文件
零配置比較局限,要有更多的功能需要手動(dòng)配置捧颅,根目錄下新增一個(gè)webpack.config.js
:
//webpack.config.js
//是一個(gè)對(duì)象
module.exports = {
}
為什么要是webpack.config.js呢景图,這是webpack定義的一個(gè)默認(rèn)的配置文件名,webpack運(yùn)行時(shí)會(huì)檢查是否有這個(gè)配置文件碉哑,有這個(gè)配置文件時(shí)挚币,會(huì)使用其中的配置來(lái)覆蓋默認(rèn)配置。
entry & output
入口和輸出文件目錄是可以自己設(shè)定的扣典,輸入以下內(nèi)容:
//webpack.config.js
const path = require('path');
module.exports = {
//entry:"./src/index.js", #入口文件路徑配置
entry:{ #入口文件配置可以使用字符串模式也可以使用對(duì)象模式
main:'./src/index.js'
},
output:{ #輸出文件路徑配置
filename:'bundle.js', #輸出文件名
//output的path需要是絕對(duì)路徑
path:path.resolve(__dirname,'dist') #輸出文件路徑妆毕,絕對(duì)路徑,使用node.js的path模塊來(lái)解析為絕對(duì)路徑贮尖,這里設(shè)置為根目錄下的dist目錄
},
}
這里修改了出口文件的名字笛粘,刪除dist文件夾后,再次運(yùn)行npx webpack
湿硝,可以看到dist里的文件已經(jīng)變成了bundle.js
什么是loader
上面已經(jīng)說(shuō)到薪前,webpack默認(rèn)只能識(shí)別JS模塊,其他模塊是不識(shí)別的关斜。
而loader就是幫助webpack來(lái)識(shí)別并解析除了JS的其他模塊的示括。
針對(duì)各種各樣的模塊,有各種的loader痢畜。
loader是一個(gè)聲明式函數(shù)垛膝。
當(dāng)webpack中有不是JS的模塊時(shí),需要配置對(duì)應(yīng)的loader丁稀,監(jiān)測(cè)對(duì)應(yīng)的模塊格式吼拥,使用對(duì)應(yīng)的loader處理。loader的配置主要在module.rules中進(jìn)行线衫,這是一個(gè)數(shù)組凿可,里面是各種loader的規(guī)則。
每一個(gè)loader的主要工作機(jī)制:
- 識(shí)別文件類(lèi)型桶雀,確定具體處理該模塊的loader(rule.test)
- 使用對(duì)應(yīng)的loader,對(duì)文件進(jìn)行相關(guān)操作轉(zhuǎn)換(rule.use)
loader的在配置文件中的設(shè)置:
//webpack.config.js
const path = require('path');
module.exports = {
entry:{
main:'./src/index.js'
},
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'dist')
},
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
{
test:/\.xxx$/, //表示匹配規(guī)則唬复,是一個(gè)正則表達(dá)式
use:{ //表示針對(duì)匹配文件將使用處理的loader
loader:"xxx-loader",
options:{ //loader的可配置項(xiàng)
}
}
}
]
},
}
常用的loader列舉:
- 處理靜態(tài)文件:file-loader矗积、url-loader、raw-loader
- 處理樣式模塊:style-loader敞咧、css-loader棘捣、sass-loader、less-loader休建、postcss-loader
- 處理數(shù)據(jù)文件:csv-loader乍恐、xml-loader
- 處理模塊語(yǔ)言:html-loader评疗、markdown-loader
- 處理測(cè)試模塊:mocha-loader、eslint-loader
靜態(tài)資源模塊loader:file-loader
靜態(tài)資源茵烈,比如圖片百匆、文件,使用file-loader來(lái)處理
file-loader的工作機(jī)制:
- 把打包入口中識(shí)別出來(lái)的靜態(tài)模塊直接復(fù)制到輸出目錄(dist)下呜投;
- 返回一個(gè)復(fù)制的文件的地址名稱(chēng)(文件名)
使用場(chǎng)景:只需要把文件移動(dòng)到輸出目錄下加匈,不需要處理,比如圖片仑荐、excel雕拼、word、svg等等粘招。
在index.js
中引入一個(gè)圖片啥寇,圖片是靜態(tài)文件,webpack是不認(rèn)識(shí)的洒扎,需要file-loader處理
import a from "./a"
a()
var pic = require('./pic.jpg');
console.log(pic);
先安裝:
npm i file-loader -D
配置:
const path = require('path');
module.exports = {
entry:"./src/index.js",
// entry:{
// main:'./index.js'
// },
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
mode:"development",
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"file-loader"
}
}
]
},
}
執(zhí)行npx webpack
可以看到文件正常打包辑甜,dist里面多了一個(gè)圖片:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功,用時(shí) 4.322 秒
'prefix' 不是內(nèi)部或外部命令逊笆,也不是可運(yùn)行的程序
或批處理文件栈戳。
Hash: 2ef4598423ef35d9401b
Version: webpack 4.31.0
Time: 409ms
Built at: 2019-05-19 21:43:02
Asset Size Chunks Chunk Names
91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
bundle.js 4.86 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 59 bytes {main} [built]
[./src/pic.jpg] 82 bytes {main} [built]
復(fù)制的文件名是可以改的,輸出位置也可以通過(guò)options選項(xiàng)可以配置:
module:{
rules:[
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"file-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符(placeholder)难裆,name表示源文件的名字子檀,ext是源文件的后綴,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/", #配置輸出位置
}
}
}
]
},
運(yùn)行命令打包如下:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功乃戈,用時(shí) 14.264 秒
'prefix' 不是內(nèi)部或外部命令褂痰,也不是可運(yùn)行的程序
或批處理文件。
Hash: faabe6751318c1104e28
Version: webpack 4.31.0
Time: 294ms
Built at: 2019-05-19 21:57:04
Asset Size Chunks Chunk Names
bundle.js 4.89 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
Entrypoint main = bundle.js
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 77 bytes {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
很多l(xiāng)oader都有一個(gè)叫做placeholder(占位符)的概念症虑,可以有不同的占位符缩歪,比如名稱(chēng)、后綴谍憔、hash等匪蝙。
靜態(tài)模塊:url-loader
url-loader可以做file-loader可以做的所有事情,多出來(lái)的功能是:默認(rèn)把靜態(tài)資源轉(zhuǎn)成base64格式并打包到bundle.js(最終的打包文件)习贫,可以使用limit選項(xiàng)來(lái)設(shè)置是否轉(zhuǎn)譯范圍逛球。大于limit范圍的不轉(zhuǎn)譯。
安裝:
npm i url-loader -D
配置:
module:{
rules:[
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符苫昌,name表示源文件的名字颤绕,ext是源文件的后綴,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)url-loader處理jpg模塊,會(huì)判斷體積是否在限制范圍之內(nèi)奥务,在limit之內(nèi)的物独,就轉(zhuǎn)成base64格式并打包到bundle.js,否則就不轉(zhuǎn)直接輸出到dist
}
}
}
]
},
運(yùn)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功氯葬,用時(shí) 5.906 秒
'prefix' 不是內(nèi)部或外部命令挡篓,也不是可運(yùn)行的程序
或批處理文件。
Hash: 74ba975fbbf2f7d18da1
Version: webpack 4.31.0
Time: 328ms
Built at: 2019-05-19 22:02:46
Asset Size Chunks Chunk Names
bundle.js 16.7 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 77 bytes {main} [built]
[./src/pic.jpg] 11.9 KiB {main} [built]
這時(shí)候我們的dist目錄下沒(méi)有了圖片了溢谤,在bundle.js中卻多出來(lái)一堆base64的字符串瞻凤,url-loader默認(rèn)把圖片轉(zhuǎn)成了base64字符串。
當(dāng)圖片小的時(shí)候世杀,用url-loader可以減少請(qǐng)求數(shù)阀参,但是圖片大的時(shí)候,這樣會(huì)增大打包文件的體積瞻坝,所以需要有個(gè)度蛛壳,可以使用options中的limit字段來(lái)設(shè)置文件是否轉(zhuǎn)base64的限制,在限制范圍內(nèi)所刀,就轉(zhuǎn)譯base64并打包到最終打包文件bundle.js衙荐,否則,就直接執(zhí)行file-loader的功能浮创,直接移動(dòng)到輸出目錄忧吟。
樣式文件模塊:
解釋style-loader、css-loader斩披、sass-loader溜族、postcss-loader
處理css模塊
處理css模塊需要兩個(gè)loader:style-loader和css-loader
css-loader工作機(jī)制:處理css模塊,識(shí)別合并css模塊
style-loader工作機(jī)制:把合并的css模塊放到html中head的style標(biāo)簽中垦沉。
安裝
npm i style-loader css-loader -D
配置:
module:{
rules:[
{
test:/\.css$/,
use: [ #執(zhí)行順序:從下到上煌抒,從右到左
'style-loader', #把合并的css放到style標(biāo)簽
'css-loader', #先識(shí)別css并合并為一個(gè)css
],
},
]
},
在src目錄中增加index.css
body{
background:blue;
}
在index.js
中引入index.css
import './index.css';
運(yùn)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功,用時(shí) 5.363 秒
'prefix' 不是內(nèi)部或外部命令厕倍,也不是可運(yùn)行的程序
或批處理文件寡壮。
Hash: 01f1fa305f332e6c34fc
Version: webpack 4.31.0
Time: 962ms
Built at: 2019-05-19 22:23:28
Asset Size Chunks Chunk Names
bundle.js 24.6 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./src/index.css] 175 bytes {main} [built]
[./src/a.js] 73 bytes {main} [built]
[./src/index.css] 1.06 KiB {main} [built]
[./src/index.js] 102 bytes {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 3 hidden modules
可以看到成功打包了index.css,在瀏覽器打開(kāi)index.html讹弯,可以看到css生效了:
處理scss模塊
樣式文件有很多種寫(xiě)法况既,這里以sass為例,sass的文件后綴是scss组民,處理sass文件需要style-loader棒仍、css-loader、sass-loader邪乍,
安裝:
#sass-loader把sass語(yǔ)法轉(zhuǎn)換成css降狠,依賴(lài)node-sass模塊
npm i scss-loader node-sass -D
配置:
module:{
rules:[
{
test:/\.scss$/,
use:[
'style-loader',//放在正確的打包位置
'css-loader',//打包合并css
'sass-loader',//處理sass,轉(zhuǎn)成css
]
}
]
},
在src下新增index.scss
:
html{
body{
background:blue;
}
}
修改index.js
庇楞,引入index.scss
import a from "./a"
a()
var pic = require('./pic.jpg');
console.log(pic)
// import './index.css';
import './index.scss';
刪除dist目錄榜配,執(zhí)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功,用時(shí) 15.772 秒
'prefix' 不是內(nèi)部或外部命令吕晌,也不是可運(yùn)行的程序
或批處理文件蛋褥。
Hash: b704540cce4d7e089aea
Version: webpack 4.31.0
Time: 3343ms
Built at: 2019-05-20 06:29:40
Asset Size Chunks Chunk Names
bundle.js 24.9 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./src/index.scss] 176 bytes {main} [built]
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 129 bytes {main} [built]
[./src/index.scss] 1.18 KiB {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 3 hidden modules
可以看到成功打包了scss模塊,在瀏覽器打開(kāi)index.html
睛驳,樣式成功渲染:
自動(dòng)給樣式增加前綴:postcss-loader
一般來(lái)說(shuō)開(kāi)發(fā)之中還會(huì)對(duì)樣式模塊的loader增加一個(gè)處理:自動(dòng)給樣式增加前綴(-webkit-烙心,-o-等瀏覽器兼容前綴),這樣就不用自己一個(gè)個(gè)的寫(xiě)了乏沸。
postcss-loader可以自定識(shí)別需要增加前綴的樣式淫茵,自動(dòng)給他們?cè)黾忧熬Y代碼。
安裝:
#autoprefixer是增加前綴的依賴(lài)包
npm i postcss-loader autoprefixer -D
配置:
module:{
rules:[
{
test:/\.scss$/,
use:[
'style-loader',//放在正確的打包位置
'css-loader',//打包合并css
'sass-loader',//處理sass蹬跃,轉(zhuǎn)成css
'postcss-loader'//自定增加前綴
]
}
]
},
增加postcss-loader配置文件匙瘪,在根目錄下新建postcss.config.js
module.exports = {
plugins:[
require('autoprefixer')
]
}
在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>Document</title>
</head>
<body>
<div class="demo">
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
在index.scss
增加css3代碼:
html{
body{
background: green;
.demo{
width:200px;
height:200px;
background: red;
transform:translate(100px,100px)
}
}
}
運(yùn)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功,用時(shí) 4.451 秒
'prefix' 不是內(nèi)部或外部命令蝶缀,也不是可運(yùn)行的程序
或批處理文件丹喻。
Hash: 6d8a1bc0a093edc5c610
Version: webpack 4.31.0
Time: 1342ms
Built at: 2019-05-20 06:44:47
Asset Size Chunks Chunk Names
bundle.js 25.3 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src/index.js!./src/index.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src!./src/index.scss 350 bytes {main} [built]
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 129 bytes {main} [built]
[./src/index.scss] 1.31 KiB {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 3 hidden modules
可以看到成功打包了,瀏覽器刷新:
可以看到css中自動(dòng)增加了瀏覽器兼容前綴代碼翁都。
什么是Plugins
Plugins是開(kāi)始打包時(shí)碍论,在某個(gè)時(shí)刻,幫助我們處理一些什么事情的機(jī)制柄慰,它是事件驅(qū)動(dòng)的鳍悠,本身是一個(gè)類(lèi)。
一種插件就是一種函數(shù)先煎,通過(guò)傳入不同的參數(shù)贼涩,可以實(shí)現(xiàn)不同的功能。
自動(dòng)生成html
HtmlWebpackPlugin是在打包后的時(shí)刻薯蝎,自動(dòng)幫你生成一個(gè)引入了打包后的JS的html遥倦,并放到輸出目錄下的一個(gè)插件。
安裝
npm i html-webpack-plugin -D
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry:"./src/index.js",
// entry:{
// main:'./index.js'
// },
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
mode:"development",
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
// {
// test:/\.(jpe?g|png|gif)$/,
// use:{
// loader:"file-loader",
// options:{
// name:"[name]-[hash].[ext]",//[]表示占位符占锯,name表示源文件的名字袒哥,ext是源文件的后綴,還可以連接hash:[name]-[hash].[ext]
// outputPath:"images/",
// }
// }
// },
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符消略,name表示源文件的名字堡称,ext是源文件的后綴,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)url-loader處理jpg模塊艺演,會(huì)判斷體積是否在限制范圍之內(nèi)却紧,在limit之內(nèi)的桐臊,就轉(zhuǎn)成base64格式并打包到bundle.js,否則就不轉(zhuǎn)直接輸出到dist
}
}
},
{
test:/\.scss$/,
use:[
'style-loader',//放在正確的打包位置
'css-loader',//打包合并css
'sass-loader',//處理sass晓殊,轉(zhuǎn)成css
'postcss-loader'
]
}
]
},
//配置插件断凶,是個(gè)數(shù)組,里面的項(xiàng)是插件的實(shí)例
plugins:[
//自動(dòng)生成html巫俺,并移到輸出目錄
new HtmlWebpackPlugin({
title:'html模板',
filename:'index.html',
template:"./index.html" #生成html的模板路徑
}),
],
}
刪除dist目錄认烁,刪除html模板(此時(shí)根目錄下的index.html)中自己加上去的script引入,運(yùn)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功介汹,用時(shí) 12.055 秒
'prefix' 不是內(nèi)部或外部命令却嗡,也不是可運(yùn)行的程序
或批處理文件。
Hash: 72bd3988b3ab5a7aeb46
Version: webpack 4.31.0
Time: 4965ms
Built at: 2019-05-20 21:13:57
Asset Size Chunks Chunk Names
bundle.js 25.3 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
index.html 406 bytes [emitted]
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src/index.js!./src/index.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src!./src/index.scss 350 bytes {main} [built]
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 129 bytes {main} [built]
[./src/index.scss] 1.31 KiB {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 3 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 569 bytes {0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 1 hidden module
成功打包嘹承,輸出的dist目錄下多了一個(gè)index.html窗价,里面自動(dòng)加上了打包后的js
自動(dòng)刪除dist目錄
我們每次在打包時(shí),文件都是已覆蓋已有的叹卷,不刪除多余的舌镶。所以dist目錄如果不手動(dòng)刪除,就會(huì)有很多多余文件豪娜,因此我們可以使用一個(gè)插件幫助我們執(zhí)行刪除dist目錄的操作餐胀。
CleanWebpackPlugin插件是在打包之前,自動(dòng)幫我們刪除dist目錄瘤载,以免污染打包環(huán)境否灾。
安裝:
npm i clean-webpack-plugin -D
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry:"./src/index.js",
// entry:{
// main:'./index.js'
// },
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
mode:"development",
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
// {
// test:/\.(jpe?g|png|gif)$/,
// use:{
// loader:"file-loader",
// options:{
// name:"[name]-[hash].[ext]",//[]表示占位符,name表示源文件的名字,ext是源文件的后綴,還可以連接hash:[name]-[hash].[ext]
// outputPath:"images/",
// }
// }
// },
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符钝尸,name表示源文件的名字,ext是源文件的后綴扣汪,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)url-loader處理jpg模塊,會(huì)判斷體積是否在限制范圍之內(nèi)锨匆,在limit之內(nèi)的崭别,就轉(zhuǎn)成base64格式并打包到bundle.js,否則就不轉(zhuǎn)直接輸出到dist
}
}
},
{
test:/\.scss$/,
use:[
'style-loader',//放在正確的打包位置
'css-loader',//打包合并css
'sass-loader',//處理sass恐锣,轉(zhuǎn)成css
'postcss-loader'
]
}
]
},
plugins:[ #執(zhí)行順序從上到下
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'html模板',
filename:'index.html',
template:"./index.html"
}),
],
}
自動(dòng)導(dǎo)出css
如果不想讓css放在style標(biāo)簽中茅主,我們可以使用插件來(lái)幫我們抽離css并打包輸出到dist目錄。
MiniCssExtractPlugin可以幫我們代替style-loader土榴,抽離css诀姚,并輸出到dist目錄
安裝:
npm i mini-css-extract-plugin -D
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:"./src/index.js",
// entry:{
// main:'./index.js'
// },
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
mode:"development",
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
// {
// test:/\.(jpe?g|png|gif)$/,
// use:{
// loader:"file-loader",
// options:{
// name:"[name]-[hash].[ext]",//[]表示占位符,name表示源文件的名字玷禽,ext是源文件的后綴赫段,還可以連接hash:[name]-[hash].[ext]
// outputPath:"images/",
// }
// }
// },
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符呀打,name表示源文件的名字,ext是源文件的后綴糯笙,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)url-loader處理jpg模塊聚磺,會(huì)判斷體積是否在限制范圍之內(nèi),在limit之內(nèi)的炬丸,就轉(zhuǎn)成base64格式并打包到bundle.js,否則就不轉(zhuǎn)直接輸出到dist
}
}
},
{
test:/\.scss$/,
use:[
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',//打包合并css
'sass-loader',//處理sass蜒蕾,轉(zhuǎn)成css
'postcss-loader'
]
}
]
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'html模板',
filename:'index.html',
template:"./index.html"
}),
new MiniCssExtractPlugin({
filename: '[name].css', #輸出文件名
chunkFilename: '[id].css', #模塊名
}),
],
}
執(zhí)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功稠炬,用時(shí) 3.619 秒
'prefix' 不是內(nèi)部或外部命令,也不是可運(yùn)行的程序
或批處理文件咪啡。
Hash: dd2b22f9beb8876949e7
Version: webpack 4.31.0
Time: 2052ms
Built at: 2019-05-20 21:45:17
Asset Size Chunks Chunk Names
bundle.js 5.5 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
index.html 399 bytes [emitted]
main.css 204 bytes main [emitted] main
Entrypoint main = main.css bundle.js
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 127 bytes {main} [built]
[./src/index.scss] 39 bytes {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 1 hidden module
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 521 bytes {0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/lib/loader.js!node_modules/postcss-loader/src/index.js!src/index.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src/index.js!./src/index.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src!./src/index.scss 350 bytes {mini-css-extract-plugin} [built]
+ 1 hidden module
輸出日志中可以看到mini-css-extract-plugin的工作流程首启,dist目錄下多了一個(gè)main.css文件,輸出的index.html中自動(dòng)增加了main.css撤摸。
開(kāi)發(fā)模式排查問(wèn)題:SourceMap
默認(rèn)情況下毅桃,如果代碼有了錯(cuò)誤,瀏覽器會(huì)直接定位到bundle.js准夷,很難找到是哪里出了錯(cuò)钥飞,但是我們可以通過(guò)開(kāi)啟SourceMap來(lái)幫助我們定位錯(cuò)誤。
mode為development時(shí)衫嵌,是默認(rèn)開(kāi)啟SourceMap的读宙,當(dāng)關(guān)閉開(kāi)發(fā)模式時(shí),我們可以使用devtool來(lái)設(shè)置SourceMap
devtool是設(shè)置打包時(shí)的文件映射楔绞,文件映射越完整结闸,打包速度越慢,devtool可以設(shè)置各種速度和程度的打包及文件映射酒朵。
設(shè)置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:"./src/index.js",
// entry:{
// main:'./index.js'
// },
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
mode:"development",
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
// {
// test:/\.(jpe?g|png|gif)$/,
// use:{
// loader:"file-loader",
// options:{
// name:"[name]-[hash].[ext]",//[]表示占位符桦锄,name表示源文件的名字,ext是源文件的后綴蔫耽,還可以連接hash:[name]-[hash].[ext]
// outputPath:"images/",
// }
// }
// },
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符结耀,name表示源文件的名字,ext是源文件的后綴匙铡,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)url-loader處理jpg模塊饼记,會(huì)判斷體積是否在限制范圍之內(nèi),在limit之內(nèi)的慰枕,就轉(zhuǎn)成base64格式并打包到bundle.js具则,否則就不轉(zhuǎn)直接輸出到dist
}
}
},
{
test:/\.scss$/,
use:[
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',//打包合并css
'sass-loader',//處理sass,轉(zhuǎn)成css
'postcss-loader'
]
}
]
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'html模板',
filename:'index.html',
template:"./index.html"
}),
new MiniCssExtractPlugin({
filename: '[name].css', //輸出文件名
chunkFilename: '[id].css', //模塊名
}),
],
devtool:'source-map' //設(shè)置文件映射
}
執(zhí)行命令:
F:\front-end\webpack\webpack-demos>npx webpack
npx: 1 安裝成功具帮,用時(shí) 4.319 秒
'prefix' 不是內(nèi)部或外部命令博肋,也不是可運(yùn)行的程序
或批處理文件低斋。
Hash: d599b2c86a9ac5ae3802
Version: webpack 4.31.0
Time: 1930ms
Built at: 2019-05-20 21:52:50
Asset Size Chunks Chunk Names
bundle.js 5.29 KiB main [emitted] main
bundle.js.map 4.19 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
index.html 399 bytes [emitted]
main.css 240 bytes main [emitted] main
main.css.map 401 bytes main [emitted] main
Entrypoint main = main.css bundle.js main.css.map bundle.js.map
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 127 bytes {main} [built]
[./src/index.scss] 39 bytes {main} [built]
[./src/pic.jpg] 93 bytes {main} [built]
+ 1 hidden module
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 521 bytes {0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/lib/loader.js!node_modules/postcss-loader/src/index.js!src/index.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src/index.js!./src/index.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src!./src/index.scss 350 bytes {mini-css-extract-plugin} [built]
+ 1 hidden module
可以看到dist目錄里多了后綴為map的文件,這些文件就是打包文件與源碼的映射文件匪凡,有助于我們定位錯(cuò)誤膊畴,調(diào)試代碼。
開(kāi)發(fā)模式下我們可以使用模式“cheap-module-eval-source-map”病游,這個(gè)模式定位錯(cuò)誤到行唇跨,并且可以定位第三方模塊的錯(cuò)誤并輸出。
本地服務(wù)器:devServer
前端開(kāi)發(fā)離不開(kāi)這個(gè)利器:本地服務(wù)器衬衬,可以配置devServer并配合插件實(shí)現(xiàn)修改代碼瀏覽器同步刷新买猖,實(shí)時(shí)查看修改效果。
WebpackDevServer
安裝:
npm i webpack-dev-server -D
修改package.json
"scripts": {
"server": "webpack-dev-server",
},
配置devServer:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
// entry:"./index.js",
entry:{
main:'./index.js'
},
output:{
filename:'bundle.js',
//絕對(duì)路徑
path:path.resolve(__dirname,'dist')
},
devServer:{
contentBase:'./dist', //服務(wù)器啟動(dòng)的目錄
open:true, //自動(dòng)打開(kāi)瀏覽器
proxy:{ //設(shè)置代理滋尉,可用于本地mock數(shù)據(jù)玉控,本地自己?jiǎn)?dòng)另外一個(gè)服務(wù)
"/api":{
target:"http://localhost:9092"
}
},
port:8083, //指定端口號(hào)
hot:true, //開(kāi)啟HMR(Hot Module Replacement)熱模塊替換,由于是webpack自帶的,所以要引入webpack 狮惜,監(jiān)控并更新js模塊的工作vue等框架自己做了高诺,否則需要自己手動(dòng)監(jiān)控
hotOnly:true
},
//不認(rèn)識(shí)的模塊(不是js)的配置
module:{
rules:[
{
test:/\.js$/,exclude:/node_modules/,
loader:"babel-loader",
options:{
// "presets":[["@babel/preset-env",{
// useBuiltIns:"usage"
// }]]
// plugins:[["@babel-plugin-transform-runtime",{
// "absolute"
// }]
}
},
{
test:/\.(jpe?g|png|gif)$/,
use:{
loader:"url-loader",
options:{
name:"[name]-[hash].[ext]",//[]表示占位符,name表示源文件的名字碾篡,ext是源文件的后綴虱而,還可以連接hash:[name]-[hash].[ext]
outputPath:"images/",
limit:2048,//當(dāng)webpack處理jpg模塊,會(huì)判斷體積是否在限制范圍之內(nèi)开泽,y限制在體積小于2048的
}
}
},
{
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',
// },
// },
'style-loader',
'css-loader',
'postcss-loader'
],
// [
// 'style-loader',
// 'css-loader',
// 'postcss-loader'
// ]
},
{
test:/\.scss$/,
use:[
'style-loader',//放在正確的打包位置
'css-loader',//打包合并css
'sass-loader',//處理sass薛窥,轉(zhuǎn)成css
'postcss-loader'
]
}
]
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'html模板',
template:"./index.html"
}),
// new MiniCssExtractPlugin({
// // Options similar to the same options in webpackOptions.output
// // both options are optional
// filename: '[name].css',
// chunkFilename: '[id].css',
// }),
new webpack.HotModuleReplacementPlugin()
],
devtool:'inline-source-map',//打包后的文件映射
mode:"development"http://去掉警告,開(kāi)發(fā)模式
}
執(zhí)行命令:
F:\front-end\webpack\webpack-demos>npm run server
> demo@1.0.0 server F:\front-end\webpack\webpack-demos
> webpack-dev-server
i ?wds?: Project is running at http://localhost:8083/
i ?wds?: webpack output is served from /
i ?wds?: Content not from webpack is served from ./dist
i ?wdm?: Hash: 06f7a27fe38a8a9b134a
Version: webpack 4.31.0
Time: 4661ms
Built at: 2019-05-20 22:24:21
Asset Size Chunks Chunk Names
bundle.js 367 KiB main [emitted] main
bundle.js.map 419 KiB main [emitted] main
images/pic-91d98190304e9e52a3b55d37b5f60397.jpg 8.89 KiB [emitted]
index.html 399 bytes [emitted]
main.css 240 bytes main [emitted] main
main.css.map 401 bytes main [emitted] main
Entrypoint main = main.css bundle.js main.css.map bundle.js.map
[0] multi (webpack)-dev-server/client?http://localhost:8083 (webpack)/hot/only-dev-server.js ./src/index.js 52 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/querystring-es3/index.js] 127 bytes {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8083] (webpack)-dev-server/client?http://localhost:8083 9.26 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
[./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
[./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {main} [built]
[./node_modules/webpack/hot/log.js] (webpack)/hot/log.js 1.11 KiB {main} [built]
[./node_modules/webpack/hot/only-dev-server.js] (webpack)/hot/only-dev-server.js 2.55 KiB {main} [built]
[./src/a.js] 73 bytes {main} [built]
[./src/index.js] 127 bytes {main} [built]
+ 17 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 521 bytes {0} [built]
[./node_modules/lodash/lodash.js] 527 KiB {0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/lib/loader.js!node_modules/postcss-loader/src/index.js!src/index.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src/index.js!./src/index.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./node_modules/postcss-loader/src!./src/index.scss 350 bytes {mini-css-extract-plugin} [built]
[./node_modules/css-loader/dist/runtime/api.js] 2.35 KiB {mini-css-extract-plugin} [built]
i ?wdm?: Compiled successfully.
自動(dòng)打開(kāi)瀏覽器: