1. webpack的作用
webpack是一个模块打包工具,可以将各种资源打成一个bundle.js包的形式, 前端网页功能丰富,SPA技术流行,JS复杂度需要一大堆依赖包,还要解决Scss, Less, 新增样式的扩展写法的编译的工作,所以需要Webpack的辅助,三个前端框架,都有自身依赖webpac的构建工具(如vue-cli是依据webpack的,已经内置了webpack的绝大多数plugin) 代码转换,文件优化,代码分割,模块合并,自动刷新,代码校验,自动发布
实际问题,首屏加载时间,提取多个页面公共代码,提取不需要的部分让其异步加载
2. webpack的原理
分析项目结构,找到JS模块及其他的一些浏览器不能直接运行的扩展语言(Sass, Typescript),将其打包为合适的格式供浏览器使用, 3.0之后有优化项目的能力。
3. webpack的构建流程
-
初始化参数: 解析webpack的配置参数,解析shell(命令行)和config.js配置的参数,生成配置结果;
-
开始编译: 根据上一步得到的参数初始化compiler对象,注册所有配置的插件plugin,监听webpack构建生命周期的事件节点,做出相应的反应,执行对象的run方法开始执行编译;
Webpack提供了一些生命周期事件,您可以在插件中注册这些事件的处理函数,以执行自定义逻辑。以下是一些常见的Webpack生命周期事件节点和相应的插件处理函数:
beforeRun和run: 这两个事件在Webpack开始构建之前和构建开始时触发。您可以使用插件在这些事件上执行一些准备工作或记录日志。emit: 在Webpack生成最终的输出文件之前触发,这是一个可以用来修改文件的好时机。您可以使用这个事件来自定义生成的输出。afterEmit: 在Webpack已经生成了输出文件后触发,可以用于执行与输出文件相关的后续操作。done: 当Webpack构建完成时触发。这是一个常用的事件,用于执行一些收尾工作,如清理临时文件、生成报告等。
- 确定入口:从配置的entry入口(文件的主入口),开始解析文件构建AST语法树,找出依赖(文件的相互依赖),递归下去
- 编译模块: 根据文件类型和loader配置,调用所有配置的loader对文件进行转换,再找出模块依赖的模块,递归本步骤到所有入口依赖的文件都经过了本步骤的处理
- 完成模块编译并输出:得到每个文件结果,包括每个模块之间的依赖关系,根据entry或分包配置生成代码块chunk
- 输出完成: 输出所有的chunk到文件系统
总结: 解析配置参数、命令行参数 -> 根据参数初始化complier,并且注册插件 -> 根据配置的entry来解析文件构建AST语法树,找出依赖 -> 开始编译,调用loader对文件进行转换 -> 完成编译并输出,生成chunk -> 输出完成
4. webpack常见plugin
plugins是用来扩展webpack功能的,在构建流程注入钩子实现,给webpack带来了很大的灵活性。
- htmlWebpackPlugin: 自动在打包结束后生成html文件,并引入bundle.js
- ExtractTextPlugin: 提取css到单独的文件
- 作用: 分离加载样式,避免加载闪烁,并行下载css文件,提高加载速度
- webpack-bundle-analyzer可视化webpack输出文件的体积
- web-webpack-plugin方便单页应用输出html
- webpack-parallel-uglify-plugin多进程执行代码压缩,提升构建速度
- define-plugin 定义环境变量
5. webpack常见loader
loader是对模块进行预处理的工具,是对模块进行转换的工具,告诉webpack在遇到哪些文件时使用哪些loader去加载和转换打包成js
常见loader:
- css-loader: 读取css文件,支持CSS模块化
- style-loader: 把css内容注入到JS中,通过DOM去加载CSS
- sass-loader: 解析sass文件,然后传递给css-loader使用,所以可以编写更复杂的样式
- postcss-loader:自动添加浏览器兼容前缀(一般同autofixer使用)
- babel-loader:将es6换成es5
- source-map-loader: 加载额外的source map文件,方便断点调试
- image-loader: 加载并且压缩图片文件
- eslint-loader: 通过Eslint检查JS代码
6. loader和plugin的区别
作用:
- loader: 翻译官: 对其他资源进行预处理;因为webpack只认识javascript
- plugin:扩展webpack的功能,监听webpack提供的api改变输出的结果
配置:
- loader, module rules中配置,类型为数组,每一项都是一个Object, 内部包含test, loader, options等
- pugin单独配置,每一项是一个plugin的实例,参数通过构造函数传入。
7. webpack热更新原理是什么?
自己开启了express应用,添加了对webpack编译的监听,添加和浏览器websocket长连接,当文件变化触发webpack进行编译完成后,会通过socket消息告诉浏览器准备刷新,不用刷新网页,而是刷新某个模块,通过hash值来对比需要更新的模块
总结:
- 启动webpack, 生成compiler, 比如启动webpack编译工作,监听本地文件变化;
- 使用express启动本地server, 让浏览器可以请求本地的静态资源
- 本地server启动后,再去启动websocket服务,通过websocket, 建立本地服务和浏览器的双向通信,及本地文件发生变化,告知浏览器更新代码
websocket简介: websocket是一种网络通信协议,它的主要特点是,建立在TCP协议上,服务端实现比较容易,与HTTP协议有着良好的兼容性,数据格式轻量,可以发送文本和二进制数据,没有同源限制,客户端可以与任意服务器通信,服务器也可以给客户端推送信息。
8. source map是什么?生产环境怎么用?
9.如何优化 Webpack 的构建速度?
- 压缩代码
- 图片压缩
- 缩小打包作用域
- 提取页面公共资源
- tree shaking
- 动态pollify
10.babel的原理
- 解析:将代码转换为AST
- 转换:访问AST
- 生成:以新的AST为基础生成代码
11. webpack treeShaking机制的原理
12.前端为什么要进行打包构建
13.webpack和其他构建工具的区别
举例:vite
总体区别: webpack是将所有模块打包成一个或多个bundle文件, vite是将每个模块作为一个单独的文件进行构建。
- 构建方式:
Webpack中,将所有模块打包成一个或多个bundle文件,利用代码分割、懒加载等技术来优化加载性能。- 在
Vite中,它使用了浏览器原生的ES模块加载器,每个模块作为一个单独的文件来构建,可以提供更快的冷启动和热更新速度
- 构建速度:
Webpack中,相对较慢,因为需要分析和处理大量的模块依赖关系,并生成对应的bundle文件。- 在
Vite中,使用了缓存机制和按需加载,动态解析和编译模块,不需要像webpack那样每次修改代码后重新构建;第一次访问项目时,会缓存编译和打包生成的文件,下次开发时,只需要编译和打包发生更改的部分,而不需要重新编译和打包整个项目;
- 生态系统:
Webpack中, 有庞大的生态系统和丰富的插件支持,可以处理各种类型的资源文件,提供了许多功能强大的插件- 在
Vite中,动态解析和编译模块,不需要像webpack那样每次修改代码后重新构建
- 服务启动方式:
Webpack中, 先打包再启动开发服务器- 在
Vite中,动态解析和编译模块,不需要像webpack那样每次修改代码后重新构建
来源: webpack面试题及答案 zhuanlan.zhihu.com/p/608823058
吐血整理」再来一打Webpack面试题juejin.cn/post/684490…
webpack和vite的区别: