前言
各位同学看到这里,就表明《重学webpack系列》已经更新完毕,这个系列我们一起探讨了一下webpack的核心机制,包括前端模块化的演变历史、webpack所能解决的问题、loader、plugin、devServer、sourceMap、hotModuleReplace、webpack的运行机制、高级特性与框架的结合使用。这一章我们主要是来讲一下关于webpack的常见面试题与个人的后期创作目标,还是那句话,欢迎点赞、关注,一溪之石感谢各位。
常见的面试题
一、在项目中让你配置一下Webpack,你应该注意什么?
针对这个问题,关于Webpack的基本配置无疑就是需要mode、devtool、entry、output、module、plugin、devServer几个配置项,mode能够告知Webpack以成熟的预设去帮助打包,entry告知Webpack打包入口是什么文件,output告知Webpack打包输出到哪里,loader、plugin为加载非js文件,Webpack的工程化构建流程提供一套最佳的解决方案,devServer为本地开发提供一个服务器,用于提高开发效率,详见重学webpack系列(零) -- 全局概况,我们还可以配置sourceMap、HMR来帮助我们提高开发效率。
二、关于mode的三种预设,你觉得他们之间有什么不同呢?
关于mode,Webpack提供了三种预设,分别为:none、development、production。
none:不会启用Webpack的任何优化插件,基本上不使用。development:自动优化打包速度,启用内置插件更好的捕捉错误,便于代码调试。production:启动内置插件优化打包结果,不过打包速度偏慢,便于生产模式访问效率
三、你对loader了解多少,你们常用哪些loader呢,如果让你手写一个loader你有什么想法呢?
loader作为Webpack集成的对非js资源加载、Webpack工程化中功能处理的模块,我们项目中常见于对样式、图片、文字、音频、字体等文件的加载、对代码兼容、缓存等功能的支持所需要的loader如下。
style-loader:用于生成一个style标签,把css引入到页面中。css-loader:加载css资源。scss-loader:加载scss资源。postcss-loader:处理css浏览器的兼容,自动加上前缀。eslint-loader:代码规范化。url-loader:加载图片,文字等资源,通过publicPath生成一个路径,供外部成员调用。babel-loader:代码降级,解决兼容问题。- ...
如果让我写一个loader,那么我得根据loader的执行要求:我不管loader如何处理逻辑,但是返回的必须是一段可执行的JavaScript代码。
四、你对plugin了解多少,你们常用哪些plugin呢,如果让你手写一个plugin你有什么想法呢?
plugin顾名思义为"插件",它能够帮助我们做一下loader做不到的事情,比如代码压缩、打包结果的清除等等,项目中常见的plugin如下。
CleanWebpackPlugin:用于在每一次打包生成新的bundle.js之前,清除上一次的打包文件。HtmlWebpackPlugin:用于生成html文件。CopyWebpackPlugin:用于拷贝那些不需要参与打包的文件。MiniCssExtractPlugin:用于提取所有css文件。ProgressBarPlugin:打包可视化进度条。HotModuleReplacementPlugin:可用于热更新。DllReferencePlugin:分包拆包,webpack5中已经不再维护了,推荐使用Webpack的optimization配置项。
如果让我写一个plugin,那么我得根据plugin的执行要求:
- 每一个插件的本身就是一个函数。
- 每个函数内部都要实现一个
apply方法。 - 借助
webpack生命周期钩子,通过compiler对象访问钩子,帮我们把插件注入到webpack运行流程中执行。 - 根据需求编写我们的逻辑。
五、loader与plugin的区别在哪呢,你知道有两种引入css的方式吗,他们的区别呢?
loader与plugin的本质都是函数,但是loader要求必须返回可执行的JavaScript代码,而plugin则必须实现一个apply方法,且需要借助Webpack的生命钩子方才能执行,这就是他们最大的区别,其次loader也可以实现构建工程化里面的功能,比如babel-loader,但是按照约定俗成,我们直接把loader成为模块加载器,主要用于资源模块的加载,而plugin能够完成loader不能完成的的事情,只能说他是对loader功能的扩展,且他的功能更加丰富。
两种引入css的方式一种是style-loader,一种是MiniCssExtractPlugin
style-loader:生成style标签,引入到页面。MiniCssExtractPlugin:生成link标签,引入到页面。
六、Webpack的optimization有配置过吗?可以简单说说吗?
module.exports = {
...
optimization : {
splitChunks: {
// chunks: 'all' || 'async' || 'initial' , all与initial效果类似,async为异步模块
cacheGroups: {
commons: {
chunks: "initial",//相同的chunks提出来
minChunks: 2,//依赖了两个以上的关系
minSize: 0 //这个依赖最小体积为0
},
vendor: {
test: /node_modules/,
// 默认选项,表示只要有依赖的第三方包就要拆出去,跟all差不多
chunks: "initial",
name: "vendor",
enforce: true
}
}
},
usedExports: true, // 只导出外部成员引用模块
// 此属性用于模块导入合并,因为单独的模块导入要使用_webpack_require_函数。
// 此属性就是可以利用_webpack_require_一次性导入所有模块,也叫作用域提升。
concatenateModules: true,
minimize: true, // 开启代码压缩,或者配置压缩器
// minimizer:[ new OptimizeCssAssetsWebpackPlugin() new terser-webpack-plugin() ]
sideEffect: true,
}
}
七、Webpack的构建原理是怎样的呢?
npm run build就可以让webpack自动打包构建了,然后webpack会经历如下步骤。
webpack-cli启动。- 载入配置项参数,初始化
Compiler对象,加载所有配置项plugin。 - 使用
Compiler对象的run方法开始编译项目。 - 通过
entry找到入口文件,解析模块依赖,形成依赖树。 - 递归遍历依赖树,让
loader去加载对应的模块以及依赖模块。 - 合并
loader处理结果,组装成chunks,转换成文件,输出到build目录。
详见重学webpack系列(八) -- webpack的运行机制与工作原理
八、Webpack的HMR原理你知道吗,请简单说说?
HMR就是模块的热更新,核心原理就是创建一个本地服务器,通过与client建立socket链接,当依赖资源有更新的时候,能够实现正在运行中的模块热替换。具体参见重学webpack系列(七) -- webpack的HMR的实践与原理
九、treeShaking知道吗,说说他跟babel-loader是否产生冲突呢?
treeShanking顾名思义就是把代码中,没有被外部成员引用到的代码优化掉,起到压缩的作用,在production中,treeShaking是自动开启的。因为我们知道treeShaking是基于ESM生效的,那么我们在项目中配置了babel-loader会把ESM转为Common.js,那treeShaking是不是就失效了呢,在babel-loader中,禁用了babel对ESM的转化,所以treeShaking还是能够生效的。
module.exports = {
...
module:{
rules:[
{
test:'js',
use:{
loader: "babel-loader",
// 禁止开启对ESM模块的转变
options: { presets: [ ['@babel/preset-env', { "modules": false }] ] }
}
}
]
}
}
十、你能不能介绍一下Webpack5都新增了哪些特性呢,简单说说吧?
webpack5中,mode='production'自动开启。- 内置
terser-webpack-plugin插件,mode='production'自动压缩。 optimization.concatenateModules = true,作用域提升,模块合并。cache-loader废弃,持久化缓存,module.exports = { cache: { type: 'filesystem', // 文件系统 }, }asset module资源模块代替file-loader、url-loader。webpack server启动本地服务,详见webpack启动服务。- ......
十一、你了解Webpack的三种hash吗?请简单说说?
三种hash分别为文件hash,chunkhash,contenthash。
hash: 为打包后所有文件的hash,只要其中一个文件改变,此hash就会改变。chunkhash: 为不同文件的单独hash值,只要本身内容改变就会改变hash值。contenthash: 为不同文件单独hash,只要本身内容改变就会改变hash值,可用于解决外部依赖文件的变更,影响到自身的hash的变化的情况。
十二、Webpack的resolve配置项有用过吗,请简单说说他有什么作用?
可用作指定配置,告知Webpack以什么样的方式去构建,表现在:
- 别名:
alias - 文件类型:
extensions - 解析的模块范围:
modules
module.exports = {
resolve: {
alias:{
'@':'root/src' // 指定别名@,通过@可以找到文件目录
},
extensions:{
['.jsx', '.tsx', '.vue'] // 指定webpack需要解析哪些类型的文件
},
modules:{
['node_modules', 'root/src'] // 指定webpack需要解析那些范围的文件
}
}
}
十三、说一说你在项目中做了Webpack层面的哪些优化呢,以及你所了解的Webpack层面的优化?
详见重学webpack系列(九) -- webpack的高级特性与前端性能优化
展望
这篇文章与上一篇文章更新隔了20多天,下一个系列前端构建工具vite进阶系列,搁浅的也有些时间了,所以接下来的主要创作时间就放在了这个上面,同时也希望跟各位同学一起交流学习心得。