一、Webpack簡介
Webpack是一種前端資源構(gòu)建工具占遥,一個(gè)靜態(tài)模塊打包器瓦胎。
在webpack 看來, 前端的所有資源文件(js/json/css/img/less/...)都會(huì)作為模塊處理。
它將根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析负芋,打包生成對(duì)應(yīng)的靜態(tài)資源(bundle)旧蛾。
1.1核心概念
Entry
入口指示W(wǎng)ebpack以哪個(gè)文件為入口起點(diǎn)開始打包蚜点,分析內(nèi)部依賴绍绘。
Output
輸出指示W(wǎng)ebpack打包后的資源bundles輸出到哪里去厂镇。
Loader
Loader讓W(xué)ebpack能夠去處理那些非js文件捺信。
Plugins
插件可以用于執(zhí)行范圍更廣的任務(wù)迄靠。從打包優(yōu)化和壓縮到重新定義環(huán)境中的變量等。
Mode
(1) development 能讓代碼本地調(diào)試運(yùn)行的環(huán)境
源代碼→webpack(打包吠式、自動(dòng)化)→bundle
(2) production 能讓代碼優(yōu)化上線運(yùn)行的環(huán)境(要做的事多特占,拖累開發(fā)環(huán)境的構(gòu)建速度是目,打包慢)
css→js(大,閃) 提取出css;壓縮萍倡;兼容...
1.2運(yùn)行指令:
開發(fā)環(huán)境:webpack .src/index.js -o ./build --mode=development
webpack會(huì)以 ./src/index.js 為入口文件開始打包列敲,然后輸出到 ./build/built.js,整體打包環(huán)境是開發(fā)環(huán)境
生產(chǎn)環(huán)境:webpack .src/index.js -o ./build --mode=production
- 結(jié)論:
- webpack能處理js/json資源戴而,不能處理css/img等其他資源凑术。
- 生產(chǎn)環(huán)境和開發(fā)環(huán)境將ES6模塊化編譯成瀏覽器能識(shí)別的模塊化。
- 生產(chǎn)環(huán)境比開發(fā)環(huán)境多一個(gè)壓縮js代碼所意。
二淮逊、配置
2.1 開發(fā)環(huán)境配置
2.1.1 打包樣式資源
webpack.config.js
/*
webpack的配置文件
作用:指示webpack干哪些活(當(dāng)運(yùn)行webpack指令時(shí)會(huì)加載里面的配置)
*/
// resolve用來拼接絕對(duì)路徑的方法
const { resolve } = require('path')
module.exports = {
// webpack配置
// 入口起點(diǎn)
entry: './src/index.js',
// 輸出
output: {
// 輸出文件名
filename: 'built.js',
// 輸出路徑
// __dirname 表示當(dāng)前文件目錄的絕對(duì)路徑
path: resolve(__dirname, 'build')
},
// loader配置
module: {
rules: [
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader
use: [
// use數(shù)組中l(wèi)oader執(zhí)行順序:從右到左,從下到上
// 創(chuàng)建style標(biāo)簽扶踊,將js中的樣式資源插入進(jìn)行,添加到head中生效
'style-loader',
// 將css文件變成commonjs模塊加載js中秧耗,里面的內(nèi)容是樣式字符串
'css-loader'
]
}
]
},
// plugins配置
plugins: [
],
// 模式
mode: 'development'
//mode: 'production'
}
2.1.2 打包html資源
webpack.config.js
/*
loader: 1. 下載 2. 使用
plugin: 1. 下載 2. 引入 3. 使用
*/
const { resolve } = require('path')
//引入plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: "./src/index.js",
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
]
},
plugins:[
// 功能:默認(rèn)創(chuàng)建一個(gè)空的html备籽,自動(dòng)引入打包輸出的所有資源
// 需要:需要有結(jié)構(gòu)的html文件
new HtmlWebpackPlugin({
// 復(fù)制'./src/index.html‘文件,并自動(dòng)引入打包輸出的所有資源
template: './src/index.html'
})
],
mode: 'development'
}
2.1.3 打包圖片資源
webpack.config.js
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build'),
publicPath: './'
},
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
// 處理圖片資源
{
// 問題:處理不了html中的圖片
test: /\.(JPG|png|gif)$/,
// 使用一個(gè)loader
// 下載url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb就會(huì)被base64處理
// 優(yōu)點(diǎn):減少請(qǐng)求數(shù)量(減輕服務(wù)器壓力)
// 缺點(diǎn):圖片體積變大(文件請(qǐng)求速度變慢)
limit: 8 * 1024,
// 問題:因?yàn)閡rl-loader默認(rèn)使用es6模塊化解析分井,而html-loader引入圖片是commonjs
// 解決:關(guān)閉url-loader的es6模塊化车猬,使用commonjs解析
esModule: false,
// 圖片重命名
// [hash:10]取圖片的hash前十位
// [ext]取文件原擴(kuò)展名
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 處理html文件的圖片(負(fù)責(zé)引入圖片,從而能被url-loader處理)
loader: 'html-withimg-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
2.1.4 打包其他資源
webpack.config.js
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
// 打包其他資源
{
// 排除css/js/html資源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
2.1.5 開發(fā)服務(wù)器devServer
用來自動(dòng)化(自動(dòng)編譯尺锚,自動(dòng)打開瀏覽器珠闰,自動(dòng)刷新瀏覽器。缩麸。铸磅。)
特點(diǎn):只會(huì)在內(nèi)存中編譯打包,不會(huì)有任何輸出
devServer: {
contentBase: resolve(__dirname, 'build'),
// 啟動(dòng)gzip壓縮
compress: true,
port: 3000,
// 自動(dòng)打開瀏覽器
open: true
}
2.2 生產(chǎn)環(huán)境配置
2.2.1 提取css成單獨(dú)文件
MiniCssExtractPlugin
module: {
rules: [
{
test: /\.css$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader'
]
}
],
},
2.2.2 css兼容性處理
postcss --> postcss-loader postcss-preset-env
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { resolve } = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 設(shè)置nodejs環(huán)境變量
// process.env.NODE_ENV = 'development'
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build'),
publicPath: '/'
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
/*
css兼容性處理:postcss --> post-loader postcss-preset
幫postcss找到package.json中的browserslist里面的配置杭朱,通過配置加載指定的css兼容性樣式
"browserslist": {
// 開發(fā)環(huán)境 --> 設(shè)置環(huán)境變量:process.env.NODE_ENV = development
"development": [
"last 1 chrome version"
],
// 生產(chǎn)環(huán)境(默認(rèn))
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
// 1. 使用loader的默認(rèn)配置
// 'postcss-loader',
// 2. 修改loader的配置
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [ require('postcss-preset-env')() ]
}
}
}
]
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
})
],
mode: 'development'
}
2.2.3 壓縮css
CssMinizerWebpackPlugin插件
2.2.4 js語法檢查
- 語法檢查: eslint-loader eslint
- 注意:只檢查自己的代碼阅仔,第三方庫不檢查
exclude: /node_modules/, - 設(shè)置檢查規(guī)則:
package.json中eslintConfig中設(shè)置
aribnb --> eslint-config-airbnb-base eslint eslint-plugin-import
package.json中的配置
"eslintConfig": {
"extends": "airbnb-base"
}
webpack.config.js
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// 自動(dòng)修復(fù)
fix: true,
},
},
],
},
// 下一行eslint所有規(guī)則都失效
// eslint-disable-next-line
2.2.5 js兼容性處理
基本js兼容性處理
babel-loader @babel/preset-env
問題:只能轉(zhuǎn)換基本語法,如promse等不能轉(zhuǎn)換全部js兼容性處理
@babel/polyfill(非插件弧械,只需引入)
問題:只需解決部分兼容性問題八酒,但將所有兼容性代碼引入,體積過大按需加載兼容性處理
core-js
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 預(yù)設(shè):指示babel做怎么樣的兼容性處理
// 1. 基本js兼容性處理
// presets: [
// '@babel/preset-env'
// ]
// 3. 按需加載兼容性處理
presets: [
[
'@babel/preset-env',
{
// 按需加載
useBuiltIns: 'usage',
corejs: {
// 指定corejs版本
version: 2
},
// 指定兼容性做到哪個(gè)版本瀏覽器
targets: {
chrome: '60',
firefox: '50',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
],
},
正常來講刃唐,一個(gè)文件只能被一個(gè)loader處理羞迷,當(dāng)一個(gè)文件要被多個(gè)loader處理時(shí),那么一定要知道loader執(zhí)行的先后順序画饥,先執(zhí)行eslint再執(zhí)行babel
enforce: 'pre'
2.2.6 html壓縮
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注釋
removeComments: true
}
}),
],
2.2.7 生產(chǎn)環(huán)境基本配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
// 定義node.js環(huán)境變量 決定使用browserlist的哪個(gè)環(huán)境
process.env.NODE_ENV = 'production';
// 服用css配置
const commonCssLoader = [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
// 兼容性處理
{
loader: 'postcss-loader',
// 修改默認(rèn)配置
options: {
postcssOptions: {
plugins: [ require('postcss-preset-env')() ]
}
}
// 還需在package.json中定義browserslist
// "browserslist": {
// "development": [
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version"
// ],
// "production": [
// ">0.2%",
// "not dead",
// "not op_mini all"
// ]
// },
},
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
// css
{
test: /\.css$/,
use: [...commonCssLoader],
},
// less
{
test: /\.less$/,
ues: [...commonCssLoader, 'less-loader'],
},
/*
正常來講衔瓮,一個(gè)文件只能被一個(gè)loader處理
當(dāng)一個(gè)文件要被多個(gè)loader處理,那么一定要知道loader執(zhí)行的先后順序
先執(zhí)行eslint再執(zhí)行babel
*/
// js語法檢查
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true,
},
// package.json
// "eslintConfig": {
// "extends": "airbnb-base"
// }
},
// js兼容性處理
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 2,
},
targets: {
chrome: '60',
firefox: '59',
},
},
],
],
},
},
// 圖片
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'img',
esModule: false,
},
},
// html圖片
{
test: /\.html/,
loader: 'html-loader',
},
// 其他文件
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media',
},
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css',
}),
new CssMinimizerWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
},
}),
],
// js壓縮
mode: 'production',
};
三抖甘、webpack性能優(yōu)化
3.1 開發(fā)環(huán)境性能優(yōu)化
- 優(yōu)化打包構(gòu)建速度
- 優(yōu)化代碼調(diào)試
HMR 功能
- 作用:一個(gè)模塊發(fā)生變化热鞍,只會(huì)重新打包這一個(gè)模塊(而不是所有模塊)
- 注意:
① 樣式文件可以使用HMR功能,因?yàn)閟tyle-loader內(nèi)部實(shí)現(xiàn)了
② html文件默認(rèn)不能使用HMR功能(不用做HMR功能)
③ js文件默認(rèn)不能使用HMR功能,需要修改js代碼(webpack配置target: 'web')
if (module.hot) {
// 一旦module.hot為true薇宠,說明開啟了HMR功能偷办,需要讓HMR代碼功能生效
module.hot.accept('./print.js', function () {
// 方法監(jiān)聽print.js文件的變化,一旦發(fā)生變化澄港,其他默認(rèn)不會(huì)重新打包構(gòu)建
// 會(huì)執(zhí)行后面的回調(diào)函數(shù)
print()
})
}
source-map
一種提供源代碼到構(gòu)建后代碼的映射技術(shù)(如果構(gòu)建后代碼出錯(cuò)了椒涯,通過映射可以追蹤到源代碼作物)
/* webpack.config.js */
devtool: 'source-map'
參數(shù) | 內(nèi)/外 | 作用 |
---|---|---|
source-map | 外部生成source-map文件 | 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置 |
inline-source-map | 內(nèi)嵌source-map,構(gòu)建速度快 | 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置 |
hidden-source-map | 外部生成source-map文件 | 錯(cuò)誤代碼原因回梧,但是沒有錯(cuò)誤位置废岂,不能追蹤源代碼錯(cuò)誤,只能提示到構(gòu)建后代碼位置 |
eval-source-map | 內(nèi)嵌(每一個(gè)文件都生成一個(gè)source-map) | 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置 |
nosources-source-map | 外部 | 錯(cuò)誤代碼準(zhǔn)確信息漂辐,但是沒有任何源代碼信息 |
cheap-source-map | 外部 | 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置泪喊,只能精確到行 |
cheap-module-source-map | 外部 | 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置,會(huì)將loader的source map加入 |
-
開發(fā)環(huán)境:速度快髓涯、調(diào)試友好
- 速度快(eval>inline>cheap>...)
eval-cheap-source-map
eval-source-map(推薦) - 調(diào)試更友好
source-map
cheap-module-source-map
cheap-source-map
- 速度快(eval>inline>cheap>...)
-
生產(chǎn)環(huán)境:源代碼要不要隱藏袒啼?調(diào)試要不要更友好?
內(nèi)嵌會(huì)讓代碼體積變大纬纪,所以生產(chǎn)環(huán)境不用內(nèi)嵌
nosources-source-map 全部隱藏
hidden-source-map 只隱藏源代碼source-map/cheap-module-source-map (推薦)
3.2 生產(chǎn)環(huán)境性能優(yōu)化
3.2.1 優(yōu)化打包構(gòu)建速度
oneOf
oneOf:匹配到 loader 后就不再向后進(jìn)行匹配蚓再,優(yōu)化生產(chǎn)環(huán)境的打包構(gòu)建速度
module: {
rules: [
{
// js 語法檢查
test: /\.js$/,
exclude: /node_modules/,
// 優(yōu)先執(zhí)行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
// oneOf 優(yōu)化生產(chǎn)環(huán)境的打包構(gòu)建速度
// 以下loader只會(huì)匹配一個(gè)(匹配到了后就不會(huì)再往下匹配了)
// 注意:不能有兩個(gè)配置處理同一種類型文件(所以把eslint-loader提取出去放外面)
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
{
// js 兼容性處理
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {version: 3},
targets: {
chrome: '60',
firefox: '50'
}
}
]
]
}
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
}
]
},
緩存
- babel緩存
配置cacheDirectory: true
讓第二次打包構(gòu)建速度更快 - 文件資源緩存
- hash:每次webpack打包時(shí)會(huì)生成一個(gè)唯一的hash值
問題:因?yàn)閖s和css同時(shí)使用一個(gè)hash值如果重新打包會(huì)導(dǎo)致所有緩存失效。 - chunkhash:根據(jù)chunk生成的hash值包各,如果打包來源于同一個(gè)chunk摘仅,那么hash值就一樣
問題:js和css的hash值還是一樣,因?yàn)閏ss是在js中被引入的问畅,同屬一個(gè)chunk - contenthash:根據(jù)文件的內(nèi)容生成hash值
讓代碼上線運(yùn)行緩存更好使用
- hash:每次webpack打包時(shí)會(huì)生成一個(gè)唯一的hash值
多進(jìn)程打包
優(yōu)化打包速度
問題: 進(jìn)程啟動(dòng)大概為600ms,進(jìn)程通信也有開銷.
只有打包工作消耗時(shí)間比較長,才需要多進(jìn)程打包
// 再某個(gè)loader后(數(shù)組前)使用thread-loader可對(duì)相應(yīng)loader進(jìn)行多進(jìn)程打包
/*
多進(jìn)程打包
*/
{
loader: "thread-loader",
options: {
workers: 2 // 進(jìn)程數(shù)
}
},
externals
防止將某些方法打包到最終輸出的bundle中
// webpack.config.js中配置
externals: {
// 忽略庫名 npm包名
// 拒絕jquery被打包
jquery: 'jQuery'
}
再將需要的包在html中引入
dll
動(dòng)態(tài)鏈接庫
類似externals,指示哪些庫不需要打包,不同在于dll會(huì)將某些庫進(jìn)行單獨(dú)打包成chunk.
- webpack.dll.js 配置:(將 jquery 單獨(dú)打包)
/*
node_modules的庫會(huì)打包到一起娃属,但是很多庫的時(shí)候打包輸出的js文件就太大了
使用dll技術(shù),對(duì)某些庫(第三方庫:jquery护姆、react矾端、vue...)進(jìn)行單獨(dú)打包
當(dāng)運(yùn)行webpack時(shí),默認(rèn)查找webpack.config.js配置文件
需求:需要運(yùn)行webpack.dll.js文件
--> webpack --config webpack.dll.js(運(yùn)行這個(gè)指令表示以這個(gè)配置文件打包)
*/
const { resolve } = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 最終打包生成的[name] --> jquery
// ['jquery] --> 要打包的庫是jquery
jquery: ['jquery']
},
output: {
// 輸出出口指定
filename: '[name].js', // name就是jquery
path: resolve(__dirname, 'dll'), // 打包到dll目錄下
library: '[name]_[hash]', // 打包的庫里面向外暴露出去的內(nèi)容叫什么名字
},
plugins: [
// 打包生成一個(gè)manifest.json --> 提供jquery的映射關(guān)系(告訴webpack:jquery之后不需要再打包和暴露內(nèi)容的名稱)
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射庫的暴露的內(nèi)容名稱
path: resolve(__dirname, 'dll/manifest.json') // 輸出文件路徑
})
],
mode: 'production'
};
- webpack.config.js 配置:(告訴 webpack 不需要再打包 jquery卵皂,并將之前打包好的 jquery 跟其他打包好的資源一同輸出到 build 目錄下)
// 引入插件
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
// plugins中配置:
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 告訴webpack哪些庫不參與打包秩铆,同時(shí)使用時(shí)的名稱也得變
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, 'dll/manifest.json')
}),
// 將某個(gè)文件打包輸出到build目錄下,并在html中自動(dòng)引入該資源
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
],
3.2.2 優(yōu)化代碼運(yùn)行性能
tree shaking
去除無用代碼灯变,減少打包體積
-
前提
- 必須使用ES6模塊化
- production環(huán)境
在package.json中配置
"sideEffects": false 所有代碼都沒有副作用(都可以進(jìn)行tree shaking)
問題:可能會(huì)把css/@babel/polyfill 文件干掉
解決:"sideEffects": ["*.css"]
代碼分割 code split
打包成一個(gè)代碼體積大殴玛,需要分隔開
方法
- 多入口
多個(gè)entry - splitChunks
可以將node_modules中的代碼單獨(dú)打包成一個(gè)chunk最終輸出(比如多入口文件中有重復(fù)的依賴,使用該方法單獨(dú)加載依賴避免重復(fù)加載)
optimization: {
splitChunks: {
chunks: 'all'
}
},
- 通過js代碼讓某個(gè)文件單獨(dú)打包成一個(gè)chunk(常用)
import動(dòng)態(tài)導(dǎo)入語法添祸,能將某個(gè)文件單獨(dú)打包
import(/* webpackChunkName: 'test' */'./test')
.then(({ mul, count }) => {
console.log(mul(2, 5));
})
.catch(() => {
console.log('err');
})
懶加載
// 懶加載
import(/* webpackChunkName: 'test', webpackPrefetch: true */'.test')
.then(({ mul })=> {
console.log(mul(4, 6));
})
正常加載:可以認(rèn)為是并行加載(同時(shí)加載多個(gè)文件)
懶加載:文件需要用時(shí)加載
預(yù)加載webpackPrefetch:會(huì)在使用之前提前加載js文件滚粟,等其他資源加載完畢空閑時(shí)加載該資源
PWA
漸進(jìn)式網(wǎng)絡(luò)開發(fā)應(yīng)用程序(離線可訪問)
workbox --> workbox-webpack-plugin
// webpack.config.js插件
// PWA
new WorkboxWebpackPlugin.GenerateSW({
// 1. 幫助serviceworker快速啟動(dòng)
// 2. 刪除舊的serviceworker
// 生成一個(gè)serviceworker配置文件
clientsClaim: true,
skipWaiting: true
})
// js文件配置
/*
問題1: eslint不認(rèn)識(shí)window,navigator全局變量
解決: 需要修改package.json中eslintConfig的配置
"env": {
"browser": true // 支持瀏覽器端全局變量
}
問題2: sw代碼必須運(yùn)行在服務(wù)器上
*/
// 注冊(cè)serviceworker
// 處理兼容性問題
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(() => {
console.log('success');
}).catch(() => {
console.log('err');
})
})
}