公司面试题总结(六)

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 可以设置图片请求超时
  • 45
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值