[前端社招面试]网易·灵犀一二三面凉经
1. 聊项目
2. webpack和rollup的区别,打包出来的产物有啥区别?
3. postcss的原理
4. webpack babel vue都用到了 AST,你是怎么理解AST的
5. 如何提高webpack的构建速度
6. 用到了vite了么 ?为什么会快
7. npm打包时需要注意哪些?如何利用webpack来更好的构建?
<di>NPM模块需要注意以下问题:
- 要支持CommonJS模块化规范,所以要求打包后的最后结果也遵守该规则。
- Npm模块使用者的环境是不确定的,很有可能并不支持ES6,所以打包的最后结果应该是采用ES5编写的。并且如果ES5是经过转换的,请最好连同SourceMap一同上传。
- Npm包大小应该是尽量小(有些仓库会限制包大小)
- 发布的模块不能将依赖的模块也一同打包,应该让用户选择性的去自行安装。这样可以避免模块应用者再次打包时出现底层模块被重复打包的情况。
- UI组件类的模块应该将依赖的其它资源文件,例如.css文件也需要包含在发布的模块里。
基于以上需要注意的问题,我们可以对于webpack配置做以下扩展和优化:
- CommonJS模块化规范的解决方案: 设置output.libraryTarget='commonjs2'使输出的代码符合CommonJS2 模块化规范,以供给其它模块导入使用
- 输出ES5代码的解决方案:使用babel-loader把 ES6 代码转换成 ES5 的代码。再通过开启devtool: 'source-map'输出SourceMap以发布调试。
- Npm包大小尽量小的解决方案:Babel 在把 ES6 代码转换成 ES5 代码时会注入一些辅助函数,最终导致每个输出的文件中都包含这段辅助函数的代码,造成了代码的冗余。解决方法是修改.babelrc文件,为其加入transform-runtime插件
- 不能将依赖模块打包到NPM模块中的解决方案:使用externals配置项来告诉webpack哪些模块不需要打包。
8. 如何在vue项目中实现按需加载
Vue UI组件库的按需加载 为了快速开发前端项目,经常会引入现成的UI组件库如ElementUI、iView等,但是他们的体积和他们所提供的功能一样,是很庞大的。 而通常情况下,我们仅仅需要少量的几个组件就足够了,但是我们却将庞大的组件库打包到我们的源码中,造成了不必要的开销。
不过很多组件库已经提供了现成的解决方案,如Element出品的babel-plugin-component和AntDesign出品的babel-plugin-import 安装以上插件后,在.babelrc配置中或babel-loader的参数中进行设置,即可实现组件按需加载了。
单页应用的按需加载 现在很多前端项目都是通过单页应用的方式开发的,但是随着业务的不断扩展,会面临一个严峻的问题——首次加载的代码量会越来越多,影响用户的体验。
通过import(*)语句来控制加载时机,webpack内置了对于import(*)的解析,会将import(*)中引入的模块作为一个新的入口在生成一个chunk。 当代码执行到import(*)语句时,会去加载Chunk对应生成的文件。import()会返回一个Promise对象,所以为了让浏览器支持,需要事先注入Promise polyfill
1、怎么保证相同的文件只加载一次?
答:定义installedChunks对象,存储异步js的promise回调,如果已经加载过,则返回一个空数组的promise.all([]),如果在加载过程中,则返回已经存储过的此文件对应的promise。
2、怎么判断文件加载完成?
答:1、在主文件中定义一个全局数组,并重写其push方法,在异步文件中执行此全局数组的push方法。
2、在重写的方法中执行promise的resolve回调。
9. webpack 怎么来优化前端性能
用webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运行快速高效。
- 压缩代码。删除多余的代码、注释、简化代码的写法等等方式。可以利用webpack的UglifyJsPlugin和ParallelUglifyPlugin来压缩JS文件, 利用cssnano(css-loader?minimize)来压缩css
- 利用CDN加速。在构建过程中,将引用的静态资源路径修改为CDN上对应的路径。可以利用webpack对于output参数和各loader的publicPath参数来修改资源路径
- 删除死代码(Tree Shaking)。将代码中永远不会走到的片段删除掉。可以通过在启动webpack时追加参数--optimi***imize来实现
- 提取公共代码。
10. 是否写过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 改变输出结果1. 实现一下new 操作符
网络协议是计算机之间为了实现网络通信而达成的一种约定或者规则,有了这种规则,不同厂商的生产设备,以及不同操作系统组成的计算机之间,就可以实现通信
11. 实现 Array 中的 reduce 方法
12. 算法题
//实现一个数字计数器,规则:连续的数字或字符是记为1,中文,每一个字记为1, //数字或者字符中间有特殊符号的,则特殊符号看作空格,即,特殊字符前后都记为1, //例如:111asg 哈哈 123@abc => 5;111asg => 1; 哈哈 => 2; 123@abc => 2 //中文:\u4E00-\u9FFF
二面
1. 聊简历,聊项目
网络协议是计算机之间为了实现网络通信而达成的一种约定或者规则,有了这种规则,不同厂商的生产设备,以及不同操作系统组成的计算机之间,就可以实现通信
2. vue中的nexttick的原理
网络协议是计算机之间为了实现网络通信而达成的一种约定或者规则,有了这种规则,不同厂商的生产设备,以及不同操作系统组成的计算机之间,就可以实现通信
3. vue的响应式原理
网络协议是计算机之间为了实现网络通信而达成的一种约定或者规则,有了这种规则,不同厂商的生产设备,以及不同操作系统组成的计算机之间,就可以实现通信
4. 小程序的架构
5. 小程序如何跟native层通信的
6. 算法题-1
// 求字符串公共前缀,例如 ['abcaaa', 'abcddd', 'abcadad'] ==> 'abc' function comStr(arr = []) { let commonStr = ''; if(!arr.length) { return commonStr; } arr.sort((a, b) => a.length - b.length); const firstStr = arr[0]; let c = 0; while(c < firstStr.length) { for(let i = 1; i < arr.length; i++) { if(firstStr[c] !== arr[i][c]) { return commonStr; } } commonStr += firstStr[c]; c++; } return commonStr; }
7. 算法题-2
// 区间合并: // 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。 // 请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。 // 示例 1: // 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] // 输出:[[1,6],[8,10],[15,18]] // 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. // 示例 2: // 输入:intervals = [[1,4],[4,5]] // 输出:[[1,5]] // 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。 function merge(intervals = []) { if(!intervals.length) { return []; } intervals.sort((a, b) => a[0] - b[0]); let c = 0, res = [intervals.shift()]; while(intervals.length) { const next = intervals.shift(); if(next[0] >= res[c][0] && next[0] <= res[c][1]) { const resVal = Math.max(next[1], res[c][1]); res[c] = [res[c][0], resVal]; } else { c++; res[c] = next; } } return res; }
8. 算法题-1
// 仿模板字符串处理功能, // 如 "Title: ${ title }, MainArtist: ${ artist[0] }, Album: ${ album.name }", // { // title: '珊湖海', // artist: ['周杰伦', '梁心颐'], // album: { // publishTime: '2006-11-1', // name: '十一月的萧邦' // } // }; function template(templateString, obj) { return templateString.replace(/\${([^{}]*)}/g, function(match, p1) { with(obj) { return eval(p1.trim()); }; }); } const str = "Title: ${ title }, MainArtist: ${ artist[0] }, Album: ${ album.name }"; const obj = { title: '珊湖海', artist: ['周杰伦', '梁心颐'], album: { publishTime: '2006-11-1', name: '十一月的萧邦' } }; console.log(template(str,obj));
三面
1. 聊简历,聊项目
2. 算法题
知道美团过去一年的股票价格,计算出什么点买入什么点卖出,收益最大? 讲了思路: 1.先遍历所有价格找出最大波峰及时间点;以这个时间点为界限,往前找股价最低点,求出差值;以这个差值为比较基准; 2. 从波峰时间点往后,在遍历所有价格,求出价格最大值及时间点;求出差值;跟基准比较,取大值; 3. 重复第二步的步骤,直到遍历完所有价格
最后
最后,就没有然后了,没有等到HR面,凉的很彻底.
#前端面试##网易##社招##面经#