webpack的理解
webpack是一个模块化打包JS的工具,在webpack中一切文件都是模块,通过loader转换文件 通过plugin注入钩子,最后输出由多个模块组合而成的文件。
webpack的工作原理
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
webpack的核心概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
- output :出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
Webpack的基本功能有哪些?
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
- 文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
- 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
- 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
- 代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
Webpack打包优化常见的几种方案
减少打包时间
优化Loader的搜索范围、HappyPack、DllPlugin、代码压缩相关(启用gzip压缩)
减少包大小
按需加载、Scope Hoisting、 Tree shaking
⽤webpack来优化前端性能(优化webpack的输出结果,让打包的最终结果在浏览器运⾏快速⾼效)
压缩代码、利用CDN加速、Tree Shaking、Code Splitting(自动)、提取公共第三库
webpack工作流程
- 1.初始化参数:从配置文件读取与合并参数,得出最终的参数
- 2.开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,开始执行编译
- 3.确定入口:根据配置中的 entry 找出所有的入口文件
- 4.编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
- 5.完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
- 6.输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
- 7。输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
常用loader
Loader 是webpack中提供了一种处理多种文件格式的机制,因为webpack只认识JS和JSON,所以Loader相当于翻译官,将其他类型资源进行预处理。
用于对模块的"源代码"进行转换。
loader支持链式调用,**调用的顺序是从右往左。**链中的每个loader会处理之前已处理过的资源,最终变为js代码。
可以通过 loader 的预处理函数,为 JavaScript 生态系统提供更多能力。
- less-loader:将less文件编译成css文件
- css-loader:读取合并CSS文件(加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性)
- style-loader:把CSS内容注入到JavaScript里(把 CSS 代码注⼊到 JavaScript 中,通过 DOM 操作 去加载 CSS)
- sass-loader:解析sass文件(安装sass-loader,node-sass)
- postcss-loader:自动添加浏览器兼容前缀(postcss.config配置)
- url-loader:将文件转换为base64 URI。
- vue-loader:处理vue文件。
- ts-loader: 打包编译Typescript文件
- babel-loader:把 ES6 转换成 ES5
- eslint-loader:通过 ESLint 检查 JavaScript 代码
- file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件
- source-map-loader:加载额外的 Source Map ⽂件,以⽅便断点调试
- image-loader:加载并且压缩图⽚⽂件
常见Plugins
- HtmlWebpackPlugin自动在打包结束后生成html文件,并引入bundle.js
- cleanWebPackPlugin打包自动删除上次打包文件
- definePlugin:定义环境变量
- miniCssExtractPlugin: CSS 提取到单独的⽂件中,⽀持按需加载
- webpack-bundle-analyzer: 可视化 webpack 输出⽂件的体积
Webpack中Loader和Plugin的区别
loader:模块转换器,用于将模块的原内容按照需要转成你想要的内容。
plugin:是用来自定义webpack打包过程的方式,扩展 Webpack 功能的,改变构建结果,它给 Webpack 带来了很大的灵活性。
运行时机
1.loader运行在编译阶段
2.plugins 在整个周期都起作用
如何利用webpack来优化前端性能?
- 代码压缩(按需加载)
- 代码分割 splitChunks - 在optimization配置项中配置
- 使用Dll进行分包
- 使用路由懒加载
Webpack如何配置压缩代码?压缩了什么?
- 在optimization配置项中来配置该插件作为压缩器进行压缩。
- 在plugins里使用该插件进行压缩
- js压缩:利用terser-webpack-plugin
- css压缩:利用了optimize-css-assets-webpack-plugin 插件
- 删除了console、注释、空格、换行、没有使用的css代码等
如何提高webpack的构建速度?
思路1:减少需要构建的文件或代码
-
HMR(Hot Module Replacement) 模块热替换只重新构建发生变化的模块 – 开发环境中
-
缩小处理范围:合理利用这两个属性exclude:不需要处理的文件 和 include:需要处理的文件
-
babel缓存 第二次构建时,会读取之前的缓存,只重新构建变化的文件
-
使用Dll进行分包 --> 分包方便按需加载 思路2:多进行进行构建
-
多进程打包 thread-loader,将其放在费时的loader之前
HMR(热更新)的原理
如何开启HMR: 通过设置devServer: {hot: true} 开启 开启后便可以在发生改变后局部刷新改变的部分
- 使用
webpack-dev-server(WDS)托管静态资源 同时以Runtime方式注入HMR客户端代码 - 浏览器加载页面后 与WDS建立
WebSocket连接 - webpack监听到文件变化后 增量构建发生变更的模块 并通过WebSocket发送
hash事件 - 浏览器接收到
hash事件后 请求manifest资源文件 确认增量变更范围 - 浏览器加载发生变更的增量模块
- webpack运行时触发变更模块的
module.hot.accept回调 执行代码变更逻辑 done:构建完成,更新变化
总结就是webpack将静态资源托管在 WDS 上,而 WDS 又和浏览器通过 webSocket 建立联系,而当webpack监听到文件变化时,就会向浏览器推送更新并携带新的hash 与之前的hash进行对比,浏览器接收到hash事件后变化加载变更的增量模块并触发变更模块的 module.hot.accept回调执行变更逻辑。
Babel 的原理是什么?
babel 的转译过程也分为三个阶段,这三步具体是:
-
解析 Parse: 将代码解析⽣成抽象语法树(AST),即词法分析与语 法分析的过程;
-
转换 Transform: 对于 AST 进⾏变换⼀系列的操作,babel 接受得 到 AST 并通过 babel-traverse 对其进⾏遍历,在此过程中进⾏添 加、更新及移除等操作;
-
⽣成 Generate: 将变换后的 AST 再转换为 JS 代码, 使⽤到的模 块是 babel-generator。