基础
-
使用原因:(1:将项目编译成浏览器能运行的代码;(2:代码压缩、兼容性处理;(3:项目代码书写更强调可读性,并不利于浏览器执行。
-
npm:下载包;npx:执行node_modules内的包程序。
-
development模式下仅进行ESM的编译;production模式下还会进行代码压缩,以及一些简单的运算。
-
配置文件运行在Node环境下,需要采用CommonJS的模块化。
-
五大核心:entry、output、loader、plugin、devserver。
-
entry中使用相对路径;output中使用绝对路径,使用Node核心模块Path来返回绝对路径,Path.resolve(_dirname, "dist")。
-
npx webpack 配置信息:按照配置信息进行打包;npx webpack:按照webpack.config.js中的配置进行打包。
-
css-loader:将CSS资源编译成CommonJS的模块放到JS中;style-loader:将JS中CSS通过创建style标签的方式添加到HTML文件中。
-
rules配置中use属性可以使用多个loader,loader属性只能使用一个loader。
-
webpack5将file-loader和url-loader内置,使用type: "asset"就相当于使用url-loader,配置后可以将图片转为Base64,可配置图片资源的输出路径;转为Base64的优势在于请求数量会减少。缺点是内存占用会变大,图片本身越大增大越明显,所以只需要将较小图片进行转换,一般设置为10kb及以下。
-
处理图片以外的其他资源文件时,使用type: "asset/resounce"。
-
在webpack5中output中增加clear: true,可以在打包前自动将path的整个目录清空。
-
Eslint可以检查JS和JSX文件代码的规范;rules会覆盖extends继承的规则;.eslintignore文件可以让插件忽略文件的校验。
-
devserver当src中的内容发送变化时,将自动重新打包,且不会输出资源而是在内存中编译打包,所以不必使用clear: true以及output的path。
-
单独打包CSS:使用mini-css-extract-plugin中的loader替换style-loader。CSS文件默认被打包到JS文件中,JS文件加载时创建style标签生成样式,这样会导致出现闪屏现象,所以需要将JS单独打包,通过link引入。
-
使用postcss-loader可以做兼容性处理,通过package.json中的browserslist配置需要兼容的浏览器版本。
-
默认生产模式开启了HTML文件、JS文件的压缩,不过HTML文件需要html插件处理。
-
sourceMap:开发模式:cheap-module-source-map。打包编译速度快,只包含行映射,不包含列隐射;生产模式:source-map。打包编译速度慢,包含行、列映射。因为生产模式的代码被压缩了,所以需要行、列映射都有。
-
HotModuleRepleacement:仅开发模式,webpack5默认打开,但不支持JS文件的热替换,需要使用对应的vue-hot-loader或react-hot-loader等loader扩展。
-
OneOf:如果每个文件只匹配一组loader规则,可以将这些loader规则用oneof包裹,这样匹配成功之后就不再继续往下匹配了。
-
规则中的include和exclude只能写一个,主要是优化JS文件的处理效率。
-
HardSourceWebpackPlugin插件用于为模块提供中间缓存步骤。
-
Cache:每次打包时JS文件都要经过ESLint检查和Babel编译,速度较慢。在babel-loader中options下配置cacheDirectory: true开启babel缓存。cacheCompression: false关闭缓存文件的压缩,因为缓存文件压缩需要时间,但并不会影响线上环境包大小,所以不用压缩。在ESLintPlugin中打开cache: true开启缓存,cacheLocation: path.resolve(_dirname, "../node_modules/.cache/eslintcache"配置缓存文件位置。webpack自动压缩JS文件的原因是开启了Terser插件。
-
thread:使用多进程打包时,仅在特别耗时的操作中使用,因为进程启动需要600ms开销,安装thread-loader插件,获取设备cpu核数,在ESLintPlugin.babel-loader.TerserWebpackPlugin中开启多核数打包。
-
推荐在optimization中的minimizer内写压缩插件,包括CSS压缩和JS压缩。
-
Tree Shaking:依赖于ES Module,生产模式默认开启。Babel为编译的每个文件都插入了辅助代码,使代码体积过大。下载并在在babel中使用这个插件@babel/plugin-transform-runtime: 禁用Babel自动对每个文件的runtime注入,将所有辅助代码从自身引用。image-minimizer-webpack-plugin: 压缩本地图片插件,有无损压缩和有损压缩两种模式,需另外下载,需要翻墙。
-
Code Split:代码压缩。默认打包时,会将所有JS文件打包到一个文件中,使用代码分割可以分割文件和按需加载。
-
多入口打包时,output的filename: "[name].js",以文件名命名。
-
npm init -y:初始化package.json文件。
-
OptimizationSplitChunks:将公共代码分割出来单独打包进行引用,chunks: "all"。
-
通过import动态引入,动态导入的文件代码会被分割为单独模块,实现按需加载,res.default中是模块暴露的内容。路由的动态导入实现组件的按需加载。
-
为打包输出的其他文件命名:在动态导入的import里面使用注释:/webpackChunkName: "name"/。在output中添加chunkFilename: "static/js/[name].chunk.js"。对图片、字体等通过asset处理的资源进行命名:assetModuleFilename: "static/media/[hash: 10][ext][query]"。如果动态导入的文件中有CSS文件,也会生成chunk,所以在plugins中的MiniCssExtractPlugin中增加chunkFilename: "static/css/[name].chunk.js。
-
Preload/Prefetch:Preload:浏览器立即加载资源。Prefetch:浏览器空闲时才加载资源。只加载不执行,有缓存。Preload优先级高,只能加载当前页面需要的,一般当前页面优先级高的资源用Preload,下一个页面用Prefetch。兼容性差,插件:@vue/preload-webpack-plugin。
-
当a模块中引入b模块,b模块发生变化导致打包的文件名hash值改变,会令a模块的缓存失效,可以使用runtimechunk: {name: (entryPoint) =>
runtime~${entryPoint.name}.js}将文件名映射存入runtime中,这样b模块改变时,只有b模块和runtime模块重新打包。 -
Core-js:如果使用了async函数、premise对象、数组的一些新方法等,Babel无法处理,需要使用core-js(Polyfill补丁)。里面是这些语法的自定义实现,通过判断浏览器是否识别,不识别时使用自定义方法。在babel.config.js中配置{useBuiltIns: "usage", corejs: 大版本号},实现按需自动加载。
-
PWA离线访问:渐进式网络应用程序,插件:workbox-webpack-plugin,在webpack配置中引入,在main.js中注册生成ServiceWorker,有兼容性问题,会将资源缓存在serviceWorker中。
-
React脚手架:开发模式:babel中使用"react-app"的预设,里面包含了core.js和runtime,不需要再单独配置。在devServer中hot: true开启HMR,样式的HMR是style-loader实现的,JS的HMR使用react-refresh/babel.ReactRefreshWebpackPlugin。devServer中historyApiFallback: true用于解决前端路由刷新404问题。生产模式:要指定output的path,提取CSS成单独文件,压缩CSS文件,压缩JS文件,生产模式会自动压缩HTML文件,压缩图片(image-minimizer-webpack-plugin)。生产模式后端处理刷新404问题。copy-webpack-plugin配置,将public目录中的文件复制到dist目录下。需要忽略index.html文件。minimize: true开启压缩。可以将node_modules中的大文件进行分组打包,实现并行加载或按需加载。performance: false关闭性能分析,加快打包速度。
-
Vue脚手架:cross-env定义的环境变量是给打包工具使用的。DefinePlugin定义的环境变量是给源代码使用的,解决Vue3页面警告问题。
-
UI库使用按需加载会添加辅助代码,可能会导致大小比整体加载更大。
-
在resolve中配置路径别名。
Loader
-
执行顺序:enforce属性 pre -> normal -> inline -> post,同优先级从右到左、从上到下。
-
配置方式:在webpack.config.js文件中指定loader;内联方式:在每个import语句中显示指定loader,在内联方式中通过 ! 将loader隔开,loader后用 ? 参数。
-
前缀:! 跳过normal;-! 跳过pre、normal;!! 跳过pre、normal、post。
-
loader是一个函数,当webpack处理解析时,会调用相应的loader去处理;loader将接收文件内容作为参数,返回内容出去。参数:content(文件内容);map(SourceMap);meta(别的loader传递的数据)。
-
loader不同方式:同步Loader;异步Loader;Raw Loader(接受到的内容是二进制数据,如图片等)。
-
Pitch Loader:picth方法会在loader之前执行,执行顺序为:pitch1 -> pitch2 -> pitch3 -> loader3 -> loader2 -> loader1。有picth方法return会中断后续pitch和loader方法。
-
loader API:async、callback、getOptions(对接收的option会进行验证,验证失败会报错)、emitFile、utils.contextify、utils.absolutify。
-
babel-loader:根据预设内容使用@babel/core核心库进行转换;@babel/parser将js解析成抽象语法树;@babel/traverse将抽象语法树格式化为更好操作的树状结构对象,对文件进行合并处理;@babel/generator生成处理后的js代码。
-
file-loader:根据文件内容生成一个带hash值的文件名,将文件输出到dist目录,返回一个module.exports指向这个文件的路径。使用时可以配置type: "javascript/auto",阻止webpack默认处理图片资源,只使用file-loader处理。
-
style-loader:只能处理样式,遇到其他样式资源(背景图片等)无法处理,需要依赖css-loader将css中的各种依赖进行解析引入。css-loader暴露的是js代码,style-loader使用pitch loader方式,通过import引入css-loader处理后的资源,动态创建一个style标签,将样式内容添加到style标签上,并插入页面中。
Plugin
-
webpack在编译过程中,触发一系列的Tapable钩子事件。
-
tap(同步异步);tapAsync(回调异步);tapPromise(Promise异步)。
-
Compiler:保存着完整的webpack环境配置(注册事件)。
-
Compilation:能够访问所有模块和它们的依赖(处理资源)。
-
webpack的生命周期。
-
webpack加载webpack.config.js中所有的配置,此时会new TestPlugin(),执行插件的constructor;webpack创建compiler对象;遍历所有plugins中的插件,调用插件的apply方法;执行剩下的编译流程(触发各个hooks事件)。
-
BannerWebpackPlugin:添加注释信息,如作者、修改时间等。
-
ClearWebpackPlugin:打包前删除上次打包的文件。
-
AnalyzeChunkWebpackPlugin:输出打包文件大小的分析文件,便于进行优化。
-
InlineChunkWebpackPlugin:webpack打包生成的runtime等小文件,额外发送请求性能不好,将其内联到js中减少请求数量,借助html-webpack-plugin实现。