resolve配置
resolve: {
alias: {
// 减少依赖包所在文件的查询时间
react: path.resolve(__dirname, "../../node_modules/react/dist/react.min.js"),
...
},
// 与alias类似,减少文件查找时间
modules:['./src/components'],
// 减少文件查找类别
extensions: ['.js', '.json']
}
DLL,预打包
// webpack.dll.js 单独预打包,并且生成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({ // 生成对应的json文件
name: "[name]",
path: path.join(process.cwd(), "dll/library/[name].json"),
})
]
// webpack.base.js
// webpack.DllReferencePlugin根据之前打包的json文件进行引用
plugins: [
new webpack.DllReferencePlugin({
manifest: path.join(process.cwd(), "/dll/library/library.json")
}),
]
缓存的使用
- css cache缓存
{
test: /\.js$/,
use: [
'babel-loader?cacheDirectory=true', // 二次构建缓存开启提升40%
'eslint-loader'
],
},
- plugins 模块缓存
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
[
new HardSourceWebpackPlugin({})
]
并发处理
- js的并发处理loader,webpack之前happy-pack,webpack4自带thread-loader
{
test: /.js$/,
use: [
'thread-loader'
],
},
- css的并发处理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 并发处理器
}),
splitChunks分包
optimization: {
splitChunks: {
// async:require.ensure()/import.then()引入的库进行分离(默认),
// initial: 同步引入的库进行分离,
// all:所有引入的库进行分离(推荐)
chunks: 'all',
minSize: 0, // 抽离的公共包最小的大小,单位字节
maxSize: 0, // 最大的大小
minChunks: 1, // 资源使用的次数(在多个页面使用到), 大于1, 最小使用次数
maxAsyncRequests: 5, // 并发请求的数量
maxInitialRequests: 3, // 入口文件做代码分割最多能分成3个js文件
automaticNameDelimiter: '~', // 文件生成时的连接符
automaticNameMaxLength: 30, // 自动自动命名最大长度
name: true, //让cacheGroups里设置的名字有效
cacheGroups: { //当打包同步代码时,上面的参数生效
verder: {
name: "verder",
test: /[\\/]node_modules[\\/]/, //检测引入的库是否在node_modlues目录下的
priority: -10, //值越大,优先级越高.模块先打包到优先级高的组里
// filename: 'vendors.js'//把所有的库都打包到一个叫vendors.js的文件里
},
commonUtils: {
name: "commonUtils",
test: /[\\/]src[\\/]utils[\\/]/,
priority: -9,
},
}
},
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
})
]
},
缩减包的体积/其它
- 动态兼容, polyfill-service,针对浏览器ua下发不同的polyfill文件
- 图片的压缩算法的原理:tinyPng: 将24位png转化为更小索引的8位图片,去除非必要的matadata信息
- devtool的选择:
--------------使用———————————————— - eval 定位webpack后的代码
- cheap-eval-source-map 进过loader转化后的代码
- 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", // 转换后文件目录
sourceRoot : "", // 转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
sources: ["foo.js", "bar.js"], // 转换前的文件。该项是一个数组,表示可能存在多个文件合并
names: ["src", "maps", "are", "fun"], // 转换前的变量名称
mappings: "AAgBC,SAAQ,CAAEA" // 记录位置信息的字符窜
}
- 主要原理在于mapping是如何实现的
- 位置对应原理:
五位的字符长度(如上述mapping中: “AAgBC”)
[“转换后的代码的第几列”,“哪个source文件”,“转换之前第几行”,“转换之后第几列”,“属于names中的哪个变量”]
- 每一位上采用的是VLQ编码
- VLQ编码流程:
“16”(变量) -->
"10000"(二进制) -->
"100000"(>0补0) -->
"00001"+"00000"(按5位分割) -->
"100000"+"00000"(反转) -->
“gB”(进行base64编码)【得到“16”的最后编码结果】
按需加载
使用import().then()或者require().ensure()
react下的异步组件
import React, { lazy, Suspense } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
Loading...