Webpack⾯试题超全⾯【吐⾎整理】
0.有哪些常见的Loader?你⽤过哪些Loader?
(我开始熟悉的报起了菜名)
raw-loader:加载⽂件原始内容(utf-8)
file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件 (处理图⽚和字体)
url-loader:与 file-loader 类似,区别是⽤户可以设置⼀个阈值,⼤于阈值时返回其 publicPath,⼩于阈值时返回⽂件 base64 形式编码 (处理图⽚和字体)
source-map-loader:加载额外的 Source Map ⽂件,以⽅便断点调试
svg-inline-loader:将压缩后的 SVG 内容注⼊代码中
image-loader:加载并且压缩图⽚⽂件
json-loader 加载 JSON ⽂件(默认包含)
handlebars-loader: 将 Handlebars 模版编译成函数并返回
babel-loader:把 ES6 转换成 ES5
ts-loader: 将 TypeScript 转换成 JavaScript
awesome-typescript-loader:将 TypeScript 转换成 JavaScript,性能优于 ts-loader
sass-loader:将 CSS 代码注⼊ JavaScript 中,通过 DOM 操作去加载 CSS
css-loader:加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性
style-loader:把 CSS 代码注⼊到 JavaScript 中,通过 DOM 操作去加载 CSS
postcss-loader:扩展 CSS 语法,使⽤下⼀代 CSS,可以配合 autoprefixer 插件⾃动补齐 CSS3 前缀
eslint-loader:通过 ESLint 检查 JavaScript 代码
tslint-loader:通过 TSLint检查 TypeScript 代码
mocha-loader:加载 Mocha 测试⽤例的代码
coverjs-loader:计算测试的覆盖率
vue-loader:加载 Vue.js 单⽂件组件
i18n-loader: 国际化
cache-loader: 可以在⼀些性能开销较⼤的 Loader 之前添加,⽬的是将结果缓存到磁盘⾥
svg运行方式有哪些更多 Loader 请参考
(⾯试官:挺好,知道的还挺多)
1.有哪些常见的Plugin?你⽤过哪些Plugin?
(这⼤兄弟好像听上瘾了,继续开启常规操作)
define-plugin:定义环境变量 (Webpack4 之后指定 mode 会⾃动配置)
ignore-plugin:忽略部分⽂件
html-webpack-plugin:简化 HTML ⽂件创建 (依赖于 html-loader)
web-webpack-plugin:可⽅便地为单页应⽤输出 HTML,⽐ html-webpack-plugin 好⽤
uglifyjs-webpack-plugin:不⽀持 ES6 压缩 (Webpack4 以前)
terser-webpack-plugin: ⽀持压缩 ES6 (Webpack4)
webpack-parallel-uglify-plugin: 多进程执⾏代码压缩,提升构建速度
mini-css-extract-plugin: 分离样式⽂件,CSS 提取为独⽴⽂件,⽀持按需加载 (替代extract-text-webpack-plugin)
serviceworker-webpack-plugin:为⽹页应⽤增加离线缓存功能
clean-webpack-plugin: ⽬录清理
ModuleConcatenationPlugin: 开启 Scope Hoisting
speed-measure-webpack-plugin: 可以看到每个 Loader 和 Plugin 执⾏耗时 (整个打包耗时、每个 Plugin 和 Loader 耗时)
webpack-bundle-analyzer: 可视化 Webpack 输出⽂件的体积 (业务组件、依赖第三⽅模块)
更多 Plugin 请参考
(Double Kill)
2.那你再说⼀说Loader和Plugin的区别?
(就知道你会问这个,我⽤⼿掩盖着嘴⾓的微笑)
Loader 本质就是⼀个函数,在该函数中对接收到的内容进⾏转换,返回转换后的结果。 因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进⾏转译的预处理⼯作。
Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运⾏的⽣命周期中会⼴播出许多事
件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每⼀项都是⼀个 Object,内部包含了 test(类型⽂件)、loader、options (参数)等属性。
Plugin 在 plugins 中单独配置,类型为数组,每⼀项是⼀个 Plugin 的实例,参数都通过构造函数传⼊。
3.Webpack构建流程简单说⼀下
Webpack 的运⾏流程是⼀个串⾏的过程,从启动到结束会依次执⾏以下流程:
初始化参数:从配置⽂件和 Shell 语句中读取与合并参数,得出最终的参数
开始编译:⽤上⼀步得到的参数初始化 Compiler 对象,加载所有配置的插件,执⾏对象的 run ⽅法开始执⾏编译
确定⼊⼝:根据配置中的 entry 出所有的⼊⼝⽂件
编译模块:从⼊⼝⽂件出发,调⽤所有配置的 Loader 对模块进⾏翻译,再出该模块依赖的模块,再递归本步骤直到所有⼊⼝依赖的⽂件都经过了本步骤的处理
完成模块编译:在经过第4步使⽤ Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
输出资源:根据⼊⼝和模块之间的依赖关系,组装成⼀个个包含多个模块的 Chunk,再把每个 Chunk 转换成⼀个单独的⽂件加⼊到输出列表,这步是可以修改输出内容的最后机会
输出完成:在确定好输出内容后,根据配置确定输出的路径和⽂件名,把⽂件内容写⼊到⽂件系统
在以上过程中,Webpack 会在特定的时间点⼴播出特定的事件,插件在监听到感兴趣的事件后会执⾏特定的逻辑,并且插件可以调⽤Webpack 提供的 API 改变 Webpack 的运⾏结果。
简单说
初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
编译:从 Entry 出发,针对每个 Module 串⾏调⽤对应的 Loader 去翻译⽂件的内容,再到该 Module 依赖的 Module,递归地进⾏编译处理
输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成⽂件,输出到⽂件系统中
对源码感兴趣的同学可以移步我的另⼀篇专栏
4.使⽤webpack开发时,你⽤过哪些可以提⾼效率的插件?
(这道题还蛮注重实际,⽤户的体验还是要从⼩抓起的)
webpack-dashboard:可以更友好的展⽰相关打包信息。
webpack-merge:提取公共配置,减少重复配置代码
speed-measure-webpack-plugin:简称 SMP,分析出 Webpack 打包过程中 Loader 和 Plugin 的耗时,有助于到构建过程中的性能瓶颈。
size-plugin:监控资源体积变化,尽早发现问题
HotModuleReplacementPlugin:模块热替换
5.source map是什么?⽣产环境怎么⽤?
source map 是将编译、打包、压缩后的代码映射回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试源码就需要 soucre map。
map⽂件只要不打开开发者⼯具,浏览器是不会加载的。
线上环境⼀般有三种处理⽅案:
hidden-source-map:借助第三⽅错误监控平台 Sentry 使⽤
nosources-source-map:只会显⽰具体⾏数以及查看源代码的错误栈。安全性⽐ sourcemap ⾼
sourcemap:通过 nginx 设置将 .map ⽂件只对⽩名单开放(公司内⽹)
注意:避免在⽣产中使⽤ inline- 和 eval-,因为它们会增加 bundle 体积⼤⼩,并降低整体性能。
6.模块打包原理知道吗?
Webpack 实际上为每个模块创造了⼀个可以导出和导⼊的环境,本质上并没有修改 代码的执⾏逻辑,代码执⾏顺序与模块加载顺序也完全⼀致。
7.⽂件监听原理呢?
在发现源码发⽣变化时,⾃动重新构建出新的输出⽂件。
Webpack开启监听模式,有两种⽅式:
启动 webpack 命令时,带上 --watch 参数
在配置 fig.js 中设置 watch:true
缺点:每次需要⼿动刷新浏览器
原理:轮询判断⽂件的最后编辑时间是否变化,如果某个⽂件发⽣了变化,并不会⽴刻告诉监听者,⽽是先缓存起来,等 aggregateTimeout 后再执⾏。
// 默认false,也就是不开启
watch: true,
// 只有开启监听模式时,watchOptions才有意义
watchOptions: {
// 默认为空,不监听的⽂件或者⽂件夹,⽀持正则匹配
ignored: /node_modules/,
// 监听到变化发⽣后会等300ms再去执⾏,默认300ms
aggregateTimeout:300,
// 判断⽂件是否发⽣变化是通过不停询问系统指定⽂件有没有变化实现的,默认每秒问1000次
poll:1000
}
}
8.说⼀下 Webpack 的热更新原理吧
(敲⿊板,这道题必考)
Webpack 的热更新⼜称热替换(Hot Module Replacement),缩写为 HMR。 这个机制可以做到不⽤刷新浏览器⽽将新变更的模块替换掉旧的模块。
HMR的核⼼就是客户端从服务端拉去更新后的⽂件,准确的说是 chunk diff (chunk 需要更新的部分),实际上 WDS 与浏览器之间维护了⼀个 Websocket,当本地资源发⽣变化时,WDS 会向浏览器推送更新,并带上构建时的 hash,让客户端与上⼀次资源进⾏对⽐。客户端对⽐出差异后会向 WDS 发起 Ajax 请求来获取更改内容(⽂件列表、hash),这样客户端就可以再借助这些信息继续向 WDS 发起 jsonp 请求获取该chunk的增量更新。
后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些⼜需要更新?)由 HotModulePlugin 来完成,提供了相关 API 以供开发者针对⾃⾝场景进⾏处理,像react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。
细节请参考
(⾯试官:不错不错,⼩伙⼦表达能⼒不错)
(基操,勿6)
9.如何对bundle体积进⾏监控和分析?
VSCode 中有⼀个插件 Import Cost 可以帮助我们对引⼊模块的⼤⼩进⾏实时监测,还可以使⽤ webpack-bundle-analyzer ⽣成 bundle 的模块组成图,显⽰所占体积。
bundlesize ⼯具包可以进⾏⾃动化资源体积监控。
10.⽂件指纹是什么?怎么⽤?
⽂件指纹是打包后输出的⽂件名的后缀。
Hash:和整个项⽬的构建相关,只要项⽬⽂件有修改,整个项⽬构建的 hash 值就会更改Chunkhash:和 Webpack 打包的 chunk 有关,不同的 entry 会⽣出不同的 chunkhash Contenthash:根据⽂件内容来定义 hash,⽂件内容不变,则 contenthash 不变
JS的⽂件指纹设置
设置 output 的 filename,⽤ chunkhash。
entry: {
app: './scr/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path:__dirname + '/dist'
}
}
复制代码
CSS的⽂件指纹设置
设置 MiniCssExtractPlugin 的 filename,使⽤ contenthash。
entry: {
app: './scr/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path:__dirname + '/dist'
},
plugins:[
new MiniCssExtractPlugin({
filename: `[name][contenthash:8].css`
})
]
}
复制代码
图⽚的⽂件指纹设置
设置file-loader的name,使⽤hash。
占位符名称及含义
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论