面试官:webpack这10道题都不会,你好意思说做前端?

361 阅读7分钟

序言

以下是本人最近面试被问到最多的webpack面试题,10道面试题一般问webpack都会问,看一遍去敲一遍差不多都会记得。要面试的小伙伴可以查漏补缺看看,面试的时候心里更清楚。答案是我自己理解加阅读别人的文章,写的有纰漏请大家批评指教。谢谢大家进来观看!

1,有哪些常见的Loader?你用过哪些Loader?

babel-loader:把 ES6 转换成 ES5******

ts-loader: 将 TypeScript 转换成 JavaScript

sass-loader:将SCSS/SASS代码转换成CSS

css-loader:加载 CSS,支持模块化、压缩、文件导入等特性

style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS

postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀

vue-loader:加载 Vue.js 单文件组件
i18n-loader: 国际化

cache-loader: 可以在一些性能开销较大的 Loader 之前添加,目的是将结果缓存到磁盘里

image-loader:加载并且压缩图片文件

2,有哪些常见的Plugin?你用过哪些Plugin?

define-plugin:定义环境变量 (Webpack4 之后指定 mode 会自动配置)
ignore-plugin:忽略部分文件
html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)
web-webpack-plugin:可方便地为单页应用输出 HTML,比 html-webpack-plugin 好用
clean-webpack-plugin: 目录清理
webpack-bundle-analyzer: 可视化 Webpack 输出文件的体积 (业务组件、依赖第三方模块)
terser-webpack-plugin: 支持压缩 ES6 (Webpack4)
speed-measure-webpack-plugin: 可以看到每个 Loader 和 Plugin 执行耗时 (整个打包耗时、每个 Plugin 和 Loader 耗时)

3,说一下Loader和Plugin的区别?

Loader:本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。 
因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译
的预处理工作。 Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 
Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件。

Plugin:可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object, 
内部包含了 test(类型文件)、loader、options (参数)等属性。
Plugin 在 plugins 中单独配置,类型为数组,每一项是一个 Plugin 的实例,参数都通过构造函数传入。

4,Webpack构建流程简单说一下

初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
确定入口:根据配置中的 entry 找出所有的入口文件******
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统

5,webpack用过哪些可以提高效率的插件?

webpack-dashboard:可以更友好的展示相关打包信息。
webpack-merge:提取公共配置,减少重复配置代码
speed-measure-webpack-plugin:简称 SMP,分析出 Webpack 打包过程中 Loader 和 Plugin 的耗时,有助于找到构建过程中的性能瓶颈。
size-plugin:监控资源体积变化,尽早发现问题
HotModuleReplacementPlugin:模块热替换

6,source map是什么?生产环境怎么用?

source map 是将编译、打包、压缩后的代码映射回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试源码就需要 soucre map。
map文件只要不打开开发者工具,浏览器是不会加载的。

7,如何优化 Webpack 的构建速度?

使用高版本的 Webpack 和 Node.js
多进程/多实例构建:HappyPack(不维护了)、thread-loader
压缩代码, 图片压缩
缩小打包作用域:exclude/include (确定 loader 规则范围)
resolve.modules 指明第三方模块的绝对路径 (减少不必要的查找)
resolve.mainFields 只采用 main 字段作为入口文件描述字段 (减少搜索步骤,需要考虑到所有运行时依赖的第三方模块的入口文件描述字段)
resolve.extensions 尽可能减少后缀尝试的可能性
noParse 对完全不需要解析的库进行忽略 (不去解析但仍会打包到 bundle 中,注意被忽略掉的文件里不应该包含 import、require、define 等模块化语句)
IgnorePlugin (完全排除模块)合理使用alias
使用 DllPlugin 进行分包,使用 DllReferencePlugin(索引链接) 对 manifest.json 引用,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间。HashedModuleIdsPlugin 可以解决模块数字id问题
提取页面公共资源
基础包分离:使用 html-webpack-externals-plugin,将基础包通过 CDN 引入,不打入 bundle 中使用 SplitChunksPlugin 进行(公共脚本、基础包、页面公共文件)分离(Webpack4内置) ,替代了 CommonsChunkPlugin

8,写过Plugin?简单描述一下编写Plugin的思路?

webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在特定的阶段钩入
想要添加的自定义功能。
Webpack 的 Tapable 事件流机制保证了插件的有序性,使得整个系统扩展性良好。
compiler 暴露了和 Webpack 整个生命周期相关的钩子
compilation 暴露了与模块和依赖有关的粒度更小的事件钩子
插件需要在其原型上绑定apply方法,才能访问 compiler 实例传给每个插件的 compiler 
和 compilation对象都是同一个引用,若在一个插件中修改了它们身上的属性,
会影响后面的插件找出合适的事件点去完成想要的功能
emit 事件发生时,可以读取到最终输出的资源、代码块、模块及其依赖,并进行修改(emit 事件是修改 Webpack 输出资源的最后时机)
watch-run 当依赖的文件发生变化时会触发
异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

9,说说webpack解析原理

1,初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数。

2,开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译。

3,确定入口:根据配置中的 entry 找出所有的入口文件。

4,编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到
所有入口依赖的文件都经过了本步骤的处理。

5,完成模块编译:在经过第 4 步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及
它们之间的依赖关系。

6,输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。

7,输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

10,简述webpack里面的热更新原理

image.png image.png