process.env

processNode.js 中的 一个全局变量,提供来有关当前 Node.js 进程的信息并对其进行控制。而process 中的 env 则是返回包含用户环境的对象。可以通过 process.env 拿到当前项目运行环境的信息。

设置环境变量

通过cli的方式进行设置
1
2
// index.js中
console.log(process.env.PROT)

Windows (cmd.exe)

1
set PROT=10086 && node index.js

Linux, macOS (Bash)

1
PROT=10086 node index.js
阅读全文 »

项目拆解:

  1. Jsx 和虚拟 DOM

  2. 组件和生命周期

  3. Diff

  4. 异步的setState

  5. hook支持

具体思路

将jsx经过babel转成React.createElement的形式

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Hem extends React.Component {
render() {
return (
<A>
<B>
<C>
<div />
<span />
</C>
<D />
</B>
<E />
<F />
</A>
);
}
}

经过babel转义后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
_createClass(Hem, [
{
key: "render",
value: function render() {
return React.createElement(
A,
null,
// A组件的亲儿子组件B
React.createElement(
B,
null,
React.createElement(
C,
null,
// C组件的亲儿子 div
React.createElement("div", null),
// C组件的亲儿子 span
React.createElement("span", null)
),
React.createElement(D, null)
),
// A组件的亲儿子组件E
React.createElement(E, null),
// A组件的亲儿子组件F
React.createElement(F, null)
);
},
},
]);
阅读全文 »

代码自动格式化工具:prettier

配置过程:https://prettier.io/docs/en/precommit.html

yarn add --dev --exact prettier

新建.prettierrc.json,.prettierignore文件

设置git commit预提交钩子

npx mrm@2 lint-staged

规范git commit工具:commitlint

配置过程:https://github.com/conventional-changelog/commitlint

yarn add --save-dev @commitlint/config-conventional @commitlint/cli

新建 commitlint.config.js文件,引入规则module.exports = {extends: [‘@commitlint/config-conventional’]}

阅读全文 »

背景

  1. 希望利用 css 变量实现 dark 和 light 模式的切换
  2. 原有的工程都是 less 形式定义的 css,并且还有 less 的函数,比如 fade 等,不想手动改 less 的函数,希望该插件能支持解析 less 函数
  3. 需要支持局部不切换模式,比如某个区域是固定的 light 模式

步骤

第一步:less 变量转换成 css 变量

这一步比较简单,less 已经提供了字段用于转换,只需要添加一个配置项就可以,就是globalVars属性。

可以查看example 代码参考

1
2
3
4
5
6
7
{
loader: 'less-loader',
options: {
globalVars: LessGlobalCSSVars,
}
}
复制代码

LessGlobalCSSVars大概长这个样子

1
2
3
4
5
6
{
"bg-body": "var(--bg-body)",
"static-white": "var(--static-white)",
...
}
复制代码
阅读全文 »

React 性能优化思路

我觉得React 性能优化的理念的主要方向就是这两个:

  1. 减少重新 render 的次数。因为在 React 里最重(花时间最长)的一块就是 reconciliation(简单的可以理解为 diff),如果不 render,就不会 reconciliation。
  2. 减少计算的量。主要是减少重复计算,对于函数式组件来说,每次 render 都会重新从头开始执行函数调用。

在使用类组件的时候,使用的 React 优化 API 主要是:shouldComponentUpdatePureComponent,这两个 API 所提供的解决思路都是为了减少重新 render 的次数,主要是减少父组件更新而子组件也更新的情况。

但是在函数式组件里面没有声明周期也没有类,那如何来做性能优化呢?

先分个类,组件什么时候会重新执行?

  1. 组件自己的状态改变
  2. 父组件重新渲染,导致子组件重新渲染,但是父组件的 props 没有改变
  3. 父组件重新渲染,导致子组件重新渲染,但是父组件传递的 props 改变

针对第二点,在FC中,可以通过memo减少rerender

1
2
3
4
function Component(props) {
/* 使用 props 渲染 */
}
const MyComponent = React.memo(Component);

通过 React.memo 包裹的组件在 props 不变的情况下,这个被包裹的组件是不会重新渲染的(相当于PureComonent)

默认情况下其只会对 props 的复杂对象做浅层对比(浅层对比就是只会对比前后两次 props 对象引用是否相同,不会对比对象里面的内容是否相同),如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。

阅读全文 »

TypeScript简介

  1. TypeScript是JavaScript的超集。
  2. 它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。
  3. TS代码需要通过编译器编译为JS,然后再交由JS解析器执行。
  4. TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。
  5. 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。

TypeScript 开发环境搭建

  1. 下载Node.js

  2. 安装Node.js

  3. 使用npm全局安装typescript

    • 进入命令行
    • 输入:npm i -g typescript
  4. 创建一个ts文件

  5. 使用tsc对ts文件进行编译

    • 进入命令行

    • 进入ts文件所在目录

    • 执行命令:tsc xxx.ts

阅读全文 »

hooks的作用

钩子(hook)就是 React 函数组件的副效应解决方案,用来为函数组件引入副效应。 函数组件的主体只应该用来返回组件的 HTML 代码,所有的其他操作(副效应)都必须通过钩子引入。

由于副效应非常多,所以钩子有许多种。React 为许多常见的操作(副效应),都提供了专用的钩子。

  • useState():保存状态
  • useContext():保存上下文
  • useRef():保存引用
  • ……

上面这些钩子,都是引入某种特定的副效应,而 useEffect()是通用的副效应钩子 。找不到对应的钩子时,就可以用它。其实,从名字也可以看出来,它跟副效应(side effect)直接相关。

阅读全文 »

Redux

设计思想

  • (1)Web 应用是一个状态机,视图与状态是一一对应的。
  • (2)所有的状态,保存在一个对象里面。

Action

  1. Action 就是 View 发出的通知,表示 State 应该要发生变化了。

  2. Action 是一个对象,其中的type属性是必须的,表示 Action 的名称,Action 描述当前发生的事情。

  3. 改变 State 的唯一办法,就是使用 Action。

可以定义一个函数来生成 Action,这个函数就叫 Action Creator,示例如下

1
2
3
4
5
6
7
8
9
10
const ADD_TODO = '添加 TODO';

function addTodo(text) {
return {
type: ADD_TODO,
text
}
}

const action = addTodo('Learn Redux');
阅读全文 »

chrome浏览器架构

Chrome 采用多进程架构,其顶层存在一个 Browser process 用以协调浏览器的其它进程。

  • Browser Process:
  1. 负责包括地址栏,书签栏,前进后退按钮等部分的工作;

  2. 负责处理浏览器的一些不可见的底层操作,比如网络请求和文件访问;

  • Renderer Process:
  1. 负责一个 tab 内关于网页呈现的所有事情
  • Plugin Process:
  1. 负责控制一个网页用到的所有插件,如 flash
  • GPU Process
  1. 负责处理 GPU 相关的任务

image-20210930012419754

由于一个tab标签页都有一个独立的渲染进程,所以一个tab异常崩溃后,其他tab不会受到影响。

一个渲染进程包括

  • JS引擎线程
  • HTTP请求线程
  • 定时触发线程
  • 事件触发线程
  • GUI线程

浏览器JS异步执行原理

执行JS代码的线程只有一个,是浏览器提供的JS引擎线程,浏览器中还有

image-20210930012033902

阅读全文 »

什么是函数式编程?

函数式编程具有五个鲜明的特点。

1. 函数是”第一等公民”

指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。

举例来说,下面代码中的print变量就是一个函数,可以作为另一个函数的参数。

1
2
3
  var print = function(i){ console.log(i);};

  [1,2,3].forEach(print);

2. 只用”表达式”,不用”语句”

“表达式”(expression)是一个单纯的运算过程,总是有返回值;”语句”(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

原因是函数式编程的开发动机,一开始就是为了处理运算(computation),不考虑系统的读写(I/O)。”语句”属于对系统的读写操作,所以就被排斥在外。

当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。

阅读全文 »
0%