webpack:前端的構(gòu)建工具,由很多小工具構(gòu)建組合而成。靜態(tài)資源打包器,將前端的所有資源文件(js/css/json/img/less/...)都作為模塊進(jìn)行處理,這個(gè)處理過程叫打包。
為什么要用到webpack?
前端開發(fā)越來越復(fù)雜,越來越多的頁面擁有復(fù)雜的js代碼和一大堆的依賴包。有些還使用了基于js開發(fā)的語言,TypeScript,這種新語言很多瀏覽器還不能識別。還有像less這張預(yù)處理器,瀏覽器也不認(rèn)識,不能呈現(xiàn)css樣式,需要一種工具轉(zhuǎn)為css語法。還有比如在js文件中通過es6的import引入其它模塊,瀏覽器也不能識別import命令。
那為了讓瀏覽器能識別這些語法或者命令,需要構(gòu)建一個(gè)大工具,將這些小的模塊工具進(jìn)行處理,轉(zhuǎn)換成瀏覽器能認(rèn)識的語法。所以就出現(xiàn)了webpack這個(gè)構(gòu)建工具。
webpack打包流程:
把項(xiàng)目當(dāng)做一個(gè)整體——>找到入口文件index.js——>分析index.js中引入的項(xiàng)目結(jié)構(gòu),形成一個(gè)依賴關(guān)系樹狀圖——>根據(jù)依賴關(guān)系的先后順序引入對應(yīng)資源,形成chunk(代碼塊)——>
對chunk代碼塊處理(處理過程叫打包),比如將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能識別的文件。webpack只認(rèn)識js。
Plugins:執(zhí)行范圍更廣的任務(wù),打包優(yōu)化、文件壓縮等
Mode:分為開發(fā)者模式、生產(chǎn)者模式
webpack初體驗(yàn):
npm init要依賴Node.js的話,最好通過npm init初始化得到package.json文件。
npm i webpack webpack-cli -g:全局安裝webpack和webpack-cli兩個(gè)包。
webpack-cli是干嘛的?為什么要安裝這兩個(gè)包?
npm i webpack webpack-cli -D:將這兩個(gè)包添加到開發(fā)時(shí)依賴。
新建src文件夾和dist文件夾——>在src文件夾下新建index.js入口文件,在dist文件夾下新建index.html。(沒有index.html文件的情況下,可直接在命令行輸入node ./dist/budle.js查看輸出結(jié)果)
在index.js文件中執(zhí)行簡單的測試:
//運(yùn)行命令:
//- 開發(fā)環(huán)境:webpack ./src/index.js -o ./dist/bundle.js --mode=development
// -webpack會(huì)以index.js為入口文件進(jìn)行打包,打包后輸出bundle.js文件到dist文件夾下。整體打包環(huán)境是開發(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))
//測試json文件能不能打包
import hh from './data.json'
console.log(hh)
//測試css文件能不能打包——>報(bào)錯(cuò)
import './index.css'
在index.html中引入index.js
<script src='./bundle.js'></script>
執(zhí)行完打包命令后,查看index.html的控制臺,可以看到add()輸出的結(jié)果以及data.json的數(shù)據(jù)。但是打包index.css報(bào)錯(cuò),因?yàn)閣ebpack不能識別css文件。要能識別css文件,必須定義webpack.config.js配置文件:打包c(diǎn)ss文件必須在開發(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中通過__dirname動(dòng)態(tài)獲取絕對路徑,__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ì)被壓縮的,開發(fā)環(huán)境下不會(huì)
打包圖片資源(必須在開發(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格式的字符串,在頁面中的url顯示的就是base64格式的url
優(yōu)點(diǎn):減少圖片請求次數(shù)
缺點(diǎn):增大圖片體積
limit的值設(shè)為多大,根據(jù)項(xiàng)目使用的圖片大小來確定。
//如果圖片大小大于8kb,則要安裝npm install --save-dev file-loader,file-loader會(huì)把這個(gè)圖片打包到dist文件夾下
limit:8 * 1024,
// 給打包后的圖片重新命名
name:'img/[name].[hash:8].[ext]',
//使用html-loader存在的問題:因?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]'的說明。
img:所有圖片都打包到img文件夾下
name:獲取圖片原來的名字,放在該位置
hash:8:為了防止圖片名稱沖突,依然使用hash,但是我們只保留8位
ext:使用圖片原來的擴(kuò)展名
打包其它資源(開發(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