webpack的幾個核心屬性
一饥臂、entry
指定入口文件占贫,webpack將根據(jù)入口文件來建立依賴關系從而進行打包構(gòu)建
entry分為單入口和多入口
單入口
entry: "./src/main.js",
多入口則以對象的形式
entry:{
index:"./src/main.js",
util:"./src/util/index.js",
...
}
二记劝、output
打包后的輸出
output: {
//所有文件的輸出路徑,__dirname: nodejs的變量,代表當前文件的文件夾目錄
path: path.resolve(__dirname, "dist"),//絕對路徑
//最終產(chǎn)物的文件名,可以指定 也可以使用[name]占位 這樣的話就會使用入口文件的名字大猛,多入口的時候必須以占位的形式
filename: "bundle.js",
//代碼塊的文件名
chunkFilename:"[name].chunk.js",
clean:true //自動刪除上次打包的結(jié)果
},
三、loader
webpack原生只支持解析js和json文件次哈,而在我們?nèi)粘i_發(fā)中除了這兩種文件還有其他的如 css less scss vue ts jsx 圖片 音視頻等等種類的文件胎署,loader就是用來解析這類文件將他們轉(zhuǎn)成webpack可解析的格式。loader是一個函數(shù) 接收源文件為參數(shù) 最終輸出一個webpack認識的東西窑滞。
下面是一些常見的loader
webpack本身是單線程的模式去打包構(gòu)建的 thread-loader可以讓webpack多進程打包 從而加快打包速度
loader語法
module: {
rules: [
//rules是一個數(shù)組里面可以配置多個loader琼牧,每個對象表示對一個loader的描述
{
//當前l(fā)oader對哪些文件生效 ,是一個正則匹配規(guī)則
test:'',
use:[]
//use里可以放置多個loader哀卫,
//執(zhí)行順序:從右到左或者從下到上巨坊,最末尾的loader最先執(zhí)行
}
]
}
四、Plugins
字面意思就是插件此改。通常一些loader沒辦法完成的事情都可以通過插件來完成趾撵,他主要用于對構(gòu)建產(chǎn)物的優(yōu)化,資源管理以及環(huán)境變量的注入共啃。
注:在整個構(gòu)建環(huán)節(jié)都可以去使用plugins占调,他作用于整個構(gòu)建過程,webpack會在構(gòu)建過程中不停的去廣播一些事件移剪,而plugins可以監(jiān)聽這些事件 從而進行相對應的處理
一些常見的plugins
五究珊、mode
webpack構(gòu)建模式,有三個可選值
development纵苛,production剿涮,none
設置不同的模式webpack會為你默認啟動一些優(yōu)化選項
了解完了以上幾個webpack的關鍵點之后 讓我們來做個小小的練習吧言津。
打包構(gòu)建一個vue應用。
基本配置
首先分析一下想要打包vue文件肯定是需要能夠解析vue的loader的取试,這里vue官方就給我們提供了這樣一個loader vue-loader悬槽,下面是官方文檔
https://vue-loader.vuejs.org/zh/guide/#vue-cli
根據(jù)官網(wǎng)的教程,可以得到以下的基本配置
const path = require('path');//nodejs的核心模塊瞬浓,專門用來處理路徑問題
const {VueLoaderPlugin} = require("vue-loader");
module.exports = {
//入口
entry: "./src/main.js",//相對路勁
//輸出
output: {
//所有文件的輸出路徑
//__dirname: nodejs的變量初婆,代表當前文件的文件夾目錄
path: path.resolve(__dirname, "dist"),//絕對路徑
//最終產(chǎn)物的文件名,可以指定 也可以使用[name]占位 這樣的話就會使用入口文件的名字瑟蜈,多入口的時候必須以占位的形式
filename: "bundle.js",
//代碼塊的文件名
// chunkFilename:"[name].chunk.js",
clean:true //自動刪除上次打包的結(jié)果
},
//加載器
module: {
rules: [
//loader的配置
{//通過babel-loader解析es6es7語法轉(zhuǎn)為es5
test:/\.js$/,
use:[
"babel-loader"
]
},
{
//通過vue-loader解析vue文件
test:/\.vue$/,
use:[
"vue-loader"
]
},
]
},
//插件
plugins: [
//plugin的配置
new VueLoaderPlugin()
],
//模式
mode: "development",
// devtool: "source-map"http://輸出源代碼
}
要注意可不是只用上一個vue-loader就行了哦烟逊,還需要配合VueLoaderPlugin插件才能完成對vue文件的打包渣窜。
接下來我們準備一個入口文件以及一個vue文件作為跟組件铺根。
//main.js
import Home from './vue/Home.vue'
import {createApp} from 'vue'
console.log(createApp,Home,123)
const app = createApp(Home).mount('#app')
console.log(app)
//Home.vue
<template>
<div>{{msg}}</div>
</template>
<script>
import {ref} from "vue";
export default {
name: "Home",
setup(){
const msg = ref('Home test')
return{
msg
}
}
}
</script>
<style scoped>
</style>
最后在準備一個html文件引入我們打包后的js文件即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>hello webpack</div>
<div id="app"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
注意引入的js的文件要么異步加載要么放在跟標簽后面,不然就會出現(xiàn)vue找不到跟標簽掛在元素了
這樣就完成了一個簡單的編譯打包vue文件的過程乔宿。
下面看看webpack是如何解析css和字體圖片文件的
首先 解析css 需要用到兩個loader位迂,一個是css-loader用來將css資源編譯成common.js的模塊到js中,第二個 style-loader將js中的css通過創(chuàng)建style標簽的形式添加到html中详瑞,以生效
{
test: /\.css$/, //只檢測.css文件
use: [ //執(zhí)行順序:從右到左或者從下到上掂林,最末尾的loader最先執(zhí)行
"style-loader",//將js中的css通過創(chuàng)建style標簽的形式添加到html中,以生效
"css-loader", //將css資源編譯成common.js的模塊到js中
]
},
這樣就可以完成對css的解析坝橡。
打包圖片資源和字體資源
使用到file-loader或者url-loader
//打包圖片資源
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
use:[
{
loader: "url-loader",
options: {
limit:10*1024
}
}
]
},
這里使用了url-loader泻帮,因為url-loader可以配置將小于多少大小的文件打包成base64,其內(nèi)部也是使用的file-loader计寇,只不過功能做了一些擴展锣杂。
PS:base64格式有利于減少http請求,但是如果文件過大 生成的base64也會特別大番宁。所以只適合讓小文件轉(zhuǎn)成base64格式
接下來去學習webpack中的文件監(jiān)聽元莫。
webpack提供了一個watch屬性當他為true的時候 文件改變就會自動觸發(fā)webpack的重新構(gòu)建,這和我們?nèi)粘i_發(fā)中的熱更新不同蝶押,他只是重新生成了構(gòu)建產(chǎn)物 但是并不會觸發(fā)瀏覽器的刷新踱蠢,所以還需要我們手動刷新瀏覽器。
也可以在webpack運行命令后面加上--watch開啟監(jiān)聽模式
"watch-build": "npx webpack --watch"
這樣執(zhí)行這個命令就可以開啟監(jiān)聽模式
原理分析
講到了文件監(jiān)聽那就不得不提webpack的熱更新了棋电。熱更新需要用到兩個包
webpack-dev-server和hot-module-replacement-plugin
以下簡稱WDS和HMR
熱更新的原理就是通過WDS啟動一個本地服務器茎截,此時構(gòu)建出的東西就不會輸出實際的文件了 而是會被放到本地的服務器上。然后HMR會在bundle里注入一個HMR runtime赶盔,這個東西是存在于瀏覽器端的企锌,他會和WDS建立一個scoket連接。當有文件被修改的時候會再次經(jīng)過webpack編譯招刨,webpack編譯后就會將最新的代碼發(fā)送至本地服務器上霎俩,本地服務器就會通知runtime runtime再去修改局部的變更哀军。(PS:所以我們在開發(fā)項目式 run dev是看不到dist文件夾的,如果想查看run dev生成了什么東西可以在本地服務端口后面拼上webpack-dev-server即可)打却。
文件指紋
在webpack中所謂的文件指紋其實就是指打包生成的文件名后的hash值杉适。那這個哈希值有什么用呢。在每次構(gòu)建項目的時候可能只是改動了一兩個文件柳击,如果文件名不發(fā)生變化猿推,那在瀏覽器上是會被緩存下來的,所以用戶沒辦法第一時間看到更新之后的資源捌肴。而如果我們給發(fā)生了變化的文件加上新的哈希值蹬叭,瀏覽器就會去下載最新的。而那些沒發(fā)生變化的則繼續(xù)沿用緩存里的状知。這樣可以極大的利用瀏覽器緩存秽五。
webpack里得哈希大概分為以上兩種,一般我們打包靜態(tài)文件會選擇Hash 而js則會選擇Chunkhash饥悴,css則是Contenthash坦喘。
用法也很簡單,直接在輸出得文件名里使用占位符即可西设。
output: {
//所有文件的輸出路徑
//__dirname: nodejs的變量瓣铣,代表當前文件的文件夾目錄
path: path.resolve(__dirname, "dist"),//絕對路徑
//最終產(chǎn)物的文件名,可以指定 也可以使用[name]占位 這樣的話就會使用入口文件的名字贷揽,多入口的時候必須以占位的形式
filename: "[name]_[chunkhash:8].js", 這里我們只取前八位就行棠笑,默認是32位
//代碼塊的文件名
// chunkFilename:"[name].chunk.js",
clean:true //自動刪除上次打包的結(jié)果
},
之前我們得css都是通過style-loader以style標簽得形式插入html,要使用哈希得話我們就得借助另一個loader禽绪,讓css以link標簽得方式引入蓖救。
npm install --save-dev mini-css-extract-plugin
插件文檔:https://webpack.docschina.org/plugins/mini-css-extract-plugin/
具體使用方法看文檔即可
//使用此插件將css分離出文件通過link引入
new MiniCssExtractPlugin({
filename:'[name]_[contenthash:8].css'
})
代碼壓縮
webpack是自帶了js代碼壓縮的,所以下面主要介紹一下css的壓縮和html的壓縮
css的壓縮主要用到的插件有optimize-css-assets-webpack-plugin以及CssMinimizerPlugin
兩者都是依賴于cssnano的丐一,所以要先安裝一下cssnano藻糖。
使用方法也很簡單,在plugins里new一下就行库车。
html的壓縮需要借助HtmlWebpackPlugin巨柒,配置一下minify對象即可
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'public/index.html',
inject: true,//配置所有js資源放置在html得哪個位置
minify:{
//壓縮配置
collapseWhitespace: true,
preserveLineBreaks:false,
html5:true,
minifyCSS:true,
minifyJS:true,
removeComments: true,
}
}),
以上就是webpack的基礎入門了