# webpack 静态模块化打包工具
## 基础理解 module chunk bundle
- module: 打包前, 各个源码文件,webpack中一切皆模块(js less ....)
- chunk: 打包中, 在对模块进行依赖分析时,代码分割出来的代码块
- bundle: 打包后,webpack打包后输出的文件
## 基础配置
### entry :入口 为webpack指定一个或多个文件入口,从这个文件(index.js)开始逐层分析模块依赖,构建依赖树,
### output:出口 为打包后的文件指定输出的文件名和文件存放路径(dist) {path,filename} 配置clean清除上一次打包文件
### loader: 加载器 因为webpack只能识别js5以下和json文件,loader可以将所有类型的文件转换为webpack能够处理的模块
- 执行顺序:从右往左(从下往上)
#### 常用loader:
样式
style-loader 将样式模块导出的内容以往 <head> 中注入多个 <style> 的形式,添加到 DOM 中
css-loader 加载 CSS 文件并解析 @import 的 CSS 文件,将 url() 处理成 require() 请求,最终返回 CSS 代码
less-loader 加载并编译 LESS 文件
sass-loader 加载并编译 SASS/SCSS 文件
postcss-loader 使用 PostCSS 加载并转换 CSS/SSS 文件
stylus-loader 加载并编译 Stylus 文件
语法转换
babel-loader 使用 Babel 加载 ES2015+ 代码并将其转换为 ES5
ts-loader 像加载 JavaScript 一样加载 TypeScript 2.0+
文件
url-loader与 file-loader 类似,但当文件 size 小于设置的 limit 值,会返回 data URL
file-loader 将文件保存至输出文件夹中并返回 URL (默认是是绝对路径,可以 outputPath 和 publicPath 通过配置成相对路径)
### plugin: 插件 解决loader无法实现的功能,对webpack进行扩展
#### 常用plugin:
html-webpack-plugin: 该插件能够自动生成一个index.html文件(可以指定模板来生成),还能够将打包的js文件,自动通过scripts标签插入到body中。
js压缩的plugin :uglifyjs-webpack-plugin
mini-css-extract-plugin: 提取css代码放入一个文件中
optimize-css-assets-webpack-plugin:这个从名称上实际上可以看出端倪,这个就是一个用于优化css资源的插件。
webpack-parallel-uglify-plugin: 多进程执行代码压缩,提升构建速度
clean-webpack-plugin: 目录清理
## 高级概念
### SourceMap 源代码文件资源映射,方便调试
### HMR(HotModuleReplacement): 热替换,修改代码保存后webpack自动对代码重新打包发送到浏览器(自动刷新)
if (module.hot) { //判断是否有热加载
module.hot.accept('./hmrTest.js', function() { //热加载的模块路径
})
}
### 提升性能(打包速度)
#### OneOf: loader通过正则表达匹配文件,每个文件都会过滤一遍,配置后当某一文件匹配上loader后,就不会继续向下取匹配其他loader
语法module: {rules:{OneOf:[ {test:/\.css$/,use:['css-loader'] } ] } };
#### Include Exclude : 为loader指定(排除)某一文件夹去匹配
语法{test:/\.css&/,Include:/src/css/,use:['css-loader']};
#### babel-loader(cache): 缓存之前的Eslint检查和babel编译的结果,webpack打包速度慢大部分是js文件,js文件每次打包都会经过Eslint检查和babel编译
语法use: {
loader: "babel-loader",
options: {
cacheDirectory: true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩提高打包的速度(不压缩只会占用电脑内存,线上项目不会读取缓存代码文件,打包后可以在node_modules可以看到.cache\babel-loader文件)
// presets: ["@babel/preset-env"],配置可以写到babel.config.js文件中好维护
},
#### Thead: 多进程打包 我们启动进程的数量就是我们 CPU 的核数。
语法 获取 CPU 的核数
const os = require("os"); // nodejs核心模块,直接使用
const threads = os.cpus().length; // cpu核数
use:[
{
loader: "thread-loader", //开启多进程
options: {
workers: threads, //开启个进程数量
},
]
#### TreeShaking 在打包时移除掉javascript上下文中无用的代码,从而优化打包的结果。在webpack5在打包模式为production时,默认开启 tree-shaking。webpack允许我们声明一个模块有无副作用。如果所有模块都是纯正的,即都没有副作用,我们可以设置"sideEffects": false
#### babel 为编译的每个文件都插入了辅助代码,使代码体积过大
@babel/plugin-transform-runtime: 禁用了 Babel 自动对每个文件的 runtime 注入,而是引入
@babel/plugin-transform-runtime 并且使所有辅助代码从这里引用
语法 {
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
},
},
},
#### image-minimizer-webpack-plugin: 用来压缩图片的插件
语法 plugins: [
// 压缩图片
new ImageMinimizerPlugin({ minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
]
}
}]
#### CodeSpilt 代码分割:将打包生成的文件进行分割,生成多个 js 文件。按需加载:需要哪个文件就加载哪个文件。
语法 optimization: {
// 代码分割配置
splitChunks: {
chunks: "all", // 对所有模块都进行分割
// 修改配置
cacheGroups: {
// 组,哪些模块要打包到一个组
// defaultVendors: { // 组名
// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
// priority: -10, // 权重(越大越高)
// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
// },
default: {
// 其他没有写的配置会使用上面的默认值
minSize: 0, // 我们定义的文件体积太小了,所以要改打包的最小文件体积
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
}
}
#### 按需加载:需要哪个文件就加载哪个文件。
divElement.onclick = function(){
import('./main').then(res=>{//成功 res.default()暴露函数})
.catch(err=>{ //失败})
}
#### 模块命名
import(/* */)
output:[chunkFilename:'[name].js'] //打包输出其他文件命名
#### Preloader(预加载):当前导航下可能需要资源 Prefetch(预获取):将来某些导航下可能需要的资源
语法 new PreloadWebpackPlugin({
rel:"preloader",
as:"script"
})
#### Core-js 处理ES6以上兼容性问题
语法: import('core-js')
use: [{
loader: "babel-loader",
options: {
// 设置预定义的环境
presets: [
"@babel/preset-env", // 指定环境插件
"corejs": "3",// 指定corejs版本
"useBuiltIns": "usage"// 使用corejs的方式 usage表示按需加载
}
]
}
},
'ts-loader'
]
#### PWA:渐进式网络开发应用程序(离线可访问),需要通过serviceWorker 实现,
语法 npm i workbox-webpack-plugin-D
new WorkboxWebpackPlugin.GenerateSW({ //生成serviceworker配置文件
clientsClaim:true, //帮助serviceworker快速启动
skipWaiting:true //删除旧的serviceworker
})
#### 总结