webpack:前端的構(gòu)建工具弧腥,由很多小工具構(gòu)建組合而成。靜態(tài)資源打包器,將前端的所有資源文件(js/css/json/img/less/...)都作為模塊進(jìn)行處理孤页,這個(gè)處理過(guò)程叫打包。
為什么要用到webpack涩馆?
前端開(kāi)發(fā)越來(lái)越復(fù)雜行施,越來(lái)越多的頁(yè)面擁有復(fù)雜的js代碼和一大堆的依賴(lài)包。有些還使用了基于js開(kāi)發(fā)的語(yǔ)言魂那,TypeScript蛾号,這種新語(yǔ)言很多瀏覽器還不能識(shí)別。還有像less這張預(yù)處理器涯雅,瀏覽器也不認(rèn)識(shí)鲜结,不能呈現(xiàn)css樣式,需要一種工具轉(zhuǎn)為css語(yǔ)法活逆。還有比如在js文件中通過(guò)es6的import引入其它模塊精刷,瀏覽器也不能識(shí)別import命令。
那為了讓瀏覽器能識(shí)別這些語(yǔ)法或者命令蔗候,需要構(gòu)建一個(gè)大工具怒允,將這些小的模塊工具進(jìn)行處理,轉(zhuǎn)換成瀏覽器能認(rèn)識(shí)的語(yǔ)法锈遥。所以就出現(xiàn)了webpack這個(gè)構(gòu)建工具纫事。
webpack打包流程:
把項(xiàng)目當(dāng)做一個(gè)整體——>找到入口文件index.js——>分析index.js中引入的項(xiàng)目結(jié)構(gòu),形成一個(gè)依賴(lài)關(guān)系樹(shù)狀圖——>根據(jù)依賴(lài)關(guān)系的先后順序引入對(duì)應(yīng)資源所灸,形成chunk(代碼塊)——>
對(duì)chunk代碼塊處理(處理過(guò)程叫打包)丽惶,比如將less文件編譯成css文件,將es6編譯成es5——>打包結(jié)束后爬立,輸出一個(gè)名為bundle.js的文件
webpack的五個(gè)核心概念:
Entry:指示webpack以哪個(gè)入口文件打包钾唬。
Output:指示webpack打包后的資源輸出到哪里,以及如何命名。
Loader:處理非js文件知纷,比如把scss/less轉(zhuǎn)為css壤圃、es6轉(zhuǎn)為es5、Typescript轉(zhuǎn)為es5琅轧、img圖片等處理成webpack能識(shí)別的文件伍绳。webpack只認(rèn)識(shí)js。
Plugins:執(zhí)行范圍更廣的任務(wù)乍桂,打包優(yōu)化冲杀、文件壓縮等
Mode:分為開(kāi)發(fā)者模式、生產(chǎn)者模式
webpack初體驗(yàn):
npm init
要依賴(lài)Node.js的話(huà)睹酌,最好通過(guò)npm init初始化得到package.json文件权谁。
npm i webpack webpack-cli -g
:全局安裝webpack和webpack-cli兩個(gè)包。
webpack-cli是干嘛的憋沿?為什么要安裝這兩個(gè)包旺芽?
npm i webpack webpack-cli -D
:將這兩個(gè)包添加到開(kāi)發(fā)時(shí)依賴(lài)。
新建src文件夾和dist文件夾——>在src文件夾下新建index.js入口文件辐啄,在dist文件夾下新建index.html采章。(沒(méi)有index.html文件的情況下,可直接在命令行輸入node ./dist/budle.js查看輸出結(jié)果)
在index.js文件中執(zhí)行簡(jiǎn)單的測(cè)試:
//運(yùn)行命令:
//- 開(kāi)發(fā)環(huán)境:webpack ./src/index.js -o ./dist/bundle.js --mode=development
// -webpack會(huì)以index.js為入口文件進(jìn)行打包壶辜,打包后輸出bundle.js文件到dist文件夾下悯舟。整體打包環(huán)境是開(kāi)發(fā)環(huán)境
//- 生產(chǎn)環(huán)境:webpack ./src/index.js -o ./dist/bundle.js --mode=production
// -webpack會(huì)以index.js為入口文件進(jìn)行打包,打包后輸出到dist文件夾下的bundle.js文件砸民。整體打包環(huán)境是生產(chǎn)環(huán)境抵怎,在生產(chǎn)環(huán)境下bundle.js內(nèi)的代碼會(huì)被壓縮。
function add(x,y){
return x + y
}
console.log(add(2,2))
//測(cè)試json文件能不能打包
import hh from './data.json'
console.log(hh)
//測(cè)試css文件能不能打包——>報(bào)錯(cuò)
import './index.css'
在index.html中引入index.js
<script src='./bundle.js'></script>
執(zhí)行完打包命令后岭参,查看index.html的控制臺(tái)反惕,可以看到add()輸出的結(jié)果以及data.json的數(shù)據(jù)。但是打包index.css報(bào)錯(cuò)演侯,因?yàn)閣ebpack不能識(shí)別css文件承璃。要能識(shí)別css文件,必須定義webpack.config.js配置文件:打包c(diǎn)ss文件必須在開(kāi)發(fā)環(huán)境下
//所有的構(gòu)建工具都是基于Node.js構(gòu)建的蚌本,所以它們都遵循commonJS規(guī)范。
// 引入node中的path核心模塊
const path = require("path")
module.exports = {
//入口起點(diǎn)
entry:"./src/main.js",
output:{
//在node中通過(guò)__dirname動(dòng)態(tài)獲取絕對(duì)路徑隘梨,__dirname是Node.js中的變量
path:path.resolve(__dirname,'dist'),
//輸出文件
filename:"bundle.js"
},
//模塊的配置
module:{
rules: [
{
test: /\.css$/,
//css-loader:將css文件變成commonJS模塊加載到JS文件中程癌,里面的內(nèi)容是樣式的字符串
//style-loader:創(chuàng)建style標(biāo)簽,將js中的樣式字符串添加到標(biāo)簽內(nèi)轴猎,再將style標(biāo)簽插入到head標(biāo)簽中
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
//less-loader:將less文件編譯成css文件
//css-loader:將css文件變成commonJS模塊加載到JS文件中嵌莉,里面的內(nèi)容是樣式的字符串
//style-loader:創(chuàng)建style標(biāo)簽,將js中的樣式字符串添加到標(biāo)簽內(nèi)捻脖,再將style標(biāo)簽插入到head標(biāo)簽中
use: [ 'style-loader', 'css-loader' ,'less-loader']
}
]
}
//插件配置
Plugins:{
}
//模式配置(二選一)
mode:"development"
//mode:"production"
{
配置好后锐峭,安裝css-loader中鼠、style-loader兩個(gè)包钻蔑。
npm install css-loader --save-dev
npm install style-loader --save-dev
打包less文件枉长,還需額外下載less-loader玖媚、less兩個(gè)包严望。
npm install less-loader --save-dev
npm install less --save-dev
打包HTML資源
//插件配置
//(1.先下載(npm i html-webpack-plugin -D) 2.引入(const HtmlWebpackPlugin = require('html-webpack-plugin')) 3.使用)
plugins:[
//功能:默認(rèn)會(huì)創(chuàng)建一個(gè)空的html文件努隙,自動(dòng)引入打包后輸出的資源
//需求:生成的空html文件能保留./src/index.html文件內(nèi)的內(nèi)容
new HtmlWebpackPlugin({
template:'./src/index.html'
})
],
mode:'development' //注意轮听,在生產(chǎn)環(huán)境下剥哑,html文件打包后會(huì)被壓縮的掠拳,開(kāi)發(fā)環(huán)境下不會(huì)
打包圖片資源(必須在開(kāi)發(fā)環(huán)境下打包蚕涤,生產(chǎn)環(huán)境打包不生效)
分兩種情況:第一種是打包background:url(...)中的背景圖片筐赔,第二種是打包HTML中<img>標(biāo)簽內(nèi)的圖片。
//在module/rules/下配置:
//第一種情況:
{
test:/'\.(jpg|png|gif|jpeg)$'/,
use:[
//需要安裝url-loader揖铜、file-loader
{
loader:'url-loader',
options:{
//如果要顯示的圖片大小小于8kb(8192),則會(huì)將圖片轉(zhuǎn)為base64格式的字符串,在頁(yè)面中的url顯示的就是base64格式的url
優(yōu)點(diǎn):減少圖片請(qǐng)求次數(shù)
缺點(diǎn):增大圖片體積
limit的值設(shè)為多大茴丰,根據(jù)項(xiàng)目使用的圖片大小來(lái)確定。
//如果圖片大小大于8kb,則要安裝npm install --save-dev file-loader天吓,file-loader會(huì)把這個(gè)圖片打包到dist文件夾下
limit:8 * 1024,
// 給打包后的圖片重新命名
name:'img/[name].[hash:8].[ext]'贿肩,
//使用html-loader存在的問(wèn)題:因?yàn)閔tml-loader是遵循commonJS編譯圖片的,url-loader默認(rèn)是使用es6模塊化解析圖片的
//所以導(dǎo)致解析出的圖片的src='[object Module]',咋辦
//設(shè)置esModule:false
esModule:false
}
}
]
},
//第二種情況:
{
test:/\.html$/,
//html-loader:處理html中<img>標(biāo)簽引入的圖片,然后由url-loader解析
//需要安裝html-loader
loader:'html-loader'
}
關(guān)于name:'img/[name].[hash:8].[ext]'的說(shuō)明失仁。
img:所有圖片都打包到img文件夾下
name:獲取圖片原來(lái)的名字尸曼,放在該位置
hash:8:為了防止圖片名稱(chēng)沖突,依然使用hash萄焦,但是我們只保留8位
ext:使用圖片原來(lái)的擴(kuò)展名
打包其它資源(開(kāi)發(fā)環(huán)境下打包)
除css/js/html文件外的其它資源控轿,比如字體圖標(biāo)。
{
exclude:/\.(css|js|html|less|jpg|png|jpeg|gif)$/,//打包其它資源
use:[
{
loader:'file-loader',
options:{
name:'other/[hash:8].[ext]'
}
}
]
}
報(bào)錯(cuò):Refusing to install package with name "webpack" under a package
原因:npm init初始化的時(shí)候把包的名字設(shè)置成了webpack拂封,導(dǎo)致和webpack這個(gè)包的名字一樣茬射,報(bào)錯(cuò)。所以初始化的時(shí)候不要命名成webpack冒签。
https://www.bilibili.com/video/BV1e7411j7T5?p=2