webpack
2023-09-11 23:52:56 0 举报
AI智能生成
webpack笔记总结
作者其他创作
大纲/内容
webpack插件机制
webpack的插件机制依赖于一个核心的库,Tapable
Tapable
web常见性能优化
webpack的性能优化,主要体现在三个方面
1.构建性能:是指在开发阶段的构建性能。当构建性能越高,开发效率越高
1.减少模块解析
模块解析包括:AST抽象语法树分析、依赖分析、模板语法替换
对某个模块不进行解析,可以缩短构建时间
如果某个模块不做解析,该模块经过laoder处理后的代码就是最终代码
如果没有loader对该模块进行处理,该模块的源码就是最终打包结果的代码
对于模块中没有其他依赖模块,则不需要解析,可以通过配置module.noParse进行处理
分支主题
2.优化loader性能
1.限制loader的应用范围
针对一些第三方库,不使用loader进行处理。例如babel-loader,转换一些本身就是用ES5语法书写的第三方库,反而会浪费构建时间
因此通过module.rules.exclude或module.rules.include,排除或仅包含需要应用loader的场景
分支主题
2.缓存loader结果
如果某个文件内容不变,经过相同的loader解析后,解析后的结果也不变,
所以我们可以把loader的解析结果保存下来,让后续的解析直接用缓存的结果
分支主题
这个时候就需要用到cache-loader
cache-loader的原理是,在执行loader之前,如果发现有缓存文件,则直接在loader.pitch函数里return源代码。
loader明明不是从后往前执行的吗?那为什么cache-loader还可以拿到loader的缓存结果?
答:其实在每个loader运行的过程中,还包括一个过程pitch
分支主题
第一次打包时,会先把filepath交给loader1.pitch执行, 检查是否有缓存结果,若无缓存,往后执行。调用loader2.pitch,检查是否有缓存,若无缓冲,往后执行,依次类推…直到最后结束了再调用loader,当调用cache-loader时,就会返回loader处理的结果并缓存。
当第二次打包时(流程同上),若发现有缓存,则直接返回缓存结果,不会继续往后走了
分支主题
pitch的好处,可以根据是否有返回,来控制下一步到哪。
对于babel-loader,使用它本身的配置也是可以缓存的。
3.开启多线程打包
通过thread-loader会开启一个线程池,它会把后续的loader放到线程池的线程中运行,以提高构建效率
分支主题
thread-loader可以通过测试决定放置的位置
放到线程池的loader的缺点
1.无法使用 webpack api 生成文件
2.无法使用自定义的 plugin api
3.无法访问 webpack options
由于开启和管理线程需要消耗时间,所以在小项目使用会增加构建时间
4.热更新
热更新是不能降低构建时间(可能还会稍微增加),因为它发生代码运行期间,但它可以降低代码改动到效果显现的时间
默认情况下,webpack-dev-server不管式否开启热更新,重新打包之后都会刷新页面,但是如果是热更新,webpack就会通过socket管道将服务器更新的内容发送给浏览器
分支主题
样式替换
对于样式替换,可以使用style-loader
分支主题
热更新原理流程
当开启热更新后,Webpack 会轮询问有没有哪些模块发生变化,如果文件内容发生改变,会异步下载更新的代码,向服务器发送请求。下载完毕后,服务器就会主动发送信息给浏览器告知有文件内容发生改变,浏览器发送请求给服务器请求发送修改后的资源文件,服务器接收到请求后把修改的资源文件发送给浏览器,浏览器把接收到的结果交给HotModuleReplacementPlugin,HotModuleReplacementPlugin再覆盖原始代码,再重新执行代码。
2.传输性能:在这方面重点考虑网络中的总传输量、JS文件数量以及浏览器缓存
1.分包
分支主题
webpack默认不进行分包,所有的依赖添加为同一个bundle,如果是多页面打包的话,会存在多个chunk引入公共模块导致代码冗余,占用打包体积
分包的目的是在不影响源代码的情况下降低代码体积
1.手动分包
1,打包公共模块,比如第三方库
分支主题
2.手动引入公共js
注:不能对小型库进行单独打包,不能对依赖多的库进行打包
2.自动分包,利用webpack的optimization配置项,配置splitchunk
分支主题
其中splitChunk是分包策略的配置,通过splitChunkPlugin配置分包策略进行分包分包时,webpack开启一个新的chunk,对分离的模块进行打包
开发阶段没必要分包,因为有热更新,而且开发一般是本地,大文件对本地开发影响不大
分包的基础单位是模块,所以设置minSize时有时会出现打包文件超过该值的情况
1.全局策略
分支主题
2.缓存组策略
修改cache Group的vendors和default配置
2.模块体积优化
1.代码压缩terser,terser是webpack内置的代码压缩工具
默认情况下webpack的production模式是开启代码压缩
更改压缩配置
/*#PURE/注释标记作用是告诉打包工具该函数的调用不会有副作用
2.tree shaking
当webpack依赖分析完毕之后,webpack会根据每个模块每个导出是否被使用,标记其为dead code,然后交给代码压缩工具处理
common.js很难做tree shaking
tree shanking 对于无法识别副作用的函数会认为是副作用函数
相比于js,css无法做到tree shanking ,可以通过purgecss-webpack-plugin进行处理,css module无法处理
3.懒加载
动态导入模块,import 的才会进行依赖分析
4.gzip
webpack可以将文件进行预压缩,在请求到来的时候直接响应压缩文件,
5.辅助:用eslint规范代码
3.运行性能:主要是指JS代码在浏览器端运行的速度
主要取决于代码的书写
webpack基础
1.webpack使用流程
1.初始化npm:npm init -y
2.下载安装webpack: npm i webpack webpack-cli -D :将webpack作为开发依赖安装
检查是否安装成功:npx webpack -v :检查node_modules下面有没有webpack文件,有的化就读取文件里的版本信息
webpack只是代码压缩工具,只在开发阶段使用
3.开始打包:npx webpack
全称:npx webpack js文件路径 :如果没有写Js路径,默认打包./src/index.js
入口:webpack打包一定要有入口文件,webpack的默认打包文件入库目录是./src/index.js,因此项目中一般都会有src目录和index.js
出口:js代码发生变化时,需要重新打包,webpack会把打包文件默认放入dist/main.js
webpack只会打包入口文件,如果想要打包其他文件,需要在入口文件导入其他模块,即被打包的文件一定会和入口文件形成直接或者间接的依赖关系
webpack模块化同时支持common.js模块化和es6模块化
common.js
导出:module.exports
导入:required
2.webpack配置文件
1.作用:修改webpack默认配置
eg:默认打包命令:npx webpack,默认入口文件:./src/index.js,默认出口文件:./dist/main.js
2.创建配置文件
1.项目根目录下创建默认配置文件--webpack.config.js
2.在配置文件中导出配置
分支主题
3.webpack常见配置作用
1.mode:打包模式
默认值production:生产模式(压缩,混淆,加密...不可读)
development:开发模式(代码不会压缩 混淆)
2.output:出口文件(对象类型)
path:设置出口文件夹(必须是绝对路径),默认值:${_dirname}/dist
filename:设置出口js文件名(相对于path路径),默认值:main.js
3.entry:入口文件
默认值(相当于项目根目录):./src/index.js
分支主题
4.webpack其他配置
分支主题
webpack构建流程
图示
分支主题
1.初始化参数(entry-option)
从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
2.开始编译(run)
用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
3.确定入口
根据配置中的entry找出所有的入口文件
4.编译模块(make)
从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
5.完成模块编译(build module)
经过上一步使用Loader翻译完所有的模块之后,得到了每个模块被翻译后的最终内容,以及他们之间的依赖关系
6.seal输出资源
根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
7.emit输出完成
在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
在打包过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果
简易webpack
简易实现链接
0 条评论
下一页