achen的个人博客

一个能力有限的前端


  • 首页

  • 归档49

  • 公益 404

  • 搜索

你真的理解 Webpack?

发表于 2020-09-07 | 更新于 2020-09-10

webpack 实战

1. 与 Webpack 类似的工具还有哪些
  • webpack

适用于大型复杂的前端站点构建

  • [https://rollupjs.org/]rollup

rollup适用于基础库的打包,如vue、react

  • [https://parceljs.org/]parcel

parcel适用于简单的实验性项目,他可以满足低门槛的快速看到效果parcel

2. 谈谈你为什么选择使用或放弃 webpack
3. Loader 和 Plugin 的不同
不同的作用
  • Loader 直译为”加载器”。webpack 将一切文件视为模块, 但是 webpack 原生是只能解析 js 文件, 如果想将其他文件也打包的话, 就会用到 loader。
    所以 loader 的作用是让 webpack 拥有加载和解析非 JavaScript 文件的能力。

  • Plugin 直译为”插件”。 Plugin 可以扩展 webpack 的功能, 让 webpack 具有更多的灵活性。在 webpack 运行的生命周期中会广播出许多事件, Plugin 可以
    监听这些事件, 在合适的时机

不同的用法
  • Loader 在 module.rules 中配置, 也就是说他作为模块的解析规则而存在。类型为数组, 每一项都是一个 Object, 里面描述了对于什么类型的文件(test), 使用什么
    加载(loader)和使用的参数(options)。

  • Plugin 在 Plugins 中单独配置。类型为数组, 每一项是一个 Plugin 的实例, 参数都通过构造函数传入。

4. 有哪些常见的 Loader?他们能解决什么问题?
  • file-loader: 把文件输出到一个文件夹中, 在代码中通过相对 URL 去引用输出的文件
  • url-loader: 和 file-loader 类似, 但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
  • source-map-loader: 加载额外的 Source Map 文件, 以方便断点调试
  • image-loader: 加载并且压缩图片文件
  • babel-loader: 把 ES6 转换成 ES5
  • css-loader: 加载 CSS, 支持模块化、压缩、文件导入等特性
  • style-loader: 把 CSS 代码注入到 JavaScript 中, 通过 DOM 操作去加载 CSS
  • eslint-loader: 通过 ESLint 检查 JavaScript 代码
5. 有哪些常见的 Plugin?他们能解决什么问题?
  • define-plugin: 定义环境变量
  • uglifujs-webpack-plugin: 通过 UglifyES 压缩 ES6 代码
  • commons-chunk-plugin: 提取公共代码
6. 如何利用 Webpack 来优化前端性能

用 webpack 优化前端性能是指优化 webpack 的输出结果, 让打包的最终结果在浏览器运行快速高效。

  • 压缩代码。
  • 利用 CDN 加速。
  • 删除多余代码(Tree Shaking)。
  • 提取公共代码。
7. 如何提高 Webpack 的构建速度?
  • 多入口情况下, 使用 CommonsChunkPlugin 来提取公共代码。
  • 通过 externals 配置来提取常用库
  • 利用 DllPlugin 和 DllReferencePlugin 预编译资源模块 通过 Dll来对那些我们引用但是绝对不会修改的 npm 包来
    进行预编译, 再通过 DllReferencePlugin 将预编译的模块加载进来。
  • 使用 HappyPack 实现多线程加速编译。
  • 使用 webpack-uglify-parallel 来提升 uglifyPlugin 的压缩速度。原理上 webpack-uglify-parallel 采用了多核并行
    压缩来提升压缩速度。
  • 使用 Tree-shaking 和 Scope Hoisting 来剔除多余代码。
8. 如何对 bundle 体积进行监控和分析?
9. 怎么配置单页应用?怎么配置多页应用?
10. 如何在 Vue 和 React 项目中实现按需加载?
11. monorepo 这种项目有什么好处,具体是如何打包的?
12. Source Map 是什么?生产环境怎么用?
13. 什么是长缓存?
14. 在 Webpack 中如何做到长缓存优化?
15. Webpack 中 hashchunkhashcontenthash 有什么区别?

Webpack 原理

1. Webpack 的构建流程是什么?
2. 是否写过 Loader ?描述一下编写 Loader 的思路?
3. 是否写过 Plugin ?描述一下编写 Plugin 的思路?
4. inlineprepostnormalloader 执行先后顺序是?
5. Webpack 打包的原理是什么?聊一聊 babel 和抽象语法树
6. dev-server 的原理是什么?描述一下它的具体流程
7. 请说一下 DIlPlugin 和 DllReferencePlugin 的工作原理
8. Webpack 的热更新是如何做到的?说明其原理?
9. Tree shaking了解过么?它的实现原理说一下

Webpack 5

1. Webpack 5 中有哪些新特性
2. Webpack 5 中的 Module Federation 对微前端的意义

URI、URL、URN

发表于 2020-07-08

URI

Uniform Resource Identifier/统一资源标志符

用来唯一标识互联网上的信息资源

包括 URL 和 URN

URL

Uniform Resource Locator/统一资源定位器

URN

永久统一资源定位符

在资源移动之后还能被找到

目前还没有非常成熟的使用方案

curl

发表于 2020-07-08 | 更新于 2020-07-09

curl 是一个命令行工具,用来请求 web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

不带有任何参数时,curl 就是发出 get 请求。

1
curl www.baidu.com

上面的命令向 www.baidu.com 发出 get 请求,服务器返回的内容会在命令行输出。

-b

-b 参数用来向服务器发送 cookie

1
curl -b 'foo=bar' www.baidu.com
-c

-c 参数将服务器设置的 cookie 写入一个文件

1
curl -c cookies.txt www.baidu.com
-d

-d 参数用来发送 post 请求

1
2
3
curl -d 'login=emma&password=123' -X POST www.baidu.com
# 或者
curl -d 'login=emma' -d 'password=123' -X POST www.baidu.com

使用 -d 参数以后, HTTP 请求会自动加上表头 Content-Type: application/x-www-form-urlencoded。并且
会自动将请求转为 POST 方法,因此可以省略 -X POST。

-d 参数也可以读取本地文本文件的数据,向服务器发送。

1
curl -d '@data.txt' www.baidu.com
-v

-v 参数输出通信的整个过程,用于调试。

1
curl -v www.baidu.com

– trace 参数也可以用于调试,还会输出原始的二进制数据。

1
curl --trace - www.baidu.com

未命名

发表于 2020-07-06 | 更新于 2020-07-10
function quickSort(arr) { if (arr.length <= 1)="" return="" arr;="" const="" index="Math.floor(arr.length" 2);="" 如果此处使用="" midval="arr[index];" 那么将会出现无限递归的错误;="" 1);="" left="[];" right="[];" for="" (let="" i="0;" <="" arr.length;="" i++)="" {="" if="" (arr[i]="" midval)="" left.push(arr[i]);="" }="" else="" right.push(arr[i]);="" quicksort(left).concat(midval,="" quicksort(right));="" var="" test1="quickSort([2,1,3,4,1,2,5,2,7,2,10,21,8,9]);" console.log(test1);="" function="" b(arr)="" j="i" +="" 1;="" j++)=""> arr[j]) { [arr[i], arr[j]] = [arr[j], arr[i]]; } } } return arr; } function curry(fn, args = []) { return function result() { const rest = [...args, ...arguments]; if (rest.length < fn.length) { return curry.call(this, fn, rest); } else { return fn.apply(this, rest); } } } document.getElementById('btn').onclick = function () { Print('#wrap', { onStart: function () { console.log('onStart', new Date()) }, onEnd: function () { console.log('onEnd', new Date()) } }) }

less

发表于 2020-05-25

如何使用

使用less有两种方式:

  1. 在页面中引入 less.js
1
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script>
  1. npm 安装
1
npm install less -g

具体使用命令 > styles.css

1
lessc styles.less

变量

  1. 值变量
1
2
3
4
@color: #000;
#wrap {
color: @color;
}
  1. 选择器变量
1
2
3
4
5
6
7
8
9
//变量名 必须使用大括号包裹
@mySelector: #wrap;
@Wrap: wrap;
@{mySelector} {
}
.@{Wrap} {
}
#@{Wrap} {
}
  1. 属性变量
1
2
3
4
5
6
7
8
9
10
@borderStyle: border-style;
@Soild: solid;
#wrap{
@{borderStyle}: @Soild;//变量名 必须使用大括号包裹
}

/* 生成的 CSS */
#wrap{
border-style: solid;
}
  1. url 变量
1
2
3
4
5
6
7
8
9
@images: "../img";//需要加引号
body {
background: url("@{images}/dog.png");//变量名 必须使用大括号包裹
}

/* 生成的 CSS */
body {
background: url("../img/dog.png");
}

JS运行机制

发表于 2020-05-14

JS运行机制

  • 理解 JS 的单线程概念
  • 理解任务队列
  • 理解 EventLoop
  • 理解哪些语句会放入异步任务队列
  • 理解语句放入异步任务队列的时机

为什么 JavaScript 是单线程

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。
JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

任务队列

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

1
2
3
4
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

宏任务 & 微任务

  • 宏任务(macro-task): 整体代码script、setTimeOut、setInterval
  • 微任务(mincro-task):promise.then、promise.nextTick(node)、async/await、MutationObserver

网络协议

发表于 2020-05-13 | 更新于 2020-05-14

https 如何建立连接, TLS 加密方式以及握手的流程

HTTPS其实是HTTP + SSL / TLS 两部分组成,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

进行三次握手,建立TCP连接。

  1. 第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
  2. 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

SSL握手过程

  1. 第一阶段 客户端发起请求,以明文传输请求信息,建立安全能力 包括协议版本 会话Id 密码构件 压缩方法和初始随机数
  2. 第二阶段 服务器发送证书 密钥交换数据和证书请求,最后发送请求-相应阶段的结束信号
  3. 第三阶段 如果有证书请求客户端发送此证书 之后客户端发送密钥交换数据 也可以发送证书验证消息
  4. 第四阶段 变更密码构件和结束握手协议

知识点

发表于 2020-04-21 | 更新于 2020-04-29

img的src也可以跨域吗

原理上都是利用标签的src可绕过同源限制,跨域请求的特点,

硬要说不同,那么区别在于:img只能单向发送get请求,不可访问响应内容(只是展现),而script可对其进行解析

实现斐波那契数列并利用缓存进行优化

redux中connect()的作用

连接 React 组件与 Store 的作用。

redux-saga的作用

http中的option方法的应用场景

OPTIONS方法请求web服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。

前端预检的过程

一、为什么要发预检请求?

出于安全考虑,浏览器会限制从脚本发起的跨域 http 请求,像 XMLHttpRequest 和 Fetch 都遵循同源策略。
浏览器限制跨域请求一般有两种方式:

  1. 浏览器限制发起跨域请求
  2. 跨域请求跨域正常发起,但是返回的结果被浏览器拦截

一般浏览器都是第二种方式限制跨域请求,那就是说请求已到达服务器,并有可能对数据库里的数据进行了操作,但是返回的结果被浏览器拦截了,那么我们就获取不到返回结果,这是一次失败的请求,但是可能对数据库里的数据产生了影响。

为了防止这种情况的发生,规范要求,对这种可能对服务器数据产生副作用的HTTP请求方法,浏览器必须先使用OPTIONS方法发起一个预检请求,从而获知服务器是否允许该跨域请求:如果允许,就发送带数据的真实请求;如果不允许,则阻止发送带数据的真实请求。

二、什么时候发预检请求

http请求包括:简单请求 和 复杂请求。

  1. 简单请求

简单请求不会触发 CORS 预检请求。
若满足以下条件,则可视为“简单请求”:

  • get
  • head
  • post

仅当 post 方法的 Content-Type 值等于下列之一才算简单请求

text-plain
multipart/form-data
application/x-www-form-unlenceded

  1. 复杂请求(需预检的请求)

“需预检的请求”要求必须首先使用OPTIONS方法发起一个预检请求到服务区,以获知服务器是否允许该实际请求。“预检请求”的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

当请求满足下述任一条件时,即应首先发送预检请求:
使用了下面任一 HTTP 方法:

  • put
  • delete
  • connect
  • options
  • trace
  • patch

移动端怎么解决12px字体的问题,怎么解决0.5px的线条

移动端手指触碰后的事件api触发顺序

react 的虚拟 dom 是怎么实现的

react 的渲染过程中,兄弟节点之间是怎么处理的?也就是 key 值不一样的时候。

你说一下 webpack 的一些 plugin,怎么使用 webpack 对项目进行优化

scoped是怎么实现的,追问为什么加deep能穿透样式?(可以说说 :global 的实现)

为什么字体大小最小设置成12px?

因为 Chrome 这款任性的浏览器做了如下限制:

  1. font-size 有一个最小值 12px(不同操作系统、不同语言可能限制不一样),低于12px的,一律按12px显示。理由是 Chrome 认为低于12px的中文对人类是不友好的。
  2. 但是允许你把 font-size 设置为0
  3. 这个12px的限制用户是可以自行调整的,进入 chrome://setting/fonts 设置。

如果一定要使用小于12px的字号,可以使用 transform: scale(0.9), 缩放的方式来解决。

Mac 下测试 Chrome、Firefox、Safire 浏览器,只有 Chrome 有这个限制。

我现在有一个数组[1,2,3,4],请实现算法,得到这个数组的全排列的数组,如[2,1,3,4],

时间复杂度

我现在有一个背包,容量为 m,然后有 n 个货物,重量分别为 w1,w2,w3…wn,每个货物的价值是 v1,v2,v3…vn,w 和 v 没有任何关系,请求背包能装下的最大价值。

JS手写二分搜索算法

实现一个Lazyman

节流、防抖

发表于 2020-04-17

js 防抖和节流

在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。

函数防抖

函数防抖(debounce):当持续触发事件时,一定时间内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了时事件,就重新开始延时。

1
2
3
4
5
6
7
8
9
10
11
function debounce(fn, delay) {
let timer = null;

return function() {
if (timer) {
clearTimeout(timer);
}

timer = setTimeout(fn, delay);
}
}

函数节流

函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

节流 throttle(时间缀版)

1
2
3
4
5
6
7
8
9
10
11
12
function throttle(fn, delay) {
let prev = Date.now();

return function() {
let now = Date.now();

if (now - prev >= delay) {
fn.apply(this, arguments);
prev = Date.now();
}
}
}

节流 throttle(定时器版)

1
2
3
4
5
6
7
8
9
10
11
12
13
function throttle(fn, delay) {
let timer = null;
return function() {
const _that = this;
const args = arguments;
if (!timer) {
timer = setTimeout(function() {
fn.apply(_that, args);
timer = null
}, delay);
}
}
}

节流 throttle (时间缀+定时器版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function throttle(fn, delay) {
let timer = null;
let startTime = Date.now();

return function() {
let _that = this;
let args = arguments;

let nowTime = Date.now();

clearTimeout(timer);

if (nowTime - startTime >= delay) {
fn.apply(_that, args);
startTime = Date.now();
} else {
timer = setTimeout(fn, delay - (nowTime - startTime));
}
}
}

总结

函数防抖:将几次操作合并为一次操作进行。原理是维护一个计时器,规定在 delay 时间后触发函数,但是在 delay 时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 AJAX 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

知识点

发表于 2020-04-02 | 更新于 2020-07-27

js 为什么是单线程?

线程:是操作系统能够进行运算调度的最小单位。
单线程:(上面有说:一条线程指的是进程中一个单一顺序的控制流)就是在进程中只有一条线程,在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所以,为了避免复杂性,从一诞生,JavaScript就是单线程。

浏览器的内核机制

浏览器的内核是多线程的,一个浏览器一般至少实现三个常驻线程:

  1. javascript引擎:是基于事件驱动单线程执行的,js引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个js线程在运行js程序。
  2. GUI 渲染线程:负责渲染浏览界面,当界面需要重排、重绘或由于某种操作引发回流时,该线程就会执行。但需要注意 GUI 渲染线程与 js 引擎是互斥的,当js引擎执行时GUI线程会被挂起,
    GUI 更新会被保存在一个队列中等到js引擎空闲时立即被执行。
  3. 事件触发线程:当一个事件被触发时该线程会把事件添加到待处理列的队尾,等待js引擎的处理。

React 事件与 js 事件的区别

JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。
另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。

那么实现合成事件的目的是什么呢?总的来说在我看来好处有两点,分别是:

  • 合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力

  • 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。

setState 的执行流程

EventLoop

移动端适配

移动端的屏幕宽度差距比较小(4-8英寸),UI页面通常也会保持一致的布局方式,只是文字、图标、大图片等可能会根据业务需要做一些定制化的处理。

Pad设备虽然也是移动设备,但是因为屏幕足够宽,所以现在多数产品(某宝)的方案都是访问PC站点了

移动端多屏适配的需求,常见主要有两类:

  1. 布局伸缩式(布局伸缩,内容大小固定或梯级变化)
  2. 等比缩放式(布局和内容完全等比例缩放)

布局伸缩式

布局伸缩式适配需求,常见于排版比较简单的信息流展示类业务。
其布局特点一般为横向伸缩,竖向高度固定或由内容填充决定;文字图标等网页内容一般会固定大小,且在宽屏窄屏上的视觉大小保持一致。

技术方案
  • 设置 viewport 宽度为 device-width,以保证 px 为单位取值的一些文字图标等网页内容视觉大小符合预期且宽窄屏大小一致。( css 中的 px 取值需按一倍屏的 UI 稿来写)。
  • 布局方案灵活使用相对单位 %/float/flex 等,以保证布局的横向伸缩和容器内各元素的大小间距符合预期;
  • 组合包裹相关元素,并相对某一方向做定位,以保证宽度变化时的定位稳定。

等比缩放式

等比缩放式适配需求,广泛应用于各种产品类、运营类等业务场景。
其布局特点简单粗暴,就是根据屏幕宽度整个页面等比缩放。

rem

rem 是 css3 新增的相对于根元素 html 的 font-size 计算值的大小的倍数单位。

  • 设置 viewport 宽度为 device-width 或其他固定值,以得到 px 为单位的文字、图标或边线等效果
  • css 单位使用 rem,js 根据 viewport 宽度以及 css 中的 rem的换算系数,动态计算并设置 html 根节点 font-size,以实现整个页面内容的等比例缩放。

rem 为基础的动态适配方案
设:横向满屏的 rem 个数预定为 remCount,标注稿总宽度 px 为 uiWidth,标注稿内某元素宽度为 uiEleWidth。
那么:
● 设计稿中 1rem 表示的 px 数 uiPX1rem = uiWidth/remCount
● CSS 中某元素 rem 的值 cssEleWidth= uiEleWidth/uiPX1rem
● JS 中根节点的 fontSize = document.documentElement.clientWidth/remCount

github 中近 1 万 star 的 js 库lib-flexible 便是采用的此方案。

viewport units

1vw 即表示当前视口宽度的 1%,我们可以利用这一点替代“rem+根节点 font-size”的等比缩放实现。
举个例子,750px 的 UI 稿中,宽度 75px 的按钮,在 css 中的宽度描述即为:width:10vw。

viewport meta only

h5与原生如何交互

  1. app调用h5的代码

因为app是宿主,可以直接访问h5,所以这种调用比较简单,就是在h5中暴露一些全局对象(包括方法),然后在原生app中调用这些对象。

  1. h5调用app的代码
  • 由app向h5注入一个全局的js对象,然后在h5直接访问这个对象
  • 由h5发起一个自定义协议请求,app拦截这个请求后,再由app调用h5中的回调函数

什么是 “React Fiber”?

Fiber 是 React 16 中新的协调引擎。它的主要目的是使 Virtual DOM 可以进行增量式渲染。

HOC 是什么?相比 mixins 有什么优点?

React 的思想中是存在函数式编程的,高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好的复用代码。

其实 HOC 和 Vue 中的 mixins 作用是一致的,并且在早期 React 也是使用 mixins 的方式。但是在使用 class 的方式创建组件以后,mixins 的方式就不能使用了,并且其实 mixins 也是存在一些问题的,比如:

  • 隐含了一些依赖,比如我在组件中写了某个 state 并且在 mixin 中使用了,就这存在了一个依赖关系。万一下次别人要移除它,就得去 mixin 中查找依赖
  • 多个 mixin 中可能存在相同命名的函数,同时代码组件中也不能出现相同命名的函数,否则就是重写了,其实我一直觉得命名真的是一件麻烦事。
  • 雪球效应,虽然我一个组件还是使用着同一个 mixin,但是一个 mixin 会被多个组件使用,可能会存在需求使得 mixin 修改原本的函数或者新增更多的函数,这样可能就会产生一个维护成本

HOC 解决了这些问题,并且它们达成的效果也是一致的,同时也更加的政治正确(毕竟更加函数式了)。

什么是作用域链?

当代码在一个环境中执行时,会创建变量对象的一个作用域链。

什么是作用域

变量的作用域分为两种:全局变量和局部变量。
1、全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的;
2、局部作用域: 局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。

webpack 优化, webpack4 与 webpack3 的区别

  1. mode

webpack4 新增了mode配置,只有两种值 development | production。

  1. CommonsChunkPlugin

webpack.optimize.CommonsChunkPlugin 已经从 webpack4 移除。 可使用 optimization.splitChunks 进行模块划分(提取公用代码)。

  1. mini-css-extract-plugin(css文件提取)

移除了 extract-text-webpack-plugin 配置,增加 mini-css-extract-plugin 配置。

  1. babel 使用新的命名空间 @babel

  2. UglifyJsPlugin

移除 UglifyJsPlugin,采用 TerserPlugin。

  1. 移除 loaders,必须使用 rules

webpack4之前,loaders 跟 rulrs 是可以一起使用的。

  1. 支持 es6 方式引入文件

import a from ‘a.js’;

  1. 升级 Happypack 插件进行多线程加速打包
12…5
achen

achen

日常复制粘贴,问啥啥不会

49 日志
12 标签
© 2021 achen
由 Hexo 强力驱动 v3.7.1
|
主题 – NexT.Pisces v6.4.0