CSS colors
CSS colors
css 支持使用多种语法描述颜色
- keywords
- hex codes
- 使用 16 进制表示 #RRGGBB
- color function
sRGB 色域可以用 16 进制, rgb/rgba, hsl/hsla, hwb 直接指定
1 | // 不同用法表示同一个颜色 |
将 HSL 颜色转为 sRGB
1 | /** |
将 sRGB 颜色转为 HSL
1 | /** |
css 支持使用多种语法描述颜色
sRGB 色域可以用 16 进制, rgb/rgba, hsl/hsla, hwb 直接指定
1 | // 不同用法表示同一个颜色 |
将 HSL 颜色转为 sRGB
1 | /** |
将 sRGB 颜色转为 HSL
1 | /** |
将多个项目存放在同一个 git 仓库中,将项目放入不同的工作区,各个工作区之间互相引用模块,实现代码共享。
前端项目使用包管理器管理 monorepo。
1 | my-monorepo |
如果将docs、 apps 和packages 下的所有目录设为工作区,需要在根目录如下设置
在根目录的 package.json 文件中配置 workspaces 字段。在workspaces 中配置工作区列表。
1 | { |
在根目录的 package.json 文件中配置 workspaces 字段。在workspaces 中配置工作区列表。
1 | { |
在根目录的 pnpm-workspace.yaml 文件中配置工作区列表。
1 | packages: |
在某个工作区将另一个工作区作为依赖项,需要在其package.json 指明:
1 | { |
1 | { |
1 | { |
在根目录执行npm install 后,npm 会在根目录和每个工作区下载依赖包到 node_modules , 当遇到工作区依赖后,会将工作区符号链接到node_modules, 所以可以将其当做普通依赖一样正常导入。
Turborepo 是一个在包管理器提供的monorepo 管理功能之上,提供了更方便并且性能更好的构建系统。
使用 Turborepo只要在根目录安装turbo, 同时在根目录下添加turbo.json 即可开始使用
1 | { |
当运行 turbo lint 时,Turborepo 会查看每个工作区中的每个 lint 脚本并运行它。
1 | // turbo.json |
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com; path=/; secure
Other-header: other-header-value
这里创建的 cookie 对所有 wrox.com 的子域及该域中的所有页面有效(通过 path=/ 指定)。不过,这个 cookie 只能在 SSL 连接上发送,因为设置了 secure 标志。 要知道,域、路径、过期时间和 secure 标志用于告诉浏览器什么情况下应该在请求中包含 cookie。 这些参数并不会随请求发送给服务器,实际发送的只有 cookie 的名/值对。
Non**e**。浏览器会在同站请求、跨站请求下继续发送 cookies,不区分大小写。
**Strict****。**浏览器将只在访问相同站点时发送 cookie。(在原有 Cookies 的限制条件上的加强,如上文 “Cookie 的作用域” 所述)。
**Lax**。与 **Strict** 类似,但用户从外部站点导航至 URL 时(例如通过链接)除外。 在新版本浏览器中,为默认选项,Same-site cookies 将会为一些跨站子请求保留,如图片加载或者 frames 的调用,但只有当用户从外部站点导航到 URL 时才会发送。如 link 链接。
未设置 SameSite, 主流浏览器默认设为 Lax。
JS 想要操作 cookie 只能通过 BOM 接口 document.cookie 操作,并且需要 URL 编码(可以用 decodeURIComponent),一般都是封装下方法再使用。
如果 cookie 设置了 HttpOnly, 则前端无法操作。
不超过 300 个 cookie;
每个 cookie 不超过 4096 字节;
每个域不超过 20 个 cookie;
每个域不超过 81920 字节。
clear():删除所有值。
getItem(name):取得给定 name 的值。
key(index):取得给定数值位置的名称。
removeItem(name):删除给定 name 的名/值对。
setItem(name, value):设置给定 name 的值。
使用 sessionStorage 存储的数据只在当前会话有效。有效的页面:
页面1页面1打开的页面如果在地址栏敲入新的页面,即使是同一个页面,也无法获取到 sessionStorage。
满足域、端口和协议都相同的页面可以获取到同一个 localSrtorage。
localStorage: 存储在 localStorage 中的数据会保留到通过 JavaScript 删除或者用户清除浏览器缓存。localStorage 数据不受页面刷新影响,也不会因关闭窗口、标签页或重新启动浏览器而丢失。
sessionStorage: sessionStorage 中的数据不受页面刷新影响,会在关闭标签页后丢失。
todo
Cache 这个 API 是针对 Request Response 的。Cache 一般结合 Service Worker 使用,因为请求级别的缓存与具有页面拦截功能的 Service Worker 最配。
// 不存在则创建
const myCache = await caches.open(‘myCache’);
通过 add/addAll 方法添加,调用 add 会类似 fetch 一样发送请求,并将响应放到 Cache Storage 里面。
在 put 方法里传一个 Response 也可以实现添加缓存。
// 参数同 fetch
myCache.add(‘/test-url’);
// 使用 put
fetch(url).then(function (response) {
if (!response.ok) {
throw new TypeError(‘bad response status’);
}
return cache.put(url, response);
})
通过 match 或 matchAll 方法读取。
// 参数同 fetch, 可以是 URL 地址,也可以是 Request 对象
const res = await myCache.match(“/subscribe”);
// const res = await myCache.matchAll(“/subscribe”);
通过 add 或 put 方法更新。
const request = new Request(“/subscribe”);
const fetchResponse = await fetch(request);
myCache.put(request, fetchResponse);
使用 delete 方法删除某个路径的缓存或者直接删除整个命名空间。
myChache.delete(‘/subscribe’);
caches.delete(‘myChache’);
在 service worker (在全局环境里也能用) 中用来缓存 js/css/img 文件或者不经常更新的接口,加快请求或者提供离线访问能力。
准备源代码
1 | // module.js |
配置 1 : 仅使用 @babel/env
1 | { |
编译结果 1
1 | // module.js |
从结果来看,module.js 和 index.js 都从 core-js 引入了自身需要的 polyfill (全局变量),针对 async/await 分别生成了同样的 asyncGeneratorStep 和 _asyncToGenerator
配置 2 : 使用 @babel/env 和 @babel/plugin-transform-runtime (默认配置)
1 | { |
编译结果 2
1 | // module.js |
添加 @babel/plugin-transform-runtime 后,对于 async/await 不再重复生成 asyncGeneratorStep 和 _asyncToGenerator,改为从 @babel/runtime 中引入, 其余 polyfill 依然从 core-js 引入
配置 3 使用 @babel/env 和 @babel/plugin-transform-runtime (配置 corejs, 需要安装 @babel/runtime-corejs3 依赖)
1 | { |
编译结果 3
1 | // module.js |
@babel/plugin-transform-runtime 添加配置 corejs: 3 后,所有的 polyfill 都改为从 @babel/runtime-corejs3 导入,同时由全局覆盖变为了局部变量,不会污染全局
结论:
@babel/presets 的 『”useBuiltIns”: “usage”』会引入模块中需要的 polyfill 并且是全局覆盖的,但是每个模块都会重复生成辅助函数
添加插件 『@babel/plugin-transform-runtime』 后,辅助函数不会在每个模块中重复生成,而是从 『@babel/runtime』引入
@babel/plugin-transform-runtime 进一步配置 『 “corejs”: 3 』后,所有的 polyfill 都从 『@babel/runtime-corejs3』引入,并且是局部变量,不会污染全局
HTTP 的标准是由 IETF 组织制定,跟它相关的标准:
HTTP Documentation (httpwg.org)
HTTP/1.1 相关
中文翻译: duoani/HTTP-RFCs.zh-cn: 翻译 HTTP 相关的 RFC (中英文对照) (github.com)
HTTP/2 相关
中文翻译: abbshr/rfc7540-translation-zh_cn: RFC 7540 - HTTP/2 中文翻译版 (github.com)
HTTP 协议是基于 TCP 协议实现的,在 TCP 的基础上规定了一个 Request-Response 的模式。这个模式就是客户端发送消息给服务端,服务端才能返回消息给客户端,服务端不能主动发送消息。
HTTP 协议大概可以划分成 Request 和 Response。
Request
Request 是客户端需要发送到服务端的数据,可以分成下面这三部分:
具体的数据格式:
GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi

sp 是空格,cr 是 \r , lf 是 \n
Response
Response 是服务端返回给客户端的数据,对应的也可以分成三部分:
Response Line(响应行)
version(版本)
status code(状态码)
status text(状态文本)
Response Header(响应头)
message-body(实体)
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: “34aa387-d-1568eb00”
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My payload includes a trailing CRLF.

响应状态码
HTTP2 是 HTTP1.1 的升级版,HTTP2 相对于 HTTP1.1 来说主要有下面几点的改进:
源文件:a.js, b.js, c.js, d.js, index.js
展开源码
1 | // a.js |
就是在 index.js 中引入 [a, b, c, d] 等使用不同模块化方式的模块, 来看看 webpack 是怎么处理模块引用的
下面是 webpack 打包出来的 bundle.js 文件(省略了多余注释和没用到的声明)
1 | (function (modules) { |
整体代码流程就是创建一个自执行函数, 根据文件名称递归调用内部函数 __webpack_require__(moduleId) , 从而把代码模块化
fs 模块提供了一个 API,用于以模仿标准 POSIX 函数的方式与文件系统进行交互。
所有文件系统操作都具有同步和异步的形式。
1 | 读取文件; |
写入/修改文件
写入文件时,如果文件不存在,则会创建并写入,如果文件存在,会覆盖文件内容.
1 | const fs = require('fs'); |
删除文件/文件夹
删除文件
1 | // 异步删除文件 |
Node 是基于事件驱动的,其就是通过核心模块 Events 实现的。 Events 模块定义了 EventEmitter 类。实际上就是发布订阅模式。所有可能触发事件的对象都是继承自 EventEmitter 类的,其主要包含下面方法:
使用 EventEmitter
其他类需要触发事件等,都需要自行继承这个类:
1 | let util = require('util') |
流(stream)是 Node.js 中处理流式数据的抽象接口。 stream 模块用于构建实现了流接口的对象。
使用 stream 的场景:
使用 fs.readFile 读取文件时会将数据整个读取到内存中再处理,当处理大文件时,会极大的展示资源,这时就是使用 stream 的时候了。
Stream 不会一次性的读取文件,而是分批次的读取适量的内容到缓存区进行操作,这样对内存的占用会少很多。
流的四种基本类型
Writable - 可写入数据的流(例如 fs.createWriteStream())。
Readable - 可读取数据的流(例如 fs.createReadStream())。
Duplex - 可读又可写的流(例如 net.Socket)。
Transform - 在读写过程中可以修改或转换数据的 Duplex 流(例如 zlib.createDeflate())。
缓冲
缓冲区有大小限制,由 highWaterMark 指定字节总数(对象模式下指定对象总数)。调用 stream.push(chunk)时,数据缓冲在可读流中,等待被消费,如果缓冲区的数据大小达到了 highWaterMark 指定的阈值,流会停止读取数据,直到当前缓冲区的数据被消费。
用于消费的 api
使用继承自 events 的 emitter api 来通讯状态。
1 | const file = fs.createReadStream('./test.txt', { |
(异步)事件触发顺序 open -> data -> data -> … -> end -> close
url 模块用于处理与解析 URL。
URL 字符串是结构化的字符串,包含多个含义不同的组成部分。 解析字符串后返回的 URL 对象,每个属性对应字符串的各个组成部分。
url 模块提供两种 api 来处理 url。(两种 api 的处理结果不同,详细)
const url = require(‘url’)
// WHATWG 标准
const myUrl = new url(‘https://baidu.com:8080/a/b/c?q=str#hash')
// 遗留 api
const myUrl2 = url.parse(‘https://baidu.com:8080/a/b/c?q=str#hash')
以下介绍的都是 WHATWG 标准解析出的对象
URL 对象的属性
const url = require(“url”);
1 | const url = require("url"); |
URL 对象属性 除了 origin 和 searchParams 是只读的,其他都是可写的.
1 | const { URL } = require('url'); |
SQL Server MySQL Access ORACLE
数据库 –> 表 –> 记录
MongoDb 文档型的非关系数据库
官网下载合适版本
不停的下一步,下一步
增加环境变量,以便直接在 shell 中使用
数据库 –> 集合 –> 文档 database –> collection –> document
存储格式 BSON 类似于 JSON
每一个 {}称为一条文档
{ “name” : “小明”, “age” : 18, “hobby”: [“睡觉”, “吃饭”] }
命令操作
mongod:mongod --dbpath dir # 打开或新建一个数据库 # mongod --dbpath E:\mongodb\mydb
mongo:use dbname # 新建叫做 dbname 的数据库, 同时进入 dbname
初步操作
1 | show dbs # 查看所有的数据库 |
1 | mongoimport --db test --collection user --drop --file C:\user\db\test.json |
假设集合名叫 user
1 | ## 查询所有文档 |
node 里简单封装增删改查
1 | // node mongodb 版本 v3.1.13 适用 |
相同点
1 | interface IAnimal { |
泛型
1 | interface IAnimal<p = string> { |
交叉继承
1 | type Robot = { |
实现
1 | class Dog implements IAnimal { |
继承类
1 | class Control { |
函数
1 | type Bark = (x: string) => void; |
递归声明
1 | type Tree<P> = { |
可索引的
1 | type StringRecord = { |
不同点
只能使用 type 来别名基本类型
1 | type NewNumber = number; |
元组
不能使用 interface 声明元组
1 | type Tuples = [number, number]; |
不相关的合集
只有 type 可以做不相关合集
1 | type SomeAnimal = { type: Dog } | { type: Cat }; |
且不能对 不相关集合不能使用 extends 关键字
1 | interface ISomeAnimal extends SomeAnimal {} |
每个作用域只能声明一次类型
1 | type Once = { a: string }; |
可以在每个作用域中多次声明接口(会进行声明合并)
1 | interface IOnce { |
React.FC | React.FunctionComponent表示函数组件的类型
1 | const MyComponent: React.FC<Props> = function(p) {...} |
React.Component表示类组件的类型
1 | class MyComponent extends React.Component<Props, State> { ... |
React.ComponentType表示(React.FC | React. Component)的联合的类型-在 HOC 中使用
1 | const withState = <P extends WrappedComponentProps>( |
React.ComponentProps获取指定组件 XXX 的 Props 类型(警告: 不能使用静态声明的默认道具和通用道具)
1 | type MyComponentProps = React.ComponentProps<typeof MyComponent>; |
React.ReactElement | JSX.Element类型表示 DOM 组件(例如
)或自定义的组件(例如1 | const elementOnly: React.ReactElement = <div /> || <MyComponent />; |
React.ReactNode表示任何可能类型的 React 节点( ReactElement + 基本 JS 类型)
1 | const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || <div /> || <MyComponent />; |
React.CSSPropertiesJSX 中输入表示样式对象的类型
1 | const styles: React.CSSProperties = { flexDirection: 'row', ... |
React.HTMLProps表示指定 HTML 元素的类型-用于扩展 HTML 元素
1 | const Input: React.FC<Props & React.HTMLProps<HTMLInputElement>> = props => { ... } |
React.ReactEventHandler表示泛型事件处理函数-用于声明处理事件的函数
1 | const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) => { ... } |
React.XXXEvent表示更具体的事件。 常见的事件: ChangeEvent, FormEvent, FocusEvent, KeyboardEvent, MouseEvent, DragEvent, PointerEvent, WheelEvent, TouchEvent.
1 | const handleChange = (ev: React.MouseEvent<HTMLDivElement>) => { ... } |
在上面的代码中反应。 鼠标事件 React.MouseEvent 是鼠标事件的类型,这个事件发生在 HTMLDivElement 上