webpack面试题整理

gulp/grunt 与 webpack的区别是什么?

三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。

grunt和gulp是基于任务和流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。

webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。

参考资料:关于webpack的面试题总结 - 腾讯云开发者社区-腾讯云

webpack是解决什么问题而生的?

如果像以前开发时一个html文件可能会引用十几个js文件,而且顺序还不能乱,因为它们存在依赖关系,同时对于ES6+等新的语法,less, sass等CSS预处理都不能很好的解决……,此时就需要一个处理这些问题的工具。

Webpack就是为处理这些问题而生的。

参考资料:webpack4.x最详细入门指南_先生姓陈的技术博客_51CTO博客

webpack如何配置多入口文件?

entry: {
 home: resolve(__dirname, "src/home/index.js"),
 about: resolve(__dirname, "src/about/index.js")
}

注意想想要不要多个出口

参考资料:入口起点(entry points) | webpack 中文文档

你是如何提高webpack构件速度的?

多入口情况下,使用CommonsChunkPlugin来提取公共代码
通过externals配置来提取常用库
利用DllPlugin和DllReferencePlugin预编译资源模块通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。
使用Happypack 实现多线程加速编译
使用webpack-uglify-paralle来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度
使用Tree-shaking和Scope Hoisting来剔除多余代码

参考资料:抱歉,站点已注销

利用webpack如何优化前端性能? 

同上条,另外加:

给打包出来的文件名添加哈希,实现浏览器缓存文件

webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全.

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

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

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

参考资料:关于webpack的面试题总结 - 腾讯云开发者社区-腾讯云

简述如何写一个loader/plugin

Loader像一个"翻译官"把读到的源文件内容转义成新的文件内容,并且每个Loader通过链式操作,将源文件一步步翻译成想要的样子。

编写Loader时要遵循单一原则,每个Loader只做一种"转义"工作。 每个Loader的拿到的是源文件内容(source),可以通过返回值的方式将处理后的内容输出,

也可以调用this.callback()方法,将内容返回给webpack。 还可以通过 this.async()生成一个callback函数,再用这个callback将处理后的内容输出出去。 此外webpack还为开发者准备了开发loader的工具函数集——loader-utils。

相对于Loader而言,Plugin的编写就灵活了许多。 webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

参考资料:关于webpack的面试题总结 - 腾讯云开发者社区-腾讯云

如何提高构建/编译速度,并解答每个方案的原理

wepback的可视化资源分析工具:webpack-bundle-analyzer

慢在何处:
从项目结构着手,代码组织是否合理,依赖使用是否合理;
从webpack自身提供的优化手段着手,看看哪些api未做优化配置;
从webpack自身的不足着手,做有针对性的扩展优化,进一步提升效率;

方案一、合理配置 CommonsChunkPlugin
原理是当有多个entry入口时,把它们可能共有的公共模块提取出来

方案二、通过 externals 配置来提取常用库
简单来说external就是把我们的依赖资源声明为一个外部依赖,
然后通过script外链脚本引入。这也是我们早期页面开发中资源引入的一种翻版,
只是通过配置后可以告知webapck遇到此类变量名时就可以不用解析和编译至模块的内部文件中,
而改用从外部变量中读取,这样能极大的提升编译速度,同时也能更好的利用CDN来实现缓存。

方案三、利用 DllPlugin 和 DllReferencePlugin 预编译资源模块
简单来说DllPlugin的作用是预先编译一些模块,
而DllReferencePlugin则是把这些预先编译好的模块引用起来。

方案四、使用 Happypack 加速你的代码构建
happypack的处理思路是
将原有的webpack对loader的执行过程从单一进程的形式扩展多进程模式,
原本的流程保持不变,这样可以在不修改原有配置的基础上来完成对编译过程的优化。

方案五、增强 uglifyPlugin
使用webpack-uglify-parallel来提升压缩速度。
webpack-uglify-parallel的是实现原理是采用了多核并行压缩的方式来提升我们的压缩速度。

方案六、Tree-shaking & Scope Hoisting
利用es6的module特性,
利用AST对所有引用的模块和方法做了静态分析,
从而能有效地剔除项目中的没有引用到的方法,
并将相关方法调用归纳到了独立的webpack_module中

参考资料:webpack三两事:浅入深出-原理解析构建优化_mb600becf249518的技术博客_51CTO博客

资源体积减小方案

Webpack如何打包才能尽可能的缩小体积(详解)_拼搏的小叔的博客-CSDN博客_webpack 减小包体积

构建速度加快方案

webpack之优化篇(二):优化配置提高构建速度_i大俊的博客-CSDN博客

3. babel 相关: polyfill 以及 runtime 区别, ES stage 含义,preset–env 作用等等


1.polyfill 以及 runtime 区别
babel-polyfill 的原理是当运行环境中并没有实现的一些方法,babel-polyfill会做兼容。
babel-runtime 它是将es6编译成es5去执行。我们使用es6的语法来编写,最终会通过babel-runtime编译成es5.也就是说,不管浏览器是否支持ES6,只要是ES6的语法,它都会进行转码成ES5.所以就有很多冗余的代码。
babel-polyfill 它是通过向全局对象和内置对象的prototype上添加方法来实现的。比如运行环境中不支持Array.prototype.find 方法,引入polyfill, 我们就可以使用es6方法来编写了,但是缺点就是会造成全局空间污染。
babel-runtime: 它不会污染全局对象和内置对象的原型,比如说我们需要Promise,我们只需要import Promise from 'babel-runtime/core-js/promise'即可,这样不仅避免污染全局对象,而且可以减少不必要的代码。

2.
stage-x:指处于某一阶段的js语言提案

Stage 0 - 设想(Strawman):只是一个想法,可能有 Babel插件。
Stage 1 - 建议(Proposal):这是值得跟进的。
Stage 2 - 草案(Draft):初始规范。
Stage 3 - 候选(Candidate):完成规范并在浏览器上初步实现。
Stage 4 - 完成(Finished):将添加到下一个年度版本发布中。

3. 理解 babel-preset-env
比如:
babel-preset-es2015: 可以将es6的代码编译成es5.
babel-preset-es2016: 可以将es7的代码编译为es6.
babel-preset-es2017: 可以将es8的代码编译为es7.
babel-preset-latest: 支持现有所有ECMAScript版本的新特性

参考资料

https://www.iteye.com/blog/wx1568487608-2457500
Babel配置中的presets、plugins、各个阶段stage的含义

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值