公司面试题总结(六)

31.说一说 webpack 的构建流程是什么?

初始化流程:

◼ 从配置文件和 Shell 语句中读取与合并参数
◼ 初始化需要使用的插件和配置插件等执行环境所需要的参数

编译构建流程:

◼ 从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容
◼ 再找到该 Module 依赖的 Module,递归地进行编译处理

输出流程:

◼ 对编译后的 Module 组合成 Chunk,
◼ 把 Chunk 转换成文件,输出到文件系统

32.如何优化 webpack 打包速度

并行编译:

thread-loader: 利用多个 CPU 内核并行运行加载器。
HappyPack : 将模块转换任务分解到多个 worker 进程中并行处理。

代码拆分

splitChunksPlugin 代码分割,将公共代码、第三方库等抽离到单独的 chunk,减
少重复编译的工作量。

动态导入(import())

◼ 根据路由或其他条件按需加载代码,避免一次性打包所有代码。

Tree Shaking:

◼ 确保你的 ES 模块使用的是静态导入导出, Tree Shaking 移除未使用的代码。

DllPlugin/DllReferencePlugin:

◼ 不经常变动的依赖(如 React, Vue 库)提前打包成 DLL(动态链接库) ,避免每次
构建都重新打包这些库。

减少 Loader 和 Plugin 的数量

◼ 只使用必要的 loader 和 plugin,每个额外的处理都会增加构建时间。

提升 Loader 性能:

◼ Babel 等慢速 loader,使用针对性的配置优化,比如@babel/preset-env 的
useBuiltIns 和 targets 选项,减少不必要的 polyfill。

Excluding node_modules:

◼ 不需要转译的 node_modules 模块,可以在.babelrc 或 webpack 配置中排除它们。

Cache:

◼ 利用 Webpack 的持久化缓存特性,如 cacheDirectory 选项,或使用 hard-source
webpack-plugin 等第三方插件来缓存编译结果。

优化 Resolving 配置:

◼ 减少模块解析的搜索范围,通过 resolve.modules, resolve.alias 等配置项提高模块 查找速度。

Source Map 优化:

◼ 开发环境使用 cheap-module-eval-source-map 或更快的 source-map 选项,生产
环境考虑是否需要 source map 或使用更简洁的格式。

升级 Webpack 和其他依赖

◼ 保持 Webpack 及其相关 loader、plugin 的版本是最新的,新版本往往带来性能改
进。

分析和监控:

◼ 使用 webpack-bundle-analyzer 分析包大小,找出可以进一步优化的地方。

33.说说 webpack 中常见的 Loader?解决了什么问题?

⚫ loader 对模块的"源代码"进行转换,
⚫ 在 import 或"加载"模块时预处理文件
⚫ webpack 分析各种模块依赖关系,然后形成资源列表,最终打包生成到指定的文件中。
babel-loader :用 babel 来转换 ES6 文件到 ES5
html-minify-loader: 压缩 HTML
style-loader: 将 css 添加到 DOM 的内联样式标签 style 里
css-loader : 允许将 css 文件通过 require 的方式引入,并返回 css 代码
less-loader: 处理 less → css
sass-loader: 处理 sass → css
postcss-loader: 用 postcss 来处理 CSS
autoprefixer-loader: 处理 CSS3 属性前缀,已被弃用,建议直接使用 postcss
file-loader: 分发文件到 output 目录并返回相对路径
url-loader: 和 file-loader 类似,但是当文件小于设定的 limit 时可以返回一个 Data Url

34.说说 webpack 中常见的 Plugin?解决了什么问题?

⚫ Plugin(Plug-in)是一种计算机应用程序,它和主应用程序互相交互,以提供特定的功

⚫ 是一种遵循一定规范的应用程序接口编写出来的程序,只能运行在程序规定的系统下,
因为其需要调用原纯净系统提供的函数库或者数据
⚫ webpack 中的 plugin 也是如此,plugin 赋予其各种灵活的功能,例如打包优化、资源
管理、环境变量注入等,它们会运行在 webpack 的不同阶段(钩子 / 生命周期),贯穿
了 webpack 整个编译周期
HtmlWebpackPlugin
◼ 在打包结束后,自动生成一个 html 文文件,
◼ 并把打包生成的 js 模块引入到该 html 中
clean-webpack-plugin 删除(清理)构建目录
mini-css-extract-plugin 提取 CSS 到一个单独的文件中
DefinePlugin 允许在编译时创建配置的全局对象,是一个 webpack 内置的插件,不需
要安装
copy-webpack-plugin
◼ 复制文件或目录到执行区域,
◼ 如 vue 的打包过程中,如果我们将一些文件放到 public 的目录下,那么这个目录
会被复制到 dist 文件夹中

35.请详细说说 webpack 中的 plugin 和 loader 之间的区别是****什么?

loader

◼ 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩
等,最终一起打包到指定的文件中

plugin

赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事

36.说说你对 promise 的了解

Promise 承诺 ,异步编程的一种解决方案,比传统解决方案(回调函数)更合理和更加强大
回调函数 形成了经典的回调地狱

promise 解决异步操作的优点:

⚫ 链式操作减低了编码难度
⚫ 代码可读性明显增强
⚫ 状态

promise 对象仅有三种状态

⚫ pending(进行中)
⚫ fulfilled(已成功)
⚫ rejected(已失败)
对象的状态不受外界影响,只有异步操作的结果,可以决定当前状态

用法

⚫ Promise 对象是一个构造函数,用来生成 Promise 实例
const promise = new Promise(function(resolve, reject) {});
⚫ Promise 构造函数接受一个函数作为参数,函数的两个参数分别是 resolve 和 reject
resolve 函数: 将 Promise 对象的状态从"未完成"变为"成功"
reject 函数: 将 Promise 对象的状态从"未完成"变为"失败"

实例方法 then() catch() finally()

then()

◼ 实例状态发生改变时的回调函数
◆ 第一个参数是 resolved 状态的回调函数,
◆ 第二个参数是 rejected 状态的回调函数
◼ then 方法返回的是一个新的 Promise 实例,也就是 promise 能链式书写的原因

catch()

.then(null, rejection)或.then(undefined, rejection) 的别名,
◼ 用于指定发生错误时的回调函数
◼ Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止
◼ 一般来说,使用 catch 方法代替 then()第二个参数

finally()

◼ 用于指定不管 Promise 对象最后状态如何,都会执行的操作

构造函数方法 all() race() allSettled() resolve() reject()

all()

◼ Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.all([p1, p2, p3]);
◼ 接受一个数组作为参数,数组成员都为 Promise 实例
◼ 实例 p 的状态由 p1、p2、p3 决定,分为两种: ◆ 只有 p1、p2、p3 的状态都变成 fulfilled,p 的状态才会变成 fulfilled,此时 p1、
p2、p3 的返回值组成一个数组,传递给 p 的回调函数
◆ 只要 p1、p2、p3 之中有一个被 rejected,p 的状态就变成 rejected,此时第
一个被 reject 的实例的返回值,会传递给 p 的回调函数
◼ 注意,如果作为参数的 Promise 实例,自己定义了 catch 方法,那么它一旦被
rejected,并不会触发 Promise.all()的 catch 方法

race()

◼ Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.race([p1, p2, p3]);
◼ 只要 p1、p2、p3 之中有一个实例率先改变状态,p 的状态就跟着改变
◼ 率先改变的 Promise 实例的返回值则传递给 p 的回调函数

allSettled()

◼ Promise.allSettled()方法接受一组 Promise 实例作参数,包装一个新 Promise 实例
◼ 只有等到所有这些参数实例都返回结果,不管是 fulfilled 还是 rejected,包装实例
才会结束
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();

resolve()

◼ 将现有对象转为 Promise 对象
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
◼ 参数可以分成四种情况:
◆ 参数是一个 Promise 实例,promise.resolve 将不做任何修改、原封不动地返
回这个实例
◆ 参数是一个thenable对象,promise.resolve会将这个对象转为 Promise对象,
然后就立即执行 thenable 对象的 then()方法
◆ 参数不是具有 then()方法的对象,或根本就不是对象,Promise.resolve()会返
回一个新的 Promise 对象,状态为 resolved
◆ 没有参数时,直接返回一个 resolved 状态的 Promise 对象

reject()

◼ Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为
rejected
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

使用场景

⚫ 将图片的加载写成一个 Promise,一旦加载完成,Promise 的状态就发生变化 ⚫ 通过链式操作,将多个渲染数据分别给个 then,让其各司其职。或当下个异步请求依
赖上个请求结果的时候,我们也能够通过链式操作友好解决问题
⚫ 通过 all()实现多个请求合并在一起,汇总所有请求结果,只需设置一个 loading 即可
⚫ 通过 race 可以设置图片请求超时

相关推荐
lyllovelemon4 小时前
🍭🍭🍭五分钟带你掌握next国际化最佳实践
前端·react.js·面试
ZShiJ5 小时前
【题解】—— LeetCode一周小结27
算法·leetcode·职场和发展
mm9954205 小时前
取得了PMP证书后有哪些优势?不清楚的快来看!
经验分享·学习·职场和发展·项目管理
振华首席娱记5 小时前
代码随想录——划分字母区间(Leetcode763)
java·数据结构·算法·leetcode·职场和发展
danaaaa6 小时前
算法力扣刷题总结篇 ——【四】
数据结构·c++·算法·leetcode·职场和发展
test6388 小时前
使用ThreadLocal存储用户登录信息
java·后端·面试
施展TIGERB8 小时前
程序员如何做"好"需求判断?
面试·程序员·团队管理
青青草原上的梦想家8 小时前
游戏开发面试题7
开发语言·游戏·面试
杰哥在此12 小时前
Python面试题:如何在 Python 中读取和写入 JSON 文件?
开发语言·python·面试·json·编程
惜了梦i12 小时前
【leetcode周赛记录——405】
算法·leetcode·职场和发展