resolve配置
resolve: {
alias: {
// 減少依賴包所在文件的查詢時間
react: path.resolve(__dirname, "../../node_modules/react/dist/react.min.js"),
...
},
// 與alias類似,減少文件查找時間
modules:['./src/components'],
// 減少文件查找類別
extensions: ['.js', '.json']
}
DLL,預(yù)打包
// webpack.dll.js 單獨預(yù)打包,并且生成json文件
// json文件中包含“./node_modules/react/cjs/react.production.min.js”:{ id: 3, ...... }
// 模塊id等信息
entry: {
library: ["react", "react-dom"]
},
output: {
filename: "[name]_[hash].dll.js", // library.dll.js
path: path.join(process.cwd(), "dll/library"),
library: '[name]', // window.react == react.js
},
plugins: [
new webpack.DllPlugin({ // 生成對應(yīng)的json文件
name: "[name]",
path: path.join(process.cwd(), "dll/library/[name].json"),
})
]
// webpack.base.js
// webpack.DllReferencePlugin根據(jù)之前打包的json文件進行引用
plugins: [
new webpack.DllReferencePlugin({
manifest: path.join(process.cwd(), "/dll/library/library.json")
}),
]
緩存的使用
- css cache緩存
{
test: /\.js$/,
use: [
'babel-loader?cacheDirectory=true', // 二次構(gòu)建緩存開啟提升40%
'eslint-loader'
],
},
- plugins 模塊緩存
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
[
new HardSourceWebpackPlugin({})
]
并發(fā)處理
- js的并發(fā)處理loader,webpack之前happy-pack,webpack4自帶thread-loader
{
test: /.js$/,
use: [
'thread-loader'
],
},
- css的并發(fā)處理plugin
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
new MiniCssExtractPlugin({
filename: "[name]_[contenthash:8].css",////都提到build目錄下的css目錄中
chunkFilename: "[id][contenthash:8].css"
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require("cssnano"), // css 并發(fā)處理器
}),
splitChunks分包
optimization: {
splitChunks: {
// async:require.ensure()/import.then()引入的庫進行分離(默認),
// initial: 同步引入的庫進行分離,
// all:所有引入的庫進行分離(推薦)
chunks: 'all',
minSize: 0, // 抽離的公共包最小的大小,單位字節(jié)
maxSize: 0, // 最大的大小
minChunks: 1, // 資源使用的次數(shù)(在多個頁面使用到), 大于1, 最小使用次數(shù)
maxAsyncRequests: 5, // 并發(fā)請求的數(shù)量
maxInitialRequests: 3, // 入口文件做代碼分割最多能分成3個js文件
automaticNameDelimiter: '~', // 文件生成時的連接符
automaticNameMaxLength: 30, // 自動自動命名最大長度
name: true, //讓cacheGroups里設(shè)置的名字有效
cacheGroups: { //當打包同步代碼時,上面的參數(shù)生效
verder: {
name: "verder",
test: /[\\/]node_modules[\\/]/, //檢測引入的庫是否在node_modlues目錄下的
priority: -10, //值越大,優(yōu)先級越高.模塊先打包到優(yōu)先級高的組里
// filename: 'vendors.js'//把所有的庫都打包到一個叫vendors.js的文件里
},
commonUtils: {
name: "commonUtils",
test: /[\\/]src[\\/]utils[\\/]/,
priority: -9,
},
}
},
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
})
]
},
縮減包的體積/其它
- 動態(tài)兼容, polyfill-service,針對瀏覽器ua下發(fā)不同的polyfill文件
- 圖片的壓縮算法的原理:tinyPng: 將24位png轉(zhuǎn)化為更小索引的8位圖片,去除非必要的matadata信息
- devtool的選擇:
--------------使用———————————————— - eval 定位webpack后的代碼
- cheap-eval-source-map 進過loader轉(zhuǎn)化后的代碼
- cheap-module-eval-source-map 源代碼只能看行
- eval-source-map 源代碼
- cheap-source-map loader后無列信息源代碼
- cheap-module-source-map 后無列信息源代碼
- source-map 源代碼
- inline-source-map 源代碼
- hidden-source-map 源代碼,注釋的形式和原文件打包
sourcemap的主要原理:
{
version : 3, // 版本
file: "out.js", // 轉(zhuǎn)換后文件目錄
sourceRoot : "", // 轉(zhuǎn)換前的文件所在的目錄。如果與轉(zhuǎn)換前的文件在同一目錄,該項為空。
sources: ["foo.js", "bar.js"], // 轉(zhuǎn)換前的文件。該項是一個數(shù)組,表示可能存在多個文件合并
names: ["src", "maps", "are", "fun"], // 轉(zhuǎn)換前的變量名稱
mappings: "AAgBC,SAAQ,CAAEA" // 記錄位置信息的字符竄
}
- 主要原理在于mapping是如何實現(xiàn)的
- 位置對應(yīng)原理:
五位的字符長度(如上述mapping中: “AAgBC”)
[“轉(zhuǎn)換后的代碼的第幾列”,“哪個source文件”,“轉(zhuǎn)換之前第幾行”,“轉(zhuǎn)換之后第幾列”,“屬于names中的哪個變量”]
- 每一位上采用的是VLQ編碼
- VLQ編碼流程:
“16”(變量) -->
"10000"(二進制) -->
"100000"(>0補0) -->
"00001"+"00000"(按5位分割) -->
"100000"+"00000"(反轉(zhuǎn)) -->
“gB”(進行base64編碼)【得到“16”的最后編碼結(jié)果】
按需加載
使用import().then()或者require().ensure()
react下的異步組件
import React, { lazy, Suspense } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}