Compare commits
65 Commits
Author | SHA1 | Date | |
---|---|---|---|
46fb45e643 | |||
3ec4dc496a | |||
19caaad574 | |||
4122b48f76 | |||
57e41a7fd6 | |||
9832aea099 | |||
dcb0c1667c | |||
25a9ba86fa | |||
cadc7dad14 | |||
a24f6a91a4 | |||
0f091beebd | |||
2c276e72ac | |||
313df63ce2 | |||
9e3b2b913f | |||
ce71a63350 | |||
96c50ca289 | |||
4460aa9246 | |||
877a763274 | |||
15c899a89f | |||
4275ee8ace | |||
7db4389708 | |||
3b8415f692 | |||
6baf60a095 | |||
489f29bb14 | |||
1dad75e9b2 | |||
bf286ba518 | |||
fb96ea19c5 | |||
03a4241228 | |||
c661cfa852 | |||
31df164656 | |||
327e35baf7 | |||
518249913e | |||
078df00bf5 | |||
79b5f6da26 | |||
878990a290 | |||
f55c4219c4 | |||
502aa0ab15 | |||
81001e2594 | |||
da18c16d26 | |||
9168e56f39 | |||
32f0936c36 | |||
9cf8737419 | |||
d903719a33 | |||
593662f3c6 | |||
a5ec6ff25c | |||
a34e5372fe | |||
b0eb01e566 | |||
2fcd80f34d | |||
6eb1ef3260 | |||
1ee5910d86 | |||
c221cd1ac3 | |||
f1d7c9e585 | |||
f13778aa5a | |||
45a20dd749 | |||
c19283b71f | |||
9a5e90d6e6 | |||
eeb88275fd | |||
01100e3c4a | |||
edaf58f327 | |||
864ef36fd6 | |||
7f4e2f5b1c | |||
417353e1ae | |||
0468d5ec52 | |||
db26d12c9d | |||
7728dfaa75 |
87
.github/workflows/ci.yml
vendored
@ -16,9 +16,94 @@ jobs:
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
|
||||
- name: Create Tag
|
||||
id: create_tag
|
||||
uses: jaywcjlove/create-tag-action@main
|
||||
with:
|
||||
package-path: ./package.json
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
commit_message: ${{ github.event.head_commit.message }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./dist
|
||||
publish_dir: ./dist
|
||||
|
||||
- name: Generate Changelog
|
||||
id: changelog
|
||||
uses: jaywcjlove/changelog-generator@main
|
||||
with:
|
||||
filter-author: (小弟调调™)
|
||||
filter: (^[\s]+?[R|r]elease)|(^[R|r]elease)
|
||||
|
||||
|
||||
- name: Create Release
|
||||
uses: ncipollo/release-action@v1
|
||||
if: steps.create_tag.outputs.successful
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: ${{ steps.create_tag.outputs.version }}
|
||||
tag: ${{ steps.create_tag.outputs.version }}
|
||||
body: |
|
||||
Documentation ${{ needs.build.outputs.create_tag_version }}: https://raw.githack.com/jaywcjlove/reference/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html
|
||||
Comparing Changes: ${{ steps.changelog.outputs.compareurl }}
|
||||
|
||||
${{ steps.changelog.outputs.changelog }}
|
||||
|
||||
## Docker
|
||||
[](https://hub.docker.com/r/wcjiang/reference) [](https://hub.docker.com/r/wcjiang/reference) [](https://hub.docker.com/r/wcjiang/reference)
|
||||
|
||||
轻松通过 `docker` 部署 `Quick Reference` 网站。
|
||||
|
||||
```bash
|
||||
docker pull wcjiang/reference
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run --name reference --rm -d -p 9667:3000 wcjiang/reference:latest
|
||||
# Or
|
||||
docker run --name reference -itd -p 9667:3000 wcjiang/reference:latest
|
||||
```
|
||||
|
||||
在浏览器中访问以下 URL
|
||||
|
||||
```bash
|
||||
http://localhost:9667/
|
||||
```
|
||||
|
||||
# Create Docker Image in Github
|
||||
- name: Login to GitHub registry
|
||||
run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Build docker image
|
||||
run: docker build -t ghcr.io/jaywcjlove/reference:latest .
|
||||
|
||||
- name: Publish to GitHub registry
|
||||
run: docker push ghcr.io/jaywcjlove/reference:latest
|
||||
|
||||
- name: Tag docker image (beta) and publish to GitHub registry
|
||||
if: steps.create_tag.outputs.successful
|
||||
run: |
|
||||
echo "version: v${{ steps.changelog.outputs.version }}"
|
||||
docker tag ghcr.io/jaywcjlove/reference:latest ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
||||
docker push ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
||||
|
||||
# Create Docker Image
|
||||
- name: Docker login
|
||||
run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build reference image
|
||||
run: docker image build -t reference .
|
||||
|
||||
- name: Tags & Push image(latest)
|
||||
run: |
|
||||
echo "DOCKER_USER: ${{ secrets.DOCKER_USER }}"
|
||||
docker tag reference ${{ secrets.DOCKER_USER }}/reference:latest
|
||||
docker push ${{ secrets.DOCKER_USER }}/reference:latest
|
||||
|
||||
- name: Tags & Push image
|
||||
if: steps.create_tag.outputs.successful
|
||||
run: |
|
||||
echo "outputs.tag - ${{ steps.changelog.outputs.version }}"
|
||||
docker tag reference ${{ secrets.DOCKER_USER }}/reference:${{steps.changelog.outputs.version}}
|
||||
docker push ${{ secrets.DOCKER_USER }}/reference:${{steps.changelog.outputs.version}}
|
7
Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
# https://lipanski.com/posts/smallest-docker-image-static-website
|
||||
# https://github.com/lipanski/docker-static-website
|
||||
FROM lipanski/docker-static-website:latest
|
||||
|
||||
# Copy the static website
|
||||
# Use the .dockerignore file to control what ends up inside the image!
|
||||
COPY ./dist .
|
42
README.md
@ -1,6 +1,13 @@
|
||||
Quick Reference
|
||||
===
|
||||
|
||||
<!--rehype:ignore:start-->
|
||||
[](https://github.com/jaywcjlove/reference/actions/workflows/ci.yml)
|
||||
[](https://hub.docker.com/r/wcjiang/reference)
|
||||
[](https://hub.docker.com/r/wcjiang/reference)
|
||||
[](https://hub.docker.com/r/wcjiang/reference)
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
为开发人员分享快速参考备忘清单(主要是方便自己),在看到 [Reference](https://github.com/Randy8080/reference) 快速参考备忘单,感觉非常简单,造轮子使命感突然来了,造个中文版本的,为了方便自己的技术栈查阅,立马撸起来 :)。
|
||||
|
||||
如果您发现此处的备忘单不合适,您可以通过提交 [PR](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
|
||||
@ -8,24 +15,40 @@ Quick Reference
|
||||
## 编程
|
||||
|
||||
[Bash](./docs/bash.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||
[C](./docs/c.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));-->
|
||||
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
||||
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31/var(\-\-bg\-opacity));-->
|
||||
[Golang](./docs/golang.md)<!--rehype:style=background: rgb(39 160 193/var(\-\-bg\-opacity));-->
|
||||
[JSON](./docs/json.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
|
||||
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
|
||||
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[Markdown](./docs/markdown.md)<!--rehype:style=background: rgb(103 61 156/var(\-\-bg\-opacity));-->
|
||||
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[YAML](./docs/yaml.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 前端
|
||||
|
||||
[CSS 3](./docs/css.md)<!--rehype:style=background: rgb(35 115 205/var(\-\-bg\-opacity));-->
|
||||
[Electron](./docs/electron.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
||||
[Emmet](./docs/emmet.md)<!--rehype:style=background: rgb(122 203 23/var(\-\-bg\-opacity));-->
|
||||
[Styled Components](./docs/styled-components.md)<!--rehype:style=background: rgb(221 60 184/var(\-\-bg\-opacity));-->
|
||||
[HTML](./docs/html.md)<!--rehype:style=background: rgb(228 77 39/var(\-\-bg\-opacity));-->
|
||||
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31/var(\-\-bg\-opacity));-->
|
||||
[Jest](./docs/jest.md)<!--rehype:style=background: rgb(153 66 91/var(\-\-bg\-opacity));-->
|
||||
[Lerna](./docs/lerna.md)<!--rehype:style=background: rgb(192 132 252/var(\-\-bg\-opacity));-->
|
||||
[npm](./docs/npm.md)<!--rehype:style=background: rgb(203 2 0/var(\-\-bg\-opacity));-->
|
||||
[package.json](./docs/package.json.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
|
||||
[RegEx](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
|
||||
[TypeScript](./docs/typescript.md)<!--rehype:style=background: rgb(49 120 198/var(\-\-bg\-opacity));-->
|
||||
[Vue 2](./docs/vue2.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 工具包
|
||||
|
||||
[npm](./docs/npm.md)<!--rehype:style=background: rgb(203 2 0/var(\-\-bg\-opacity));-->
|
||||
[package.json](./docs/package.json.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[nginx](./docs/nginx.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));-->
|
||||
[Semver](./docs/semver.md)<!--rehype:style=background: rgb(106 111 141/var(\-\-bg\-opacity));-->
|
||||
[Sketch](./docs/sketch.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
|
||||
[Jest](./docs/jest.md)<!--rehype:style=background: rgb(153 66 91/var(\-\-bg\-opacity));-->
|
||||
[RegEx](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
|
||||
[Sublime Text](./docs/sublime-text.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
|
||||
[VSCode](./docs/vscode.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
[Vim](./docs/vim.md)<!--rehype:style=background: rgb(9 150 8/var(\-\-bg\-opacity));-->
|
||||
[XPath](./docs/xpath.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
@ -36,9 +59,12 @@ Quick Reference
|
||||
[Chmod](./docs/chmod.md)<!--rehype:style=background: rgb(239 68 113/var(\-\-bg\-opacity));-->
|
||||
[Cron](./docs/cron.md)<!--rehype:style=background: rgb(239 68 68/var(\-\-bg\-opacity));-->
|
||||
[Git](./docs/git.md)<!--rehype:style=background: rgb(215 89 62/var(\-\-bg\-opacity));-->
|
||||
[Grep](./docs/grep.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[find](./docs/find.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[htop](./docs/htop.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Sed](./docs/sed.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[SSH](./docs/ssh.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
[Screen](./docs/screen.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 其它
|
||||
@ -54,7 +80,7 @@ Quick Reference
|
||||
|
||||
上面的列表没有看到你想要的? 您是否正在寻找一些备忘清单或参考资料,或者您有一些片段备忘清单要分享,这是一个最好的机会!
|
||||
|
||||
[`请求添加备忘单`](https://github.com/jaywcjlove/reference/issues/new?title=备忘清单+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`请求添加备忘单`](https://github.com/jaywcjlove/reference/issues/new?title=【备忘清单】+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`我有一张备忘单`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)<!--rehype:class=home-button text-grey&target=__blank-->
|
||||
<!--rehype:style=margin-top:3rem-->
|
||||
|
||||
|
1384
docs/css.md
Normal file
@ -25,12 +25,13 @@ $ docker run -d -p 80:80 docker/getting-started
|
||||
在前台创建并运行容器
|
||||
|
||||
```shell
|
||||
$ docker run -it -p 8001:8080 --name my-nginx nginx
|
||||
$ docker run -it -p --rm 8001:8080 --name my-nginx nginx
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
- `-it` - 交互式 bash 模式
|
||||
- `--rm` - 容器终止运行后自动删除容器文件
|
||||
- `-p 8001:8080` - 将 `8001` 端口映射到容器中的 `8080` 端口
|
||||
- `--name my-nginx` - 指定名称
|
||||
- `nginx` - 要使用的镜像
|
||||
@ -231,17 +232,17 @@ docker network create -d overlay \
|
||||
`docker login ` | 向 docker hub 进行身份验证
|
||||
`docker push user/image ` | 将镜像上传到 docker hub。
|
||||
|
||||
### 注册表命令
|
||||
### 镜像仓库命令
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
登录到注册表
|
||||
登录到镜像仓库
|
||||
|
||||
```shell
|
||||
$ docker login
|
||||
$ docker login localhost:8080
|
||||
```
|
||||
|
||||
从注册表注销
|
||||
从镜像仓库注销
|
||||
|
||||
```shell
|
||||
$ docker logout
|
||||
@ -291,6 +292,64 @@ $ docker volume ls
|
||||
$ docker volume prune
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`docker-compose up` | 创建和启动容器
|
||||
`docker-compose up -d` | 以分离模式创建和启动容器
|
||||
`docker-compose down` | 停止和删除容器、网络、映像和卷
|
||||
`docker-compose logs` | 查看容器的输出
|
||||
`docker-compose restart` | 重启所有服务
|
||||
`docker-compose pull` | 拉取所有图片服务
|
||||
`docker-compose build` | 构建所有图像服务
|
||||
`docker-compose config` | 验证并查看 Compose 文件
|
||||
`docker-compose scale <service_name>=<replica>` | 规模特殊服务
|
||||
`docker-compose top` | 显示正在运行的进程
|
||||
`docker-compose run -rm -p 2022:22 web bash` | 启动 Web 服务并运行 bash 作为其命令,删除旧容器。
|
||||
|
||||
### Docker Services
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`docker service create <options> <image> <command>` | 创建新服务
|
||||
`docker service inspect --pretty <service_name>` | 显示详细信息服务
|
||||
`docker service ls` | 列出服务
|
||||
`docker service ps` | 列出服务的任务
|
||||
`docker service scale <service_name>=<replica>` | 规模特殊服务
|
||||
`docker service update <options> <service_name>` | 更新服务选项
|
||||
|
||||
### Docker Stack
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`docker stack ls` | 列出此 Docker 主机上所有正在运行的应用程序
|
||||
`docker stack deploy -c <composefile> <appname>` | 运行指定的 Compose 文件
|
||||
`docker stack services <appname>` | 列出与应用关联的服务
|
||||
`docker stack ps <appname>` | 列出与应用关联的正在运行的容器
|
||||
`docker stack rm <appname>` | 拆掉一个应用程序
|
||||
|
||||
### Docker Machine
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`docker-machine create --driver virtualbox myvm1` | 创建虚拟机(Mac、Win7、Linux)
|
||||
`docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1` | Win10
|
||||
`docker-machine env myvm1` | 查看有关您的节点的基本信息
|
||||
`docker-machine ssh myvm1 "docker node ls"` | 列出集群中的节点
|
||||
`docker-machine ssh myvm1 "docker node inspect <node ID>"` | 检查节点
|
||||
`docker-machine ssh myvm1 "docker swarm join-token -q worker"` | 查看加入令牌
|
||||
`docker-machine ssh myvm1` | 打开与 VM 的 SSH 会话; 输入“exit”结束
|
||||
`docker-machine ssh myvm2 "docker swarm leave"` | 让工人离开群体
|
||||
`docker-machine ssh myvm1 "docker swarm leave -f"` | 让主人离开,杀群
|
||||
`docker-machine start myvm1` | 启动当前未运行的 VM
|
||||
`docker-machine stop $(docker-machine ls -q)` | 停止所有正在运行的虚拟机
|
||||
`docker-machine rm $(docker-machine ls -q)` | 删除所有虚拟机及其磁盘映像
|
||||
`docker-machine scp docker-compose.yml myvm1:~` | 将文件复制到节点的主目录
|
||||
`docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"` | 部署应用
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
|
738
docs/electron.md
Normal file
@ -0,0 +1,738 @@
|
||||
Electron 备忘清单
|
||||
====
|
||||
|
||||
此快速参考备忘单提供了 Electron v21 API 说明和使用示例。
|
||||
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 快速开始
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
[Electron](https://www.electronjs.org/) 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架
|
||||
|
||||
#### 创建你的应用程序
|
||||
|
||||
- 安装
|
||||
```bash
|
||||
mkdir my-app && cd my-app
|
||||
npm init
|
||||
```
|
||||
在项目根目录会生成 `package.json`
|
||||
```json
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Hello World!",
|
||||
"main": "main.js",
|
||||
"author": "Jane Doe",
|
||||
"license": "MIT"
|
||||
}
|
||||
```
|
||||
- 安装依赖包
|
||||
```bash
|
||||
npm install --save-dev electron
|
||||
```
|
||||
- 添加开发模式打开您的应用命令
|
||||
```js
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
}
|
||||
```
|
||||
- 运行命令,启动应用程序
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
入口都是 `main` 文件。这个文件控制了主进程,它运行在一个完整的Node.js环境中
|
||||
- 创建 `index.html` 页面
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
- 窗口中打开您的页面
|
||||
```js
|
||||
const {
|
||||
app,
|
||||
BrowserWindow
|
||||
} = require('electron');
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
});
|
||||
win.loadFile('index.html');
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### 关闭所有窗口时退出应用
|
||||
|
||||
```js
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 创建无边框窗口
|
||||
|
||||
```js
|
||||
const win = new BrowserWindow({
|
||||
frame: false
|
||||
})
|
||||
```
|
||||
|
||||
### 自定义标题栏样式
|
||||
|
||||
```js
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden'
|
||||
})
|
||||
```
|
||||
|
||||
### 控制红绿灯 (macOS)
|
||||
|
||||
```js
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'customButtonsOnHover'
|
||||
})
|
||||
```
|
||||
|
||||
### 通过预加载脚本从渲染器访问 Node.js
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
创建一个名为 preload.js 的新脚本如下
|
||||
|
||||
```js
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const dependency of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${dependency}-version`, process.versions[dependency])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
在创建窗口方法中传递 `preload` 参数
|
||||
|
||||
```js
|
||||
const path = require('path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
```
|
||||
|
||||
### 将的 process.versions 对象暴露给渲染器
|
||||
|
||||
```js
|
||||
const { contextBridge } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
'versions', {
|
||||
// 能暴露的不仅仅是函数,我们还可以暴露变量
|
||||
node:
|
||||
() => process.versions.node,
|
||||
chrome:
|
||||
() => process.versions.chrome,
|
||||
electron:
|
||||
() => process.versions.electron,
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
通过 `preload.js` 脚本将 `versions` 这一全局变量暴露给渲染器
|
||||
|
||||
### 启用拼写检查器
|
||||
|
||||
```js
|
||||
const myWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
spellcheck: true
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
设置拼写检查器以检查英语 和 法语
|
||||
|
||||
```js
|
||||
myWindow.session
|
||||
.setSpellCheckerLanguages([
|
||||
'en-US', 'fr'
|
||||
])
|
||||
```
|
||||
|
||||
app
|
||||
---
|
||||
<!--rehype:body-class=cols-6-->
|
||||
|
||||
### 事件绑定方法使用示例
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```js
|
||||
const { app } = require('electron');
|
||||
|
||||
app.on('session-created', (session) => {
|
||||
console.log(session);
|
||||
})
|
||||
|
||||
// 立即重启当前实例并向新的实例添加新的命令行参数的示例
|
||||
app.relaunch({
|
||||
args: process.argv.slice(1).concat(['--relaunch']);
|
||||
})
|
||||
|
||||
app.exit(0);
|
||||
```
|
||||
|
||||
### 方法
|
||||
<!--rehype:wrap-class=col-span-3 row-span-4-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`quit` | 尝试关闭所有窗口 [#](https://www.electronjs.org/zh/docs/latest/api/app#appquit)
|
||||
`exit` | 使用 exitCode 立即退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#appexitexitcode)
|
||||
`relaunch` | 当前实例退出,重启应用 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprelaunchoptions)
|
||||
`isReady` | 已完成初始化返回 boolean [#](https://www.electronjs.org/zh/docs/latest/api/app#appisready)
|
||||
`whenReady` | 初始化完成 [#](https://www.electronjs.org/zh/docs/latest/api/app#appwhenready)
|
||||
`focus` | 获得焦点/激活的 app [#](https://www.electronjs.org/zh/docs/latest/api/app#appfocusoptions)
|
||||
`hide` | 隐藏所有的应用窗口,不是最小化 [#](https://www.electronjs.org/zh/docs/latest/api/app#apphide-macos)
|
||||
`isHidden` _(mac)_ | 所有窗口是否都被隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/app#appishidden)
|
||||
`show` _(mac)_ | 显示隐藏后的应用程序窗口 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshow-macos)
|
||||
`setAppLogsPath` | 设置或创建一个您的应用程序日志目录 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetapplogspathpath)
|
||||
`getAppPath` | 获取当前应用程序目录 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapppath)
|
||||
`getPath(name)` | 与 name 关联的目录或文件的路径 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetpathname)
|
||||
`getFileIcon` | 一个 NativeImage 类型的应用图标 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetfileiconpath-options)
|
||||
`setPath(name)` | 重写 name 的路径特定文件夹或文件 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetpathname-path)
|
||||
`getVersion` | 应用程序的版本号 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetversion)
|
||||
`getName` | 应用程序的名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetname)
|
||||
`setName` | 设置当前应用程序的名字 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetname)
|
||||
`getLocale` | 当前应用程序区域 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetlocale)
|
||||
`getLocaleCountryCode` | 获取双字母 [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) 国家代码 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetlocalecountrycode)
|
||||
`getSystemLocale` | 当前系统语言环境 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetsystemlocale)
|
||||
`addRecentDocument` _(win/mac)_ | 最近打开的文件列表添加新路径 [#](https://www.electronjs.org/zh/docs/latest/api/app#appaddrecentdocumentpath-macos-windows)
|
||||
`clearRecentDocuments` _(win/mac)_ | 清空最近打开的文档列表[#](https://www.electronjs.org/zh/docs/latest/api/app#appclearrecentdocuments)
|
||||
`setAsDefaultProtocolClient` | 设置协议(URI scheme)默认处理程序 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetasdefaultprotocolclientprotocol-path-args)
|
||||
`removeAsDefaultProtocolClient` | 移除默认处理器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appremoveasdefaultprotocolclientprotocol-path-args-macos-windows)
|
||||
`isDefaultProtocolClient` | 可执行程序是否是协议 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisdefaultprotocolclientprotocol-path-args)
|
||||
`getApplicationNameForProtocol` | 返回默认处理器的应用程序名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapplicationnameforprotocolurl)
|
||||
`getApplicationInfoForProtocol` _(win/mac)_ | 返回包含应用程序名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetapplicationinfoforprotocolurl-macos-windows)
|
||||
`setUserTasks` _(win)_ | 添加 tasks 到Jump List的Tasks类别 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetusertaskstasks-windows)
|
||||
`getJumpListSettings` _(win)_ | 获取跳转列表 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetjumplistsettings-windows)
|
||||
`setJumpList` _(win)_ | 设置跳转列表 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetjumplistcategories-windows)
|
||||
`requestSingleInstanceLock` | 返回应用程序实例是否成功取了锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprequestsingleinstancelockadditionaldata)
|
||||
`hasSingleInstanceLock` | 返回应用实例当前是否持有单例锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#apphassingleinstancelock)
|
||||
`releaseSingleInstanceLock` | 释放所有创建的锁 [#](https://www.electronjs.org/zh/docs/latest/api/app#appreleasesingleinstancelock)
|
||||
`setUserActivity` _(mac)_ | 创建 NSUserActivity 并将其设置为当前活动 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetuseractivitytype-userinfo-webpageurl-macos)
|
||||
`getCurrentActivityType` _(mac)_ | 正在运行的 activity 的类型 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetcurrentactivitytype-macos)
|
||||
`invalidateCurrentActivity` _(mac)_ | 使当前的Handoff用户活动无效 [#](https://www.electronjs.org/zh/docs/latest/api/app#appinvalidatecurrentactivity-macos)
|
||||
`resignCurrentActivity` _(mac)_ | 将当前 Handoff 用户活动标记为非活动,但不使其失效 [#](https://www.electronjs.org/zh/docs/latest/api/app#appresigncurrentactivity-macos)
|
||||
`updateCurrentActivity` _(mac)_ | 将项目从 用户信息 合并到其当前 用户信息 字典中 [#](https://www.electronjs.org/zh/docs/latest/api/app#appupdatecurrentactivitytype-userinfo-macos)
|
||||
`setAppUserModelId` _(win)_ | 改变当前应用的 Application User Model ID 为 id [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetappusermodelidid-windows)
|
||||
`setActivationPolicy` _(mac)_ | 为给定应用设置激活策略 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetactivationpolicypolicy-macos)
|
||||
`importCertificate` _(linux)_ | 将 pkcs12 格式的证书导入到平台证书库 [#](https://www.electronjs.org/zh/docs/latest/api/app#appimportcertificateoptions-callback-linux)
|
||||
`configureHostResolver` | 配置主机解析器 (DNS 和 DNS-over-HTTPS) [#](https://www.electronjs.org/zh/docs/latest/api/app#appconfigurehostresolveroptions)
|
||||
`disableHardwareAcceleration` | 禁用当前应用程序的硬件加速 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdisablehardwareacceleration)
|
||||
`disableDomainBlockingFor3DAPIs` | GPU 进程频繁崩溃,在每个域的基础上重新启动,禁用该行为 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdisabledomainblockingfor3dapis)
|
||||
`getAppMetrics` | 返回 [ProcessMetric[]](https://www.electronjs.org/zh/docs/latest/api/structures/process-metric) [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetappmetrics)
|
||||
`getGPUFeatureStatus` | 返回 [GPUFeatureStatus](https://www.electronjs.org/zh/docs/latest/api/structures/gpu-feature-status) [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetgpufeaturestatus)
|
||||
`getGPUInfo` | GPU 信息 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetgpuinfoinfotype)
|
||||
`setBadgeCount` _(mac/linux)_ | 应用设置计数器角标 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetbadgecountcount-linux-macos)
|
||||
`getBadgeCount` _(mac/linux)_ | 获取计数器(badge)显示的当前值 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetbadgecount-linux-macos)
|
||||
`isUnityRunning` _(linux)_ | 前桌面环境是否为 Unity 启动器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisunityrunning)
|
||||
`getLoginItemSettings` _(mac/win)_ | 为 openAtLogin 设置相同的参数已确保正确的设置 [#](https://www.electronjs.org/zh/docs/latest/api/app#appgetloginitemsettingsoptions-macos-windows)
|
||||
`setLoginItemSettings` _(mac/win)_ | 传递指定应用程序名称的参数 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetloginitemsettingssettings-macos-windows)
|
||||
`isAccessibilitySupportEnabled` _(mac/win)_ | 是否开启了辅助功能 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisaccessibilitysupportenabled-macos-windows)
|
||||
`setAccessibilitySupportEnabled` _(mac/win)_ | 启用或禁用访问权限树视图 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetaccessibilitysupportenabledenabled-macos-windows)
|
||||
`showAboutPanel` | 显示程序的"关于"面板选项 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshowaboutpanel)
|
||||
`setAboutPanelOptions` | 设置 "关于" 面板选项 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetaboutpaneloptionsoptions)
|
||||
`isEmojiPanelSupported` | 当前操作系统是否支持本地 emoji 选择器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisemojipanelsupported)
|
||||
`showEmojiPanel` _(mac/win)_ | 打开系统自身的emjio选取器 [#](https://www.electronjs.org/zh/docs/latest/api/app#appshowemojipanel)
|
||||
`startAccessingSecurityScopedResource` _(mac)_ | 开始访问安全范围内的资源 [#](https://www.electronjs.org/zh/docs/latest/api/app#appstartaccessingsecurityscopedresourcebookmarkdata-macos)
|
||||
`enableSandbox` | 在应用程序上启用完全沙盒模式 [#](https://www.electronjs.org/zh/docs/latest/api/app#appenablesandbox)
|
||||
`isInApplicationsFolder` _(mac)_ | 是否从系统应用程序文件夹运行 [#](https://www.electronjs.org/zh/docs/latest/api/app#appisinapplicationsfolder-macos)
|
||||
`moveToApplicationsFolder` _(mac)_ | [#](https://www.electronjs.org/zh/docs/latest/api/app#appmovetoapplicationsfolderoptions-macos)
|
||||
`isSecureKeyboardEntryEnabled` _(mac)_ | 是否已启用安全键盘输入 [#](https://www.electronjs.org/zh/docs/latest/api/app#appissecurekeyboardentryenabled-macos)
|
||||
`setSecureKeyboardEntryEnabled` _(mac)_ | 在应用中启用安全键盘输入 [#](https://www.electronjs.org/zh/docs/latest/api/app#appsetsecurekeyboardentryenabledenabled-macos)
|
||||
|
||||
### 启动时激活主实例窗口的示例
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```js
|
||||
const { app } = require('electron');
|
||||
let myWindow = null;
|
||||
|
||||
const additionalData = { myKey: 'myValue' };
|
||||
const gotTheLock = app.requestSingleInstanceLock(additionalData);
|
||||
|
||||
if (!gotTheLock) {
|
||||
app.quit();
|
||||
} else {
|
||||
app.on(
|
||||
'second-instance',
|
||||
(event, commandLine, workingDirectory, additionalData) => {
|
||||
// 输出从第二个实例中接收到的数据
|
||||
console.log(additionalData);
|
||||
|
||||
// 有人试图运行第二个实例,我们应该关注我们的窗口
|
||||
if (myWindow) {
|
||||
if (myWindow.isMinimized()) myWindow.restore();
|
||||
myWindow.focus();
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 创建 myWindow, 加载应用的其余部分, etc...
|
||||
app.whenReady().then(() => {
|
||||
myWindow = createWindow();
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 事件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`will-finish-launching` | 基础的启动的时候被触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-finish-launching)
|
||||
`ready` | 完成初始化时,触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-ready)
|
||||
`window-all-closed` | 在程序关闭窗口前发信号 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-window-all-closed)
|
||||
`before-quit` | 当所有窗口被关闭后触发,应用程序将退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-before-quit)
|
||||
`will-quit` | 所有窗口被关闭后触发,应用程序将退出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-quit)
|
||||
`quit` | 在应用程序退出时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-quit)
|
||||
`open-file` _(mac)_ | 在应用中打开一个文件时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-open-file-macos)
|
||||
`open-url` _(mac)_ | 应用中打开一个 URL 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-open-url-macos)
|
||||
`activate` _(mac)_ | 当应用被激活时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-activate-macos)
|
||||
`did-become-active` _(mac)_ | 不同设备的活动想要恢复时在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-did-become-active-macos)
|
||||
`continue-activity` _(mac)_ | 不同设备的活动通过 Handoff 想要恢复时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-continue-activity-macos)
|
||||
`will-continue-activity` _(mac)_ | 恢复来自不同设备的活动之前在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-will-continue-activity-macos)
|
||||
`continue-activity-error` _(mac)_ | 不同设备的活动无法恢复时在切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-continue-activity-error-macos)
|
||||
`activity-was-continued` _(mac)_ | 活动在另一个设备上成功恢复后切换期间触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-activity-was-continued-macos)
|
||||
`update-activity-state` _(mac)_ | 当即将在另一台设备上恢复切换时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-update-activity-state-macos)
|
||||
`new-window-for-tab` _(mac)_ | 用户点击原生的 macOS 新标签按钮时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-new-window-for-tab-macos)
|
||||
`browser-window-blur` | 当 browserWindow 变得模糊时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-blur)
|
||||
`browser-window-focus` | 当 browserWindow 获得焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-focus)
|
||||
`browser-window-created` | 创建新的 browserWindow 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-browser-window-created)
|
||||
`web-contents-created` | 创建新的 webContents 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-web-contents-created)
|
||||
`certificate-error` | 当对 url 的 certificate 证书验证失败触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-certificate-error)
|
||||
`select-client-certificate` | 当一个客户证书被请求的时候发出 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-select-client-certificate)
|
||||
`login` | 当 webContents 要进行基本身份验证时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-login)
|
||||
`gpu-info-update` | 每当有 GPU 信息更新时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-gpu-info-update)
|
||||
~~`gpu-process-crashed`~~ ~~废弃~~ | 当 gpu 进程崩溃或关闭(杀死)时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-gpu-process-crashed-已废弃)
|
||||
~~`renderer-process-crashed`~~ ~~废弃~~ | 渲染器进程崩溃或关闭(杀死)时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-renderer-process-crashed-已废弃)
|
||||
`render-process-gone` | 渲染器进程意外消失时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-render-process-gone)
|
||||
`child-process-gone` | 子进程意外消失时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-child-process-gone)
|
||||
`accessibility-support-changed` | 当 Chrome 的辅助功能状态改变时触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-accessibility-support-changed--macos---windows-)
|
||||
`session-created` | 创建了一个新的 session 后被触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-session-created)
|
||||
`second-instance` | 在你的应用程序的首个实例中触发 [#](https://www.electronjs.org/zh/docs/latest/api/app#事件-second-instance)
|
||||
|
||||
### 属性
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`accessibilitySupportEnabled` _(mac/win)_ | 是否开启了辅助功能 [#](https://www.electronjs.org/zh/docs/latest/api/app#appaccessibilitysupportenabled-macos-windows)
|
||||
`applicationMenu` | 传递 Menu 来给此属性赋值 [#](https://www.electronjs.org/zh/docs/latest/api/app#appapplicationmenu)
|
||||
`badgeCount` _(mac/linux)_ | 返回应用角标计数的 Integer 属性 [#](https://www.electronjs.org/zh/docs/latest/api/app#appbadgecount-linux-macos)
|
||||
`commandLine` | Chromium 使用的命令行参数 [#](https://www.electronjs.org/zh/docs/latest/api/app#appcommandline-只读)
|
||||
`dock` _(mac/只读)_ | 用户dock中对应用图标进行操作 [#](https://www.electronjs.org/zh/docs/latest/api/app#appdock-macos-只读)
|
||||
`isPackaged` _(只读)_ | 应用是否已经打包 [#](https://www.electronjs.org/zh/docs/latest/api/app#appispackaged-只读)
|
||||
`name` | 当前应用程序的名称 [#](https://www.electronjs.org/zh/docs/latest/api/app#appname)
|
||||
`userAgentFallback` | 全局回退的用户代理字符串 [#](https://www.electronjs.org/zh/docs/latest/api/app#appuseragentfallback)
|
||||
~~`runningUnderRosettaTranslation`~~ _(mac)_ | 提示下载应用程序的 arm64 版本 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprunningunderrosettatranslation-macos-只读-弃用)
|
||||
`runningUnderARM64Translation` _(mac/win)_ | 前应用正在使用 ARM64 运行环境 [#](https://www.electronjs.org/zh/docs/latest/api/app#apprunningunderarm64translation-只读-macos-windows)
|
||||
|
||||
BrowserWindow
|
||||
----
|
||||
<!--rehype:body-class=cols-6-->
|
||||
|
||||
### 参数
|
||||
<!--rehype:wrap-class=col-span-3 row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`width` _整数_ | 窗口的宽度(以像素为单位)。默认值 _(800)_
|
||||
`height` _整数_ | 窗口的高度(以像素为单位)。默认值 _(600)_
|
||||
`x` _整数_ (**可选**) | 窗口相对于屏幕左侧偏移量。默认值窗口居中
|
||||
`y` _整数_ (**可选**) | 窗口相对于屏幕顶端偏移量。默认值窗口居中
|
||||
`useContentSize` _boolean_ | _(宽)_ 和 _(高)_ 设置为web页面的尺寸。默认值 _(false)_
|
||||
`center` _boolean_ | 窗口是否在屏幕居中。默认值 _(false)_
|
||||
`minHeight` _整数_ | 窗口的最小高度。默认值 _(0)_
|
||||
`maxWidth ` _整数_ | 窗口的最大宽度。默认值不限
|
||||
`maxHeight ` _整数_ | 窗口的最大高度。默认值不限
|
||||
`resizable` _boolean_ | 窗口大小是否可调整。默认值 _(true)_
|
||||
`movable` _boolean_ _(win/mac)_ | 窗口是否可移动。默认值 _(true)_
|
||||
`minimizable` _boolean_ _(win/mac)_ | 窗口是否可最小化。默认值 _(true)_
|
||||
`maximizable` _boolean_ _(win/mac)_ | 窗口是否最大化。默认值 _(true)_
|
||||
`closable` _boolean_ _(win/mac)_ | 窗口是否可关闭。默认值 _(true)_
|
||||
`focusable` _boolean_ | 窗口是否可以聚焦. 默认值 _(true)_。在 Windows 中设置 _(focusable: false)_ 也意味着设置了 _(skipTaskbar: true)_ 在 Linux 中设置 _(focusable: false)_ 时窗口停止与 wm 交互, 并且窗口将始终置顶
|
||||
`alwaysOnTop` _boolean_ | 窗口是否永远在别的窗口的上面。默认值 _(false)_
|
||||
`fullscreen` _boolean_ | 窗口是否全屏。为 _(false)_ 时 macOS 上按钮将被隐藏或禁用。默认值 _(false)_
|
||||
`fullscreenable` _boolean_ | 窗口是否可以进入全屏状态。macOS上,最大化/缩放按钮是否可用 默认值 _(true)_
|
||||
`simpleFullscreen` _boolean_ _(mac)_ | 在 macOS 上使用 pre-Lion 全屏。默认值 _(false)_
|
||||
`skipTaskbar` _boolean_ _(win/mac)_ | 是否在任务栏中显示窗口。默认值 _(false)_
|
||||
`kiosk` _boolean_ | 窗口是否进入kiosk模式。默认值 _(false)_
|
||||
`title` _string_ | 默认窗口标题 默认为 _("Electron")_ 。如果由 _(loadURL())_ 加载的HTML文件中含有标签 _(<title>)_ ,此属性将被忽略
|
||||
`icon` _NativeImage/string_ | 窗口图标。在 Windows 上推荐使用 _(ICO)_ 图标来获得最佳的视觉效果, 默认使用可执行文件的图标
|
||||
`show` _boolean_ | 窗口是否在创建时显示。默认值 _(true)_
|
||||
`paintWhenInitiallyHidden` _boolean_ | 当 _(show)_ 为 _(false)_ 并且渲染器刚刚被创建时,它是否应激活。为了让 _(document.visibilityState)_ 在 _(show: false)_ 的情况下第一次加载时正确地工作,你应该把这个设置成 _(false)_。设置为 _(false)_ 将会导致 _(ready-to-show)_ 事件不触发。默认值 _(true)_
|
||||
`frame` _boolean_ | 设置为 _(false)_ 时可以创建一个无边框窗口,默认值 _(true)_
|
||||
`parent` _BrowserWindow_ | 指定父窗口 默认值 _(null)_
|
||||
`modal` _boolean_ | 当前是否为模态窗口。只有当窗口是子窗口时才起作用。默认值 _(false)_
|
||||
`acceptFirstMouse` _boolean_ _(mac)_ | 点击 非活动窗口是否会穿透到 web contents。默认值 _(false)_
|
||||
`disableAutoHideCursor` _boolean_ | 是否在打字时隐藏光标。默认值 _(false)_
|
||||
`autoHideMenuBar` _boolean_ | 自动隐藏菜单栏,除非按了_(Alt)_键。默认值 _(false)_
|
||||
`enableLargerThanScreen` _boolean_ _(mac)_ | 使窗口尺寸可大于屏幕的大小。其他操作系统默认允许大于屏幕的窗口。默认值 _(false)_
|
||||
`backgroundColor` _string_ | 窗口背景色,格式为 Hex, RGB, RGBA, HSL, HSLA 或 CSS 命名颜色。如果 _(transparent)_ 设置为 _(true)_,则支持 #AARRGGBB 格式的透明。默认值 _(#FFF)_(白色)
|
||||
`hasShadow` _boolean_ | 窗口是否有阴影. 默认值 _(true)_
|
||||
`opacity` _number_ _(win/mac)_ | 设置窗口的初始透明度,在 0.0(全透明)和 1.0(完全不透明)之间 。 目前仅在 Windows 和 macOS上实现。
|
||||
`darkTheme` _boolean_ | 强制窗口使用深色主题,只在部分GTK+3桌面环境下有效。 默认值 _(false)_.
|
||||
`transparent` _boolean_ | 使窗口 <a href="/zh/docs/latest/tutorial/window-customization#create-transparent-windows">透明</a>。 默认值 _(false)_. 在Windows上,仅在无边框窗口下起作用。
|
||||
`type` _string_ | 窗口的类型, 默认为普通窗口. 更多信息见下文
|
||||
`visualEffectState` _string_ _(mac)_ | 在 macOS 上指定外观应如何响应窗口活动状态。 必须与 _(vibrancy)_ 属性一起使用。 可能的值有
|
||||
` visualEffectState.followWindow` | 当窗口处于激活状态时,后台应自动显示为激活状态,当窗口处于非激活状态时,后台应自动显示为非激活状态。 默认为该值。
|
||||
` visualEffectState.active` | 后台应一直显示为激活状态。
|
||||
` visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
|
||||
` titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
` titleBarStyle.hidden` | 在一个隐藏的标题栏和一个全尺寸大小的内容窗口中取得结果。 在 macOS 内, 窗口将一直拥有位于左上的标准窗口控制器 _(“traffic lights”)_。 在 Windows上,当与 _(titleBarOverlay: true)_ 合并时,它将激活窗口控件叠加(详情请参阅 _(titleBarOverlay)_),否则将不会显示窗口控件。
|
||||
` titleBarStyle.hiddenInset` _(mac)_ | 隐藏标题栏,使用窗口边缘稍微小的红绿灯按钮替代。
|
||||
` titleBarStyle.customButtonsOnHover` _(mac)_ | 隐藏的标题栏的全尺寸的内容窗口, 红绿灯按钮在鼠标悬停在窗口左上方时显示。**注意:**此选项目前是实验性的。
|
||||
`trafficLightPosition` _Point_ _(mac)_ | 在无边框窗口中设置灯绿灯按钮位置。
|
||||
`roundedCorners` _boolean_ _(mac)_ | 无边框窗口在 macOS 上,是否应该有圆角。 默认值为 _(true)_。 属性设置为 _(false)_ ,将阻止窗口是可全屏的。
|
||||
~~`fullscreenWindowTitle`~~ _boolean_ _(mac)_ ~~_已弃用_~~ | _titleBarStyle_ 设置为 _(hiddenInset)_ 时,在 macOS 全屏模式下标题栏显示标题。默认值为 _(false)_.
|
||||
`thickFrame` _boolean_ | 对 Windows 上的无框窗口使用 _(WS_THICKFRAME)_ 样式,会增加标准窗口框架。 设置为 _(false)_ 时将移除窗口的阴影和动画. 默认值为 _(true)_。
|
||||
`vibrancy` _string_ _(mac)_ | 为窗口添加一种类型的动态效果,仅 macOS。 可以是 _(appearance-based)_,_(light)_,_(dark)_,_(titlebar)_,_(selection)_,_(menu)_,_(popover)_,_(sidebar)_,_(medium-light)_,_(ultra-dark)_,_(header)_,_(sheet)_,_(window)_,_(hud)_,_(fullscreen-ui)_,_(tooltip)_,_(content)_,_(under-window)_ 或 _(under-page)_。 请注意 _(appearance-based)_,_(light)_,_(dark)_,_(medium-light)_ 和 _(ultra-dark)_ 已弃用,在 macOS Catalina (10.15) 中已经移除。
|
||||
`zoomToPageWidth` _boolean_ _(mac)_ | 在 macOS 上控制,当按住 option 点击工具栏绿色红绿灯按钮或点击窗口 > 放大菜单项的行为。 如果为 _(true)_,窗口为将会缩放到适合宽度,若为 _(false)_ 将会放大到屏幕宽度。 这也会影响,直接调用 _(maximize())_ 的行为。 默认值为 _(false)_.
|
||||
`tabbingIdentifier` _string_ _(mac)_ | 选项卡组名称,允许在原生选择卡中打开窗口,macOS 10.12+ 支持。 Windows 中,有相同选项卡标识的将会组合在一起。 这会添加一个原生新增选项卡按钮到你窗口的选项卡栏,同时 _(app)_ 和窗口允许接收 _(new-window-for-tab)_ 事件。
|
||||
`webPreferences` _Object_ | 网页功能设置。
|
||||
` webPreferences.devTools` _boolean_ | 是否开启 DevTools. 如果设置为 _(false)_, 则无法使用 _(BrowserWindow.webContents.openDevTools ())_ 打开 DevTools。 默认值为 _(true)_。
|
||||
` webPreferences.nodeIntegration` _boolean_ | 是否启用Node integration. 默认值为 _(false)_.
|
||||
` webPreferences.nodeIntegrationInWorker` _boolean_ | 是否在Web工作器中启用了Node集成. 默认值为 _(false)_. 更多内容参见 [多线程](https://www.electronjs.org/docs/latest/tutorial/multithreading)
|
||||
` webPreferences.nodeIntegrationInSubFrames` _boolean_ **_实验性_**| 是否允许在子页面(iframe)或子窗口(child window)中集成Node.js; 预先加载的脚本会被注入到每一个iframe,你可以用 _(process.isMainFrame)_ 来判断当前是否处于主框架(main frame)中。
|
||||
` webPreferences.preload` _string_ | 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志[参考示例](https://www.electronjs.org/docs/latest/api/context-bridge#exposing-node-global-symbols)
|
||||
` webPreferences.sandbox` _boolean_ | 如果设置该参数, 沙箱的渲染器将与窗口关联, 使它与Chromium OS-level 的沙箱兼容, 并禁用 Node. js 引擎。 它与 _(nodeIntegration)_ 的选项不同,且预加载脚本的 API 也有限制。[更多详情](https://www.electronjs.org/docs/latest/tutorial/sandbox)
|
||||
` webPreferences.session` | [Session](https://www.electronjs.org/docs/latest/api/session#class-session) 设置页面的 session 而不是直接忽略 Session 对象, 也可用 _(partition)_ 选项来代替,它接受一个 partition 字符串. 同时设置了_(session)_ 和 _(partition)_时, _(session)_ 的优先级更高. 默认使用默认的 session.
|
||||
` webPreferences.partition` | string (optional) - 通过 session 的 partition 字符串来设置界面session. 如果 _(partition)_ 以 _(persist:)_开头, 该页面将使用持续的 session,并在所有页面生效,且使用同一个_(partition)_. 如果没有 _(persist:)_ 前缀, 页面将使用 in-memory session. 通过分配相同的 _(partition)_, 多个页可以共享同一会话。 默认使用默认的 session.
|
||||
` webPreferences.zoomFactor` _number_ | 页面的默认缩放系数, _(3.0)_ 表示 _(300%)_。 默认值为 _(1.0)_.
|
||||
` webPreferences.javascript` _boolean_ | 是否启用 JavaScript 支持。 默认值为 _(true)_。
|
||||
` webPreferences.webSecurity` _boolean_ | 当设置为 _(false)_, 它将禁用同源策略 (通常用来测试网站), 如果此选项不是由开发者设置的,还会把 _(allowRunningInsecureContent)_设置为 _(true)_. 默认值为 _(true)_
|
||||
` webPreferences.allowRunningInsecureContent` _boolean_ | 允许一个 https 页面运行来自http url的JavaScript, CSS 或 plugins。 默认值为 _(false)_
|
||||
` webPreferences.images` _boolean_ | 允许加载图片。 默认值为 _(true)_
|
||||
` webPreferences.imageAnimationPolicy` _string_ | 指定如何运行图像动画 (比如: GIF等). 可以是 _(animate)_, _(animateOnce)_ 或 _(noAnimation)_。默认值为 _(animate)_
|
||||
` webPreferences.textAreasAreResizable` _boolean_ | 允许调整 TextArea 元素大小。 默认值为 _(true)_
|
||||
` webPreferences.webgl` _boolean_ | 启用 WebGL 支持。 默认值为 _(true)_
|
||||
` webPreferences.plugins` _boolean_ | 是否应该启用插件。 默认值为 _(false)_
|
||||
` webPreferences.experimentalFeatures` _boolean_ | 启用 Chromium 的实验功能。 默认值为 _(false)_
|
||||
` webPreferences.scrollBounce` _boolean_ _(mac)_ | 启用滚动回弹(橡皮筋)效果。 默认值为 _(false)_
|
||||
` webPreferences.enableBlinkFeatures`_string_ | 以 _(逗号)_ 分隔的需要启用的特性列表,譬如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
` webPreferences.disableBlinkFeatures` _string_ | 以 _(,)_ 分隔的禁用特性列表, 如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
`defaultFontFamily` _Object_ | 为 font-family 设置默认字体
|
||||
` defaultFontFamily.standard` _string_ |默认值为 _(Times New Roman)_
|
||||
` defaultFontFamily.serif` _string_ | 默认值为 _(Times New Roman)_
|
||||
` defaultFontFamily.sansSerif` _string_ | 默认值为 _(Arial)_
|
||||
` defaultFontFamily.monospace` _string_ | 默认值为 _(Courier New)_
|
||||
` defaultFontFamily.cursive` _string_ | 默认值为 _(Script)_
|
||||
` defaultFontFamily.fantasy` _string_ | 默认值为 _(Impact)_
|
||||
`defaultFontSize` _Integer_ | 默认值为 _(16)_
|
||||
`defaultMonospaceFontSize` _Integer_ | 默认值为 _(13)_
|
||||
`minimumFontSize` _Integer_ | 默认值为 _(0)_
|
||||
`defaultEncoding` _string_ | 默认值为 _(ISO-8859-1)_
|
||||
`backgroundThrottling` _boolean_ | 是否在页面成为背景时限制动画和计时器。 这也会影响到 _[Visibility API](https://www.electronjs.org/docs/latest/api/browser-window#page-visibility)_。默认值为 _(true)_
|
||||
`offscreen` _boolean_ | 是否绘制和渲染可视区域外的窗口。默认值为 _(false)_。更多详情, 请参见 [offscreen rendering tutorial](https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering)
|
||||
`contextIsolation` _boolean_ | 是否在独立 JavaScript 环境中运行 Electron API和指定的_(preload)_ 脚本。默认为 _(true)_。 _(预加载)_脚本所运行的上下文环境只能访问其自身专用的 _(文档)_ 和全局 _(窗口)_,其自身一系列内置的JavaScript (_(Array)_, _(Object)_, _(JSON)_, 等等) 也是如此,这些对于已加载的内容都是不可见的。 Electron API 将只在_(预加载)_脚本中可用,在已加载页面中不可用。 这个选项应被用于加载可能不被信任的远程内容时来确保加载的内容无法篡改_(预加载)_脚本和任何正在使用的Electron api。 该选项使用的是与[Chrome内容脚本](https://developer.chrome.com/extensions/content_scripts#execution-environment)相同的技术。你可以在开发者工具Console选项卡内顶部组合框中选择 'Electron Isolated Context'条目来访问这个上下文
|
||||
`webviewTag` _boolean_ | 是否启用 [_(<webview>)_ tag](https://www.electronjs.org/docs/latest/api/webview-tag)标签。默认值为 _(false)_。**注意:** 为 _(< webview>)_ 配置的 _(preload)_ 脚本在执行时将启用节点集成, 因此应确保远程或不受信任的内容无法创建恶意的 _(preload)_ 脚本 。 可以使用 [webContents](https://www.electronjs.org/docs/latest/api/web-contents) 上的 _(will-attach-webview)_ 事件对 _(preload)_ 脚本进行剥离, 并验证或更改 _(<webview>)_ 的初始设置
|
||||
`additionalArguments` _string[]_ | strin一个将被附加到当前应用程序的渲染器进程中_(process.argv)_的字符串列表。可用于将少量的数据传递到渲染器进程预加载脚本中。
|
||||
`safeDialogs` _boolean_ | 是否启用浏览器样式的持续对话框保护。 默认值为 _(false)_
|
||||
`safeDialogsMessage` _string_ | 当持续对话框保护被触发时显示的消息。 如果没有定义,那么将使用缺省的消息。注意:当前缺省消息是英文,并没有本地化
|
||||
`disableDialogs` _boolean_ | 是否完全禁用对话框。 覆盖 _(safeDialogs)_。 默认值为 _(false)_
|
||||
`navigateOnDragDrop` _boolean_ | 将文件或链接拖放到页面上时是否触发页面跳转。 默认值为 _(false)_
|
||||
`autoplayPolicy` _string_ | 窗口中内容要使用的自动播放策略,值可以是 _(no-user-gesture-required)_, _(user-gesture-required)_, _(document-user-activation-required)_。默认为 _(no-user-gesture-required)_
|
||||
`disableHtmlFullscreenWindowResize` _boolean_ | 是否阻止窗口在进入 HTML 全屏时调整大小。默认值为 _(false)_
|
||||
`accessibleTitle` _string_ | 仅提供给如屏幕读取器等辅助工具的替代标题字符串。此字符串不直接对用户可见
|
||||
`spellcheck` _boolean_ | 是否启用内置拼写检查器。 默认值为 _(true)_
|
||||
`enableWebSQL` _boolean_ | 是否启用 [WebSQL api](https://www.w3.org/TR/webdatabase/)。 默认值为 _(true)_
|
||||
`v8CacheOptions` _string_ | 强制 blink 使用 v8 代码缓存策略。 可接受的值为:
|
||||
` v8CacheOptions.none` | 禁用代码缓存
|
||||
` v8CacheOptions.code` | 基于启发式代码缓存
|
||||
` v8CacheOptions.bypassHeatCheck` | 绕过启发式代码缓存,但使用懒编译。
|
||||
` v8CacheOptions.bypassHeatCheckAndEagerCompile` | 与上面相同,除了编译是及时的。 默认策略是 _(code)_
|
||||
`enablePreferredSizeMode` _boolean_ | 是否启用首选大小模式。 首选大小是包含文档布局所需的最小大小--无需滚动。 启用该属性将导致在首选大小发生变化时,在 _(WebContents)_ 上触发 _(preferred-size-changed)_ 事件。默认值为 _(false)_
|
||||
`titleBarOverlay` _Object/Boolean_ | 当在 macOS 使用无框窗口结合 _(win.setWindowButtonVisibility(true))_ 或使用 _(titleBarStyle)_ 以便标准窗口控制 (在 macOS为 "traffic lights") 可见,此属性将启用 Window Controls Overlay [JavaScript APIs](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis) 和 [CSS Environment Variables](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables)。指定 _(true)_ 将导致覆盖默认系统颜色。 默认值为 _(false)_
|
||||
`color` _String_ _(win)_ | 启用窗口控制时覆盖面的 CSS 颜色 默认是系统颜色
|
||||
`symbolColor` _String_ _(win)_ | 启用时窗口控制中符号的 CSS 颜色 默认是系统颜色
|
||||
`height` _Integer_ _(win/mac)_ | 标题栏和 Window Controls Overlay,以像素为单位。 默认值为系统高度
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### 实例事件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const child = new BrowserWindow({ modal: true, show: false })
|
||||
child.loadURL('https://github.com')
|
||||
child.once('ready-to-show', () => {
|
||||
child.show()
|
||||
})
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`page-title-updated` | 文档更改标题时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-page-title-updated)
|
||||
`close` | 在窗口要关闭的时候触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-close)
|
||||
`closed` | 在窗口关闭时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-closed)
|
||||
`session-end` _(win)_ | 因为强制关机/重启/会话注销而导致窗口会话结束时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-session-end-windows)
|
||||
`unresponsive` | 网页变得未响应时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-unresponsive)
|
||||
`responsive` | 未响应的页面变成响应时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-responsive)
|
||||
`blur` | 当窗口失去焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-blur)
|
||||
`focus` | 当窗口获得焦点时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-focus)
|
||||
`show` | 当窗口显示时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-show)
|
||||
`hide` | 当窗口隐藏时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-hide)
|
||||
`ready-to-show` | 当页面已经渲染完成(还没有显示)窗口可以被显示时触发[#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-ready-to-show)
|
||||
`maximize` | 窗口最大化时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-maximize)
|
||||
`unmaximize` | 当窗口从最大化状态退出时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-unmaximize)
|
||||
`minimize` | 窗口最小化时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-minimize)
|
||||
`restore` | 当窗口从最小化状态恢复时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-restore)
|
||||
`will-resize` _(mac/win)_ | 调整窗口大小前触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-will-resize-macos-windows)
|
||||
`resize` | 调整窗口大小后触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-resize)
|
||||
`resized` _(mac/win)_ | 当窗口完成调整大小后触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件resized-macos-windows)
|
||||
`will-move` _(mac/win)_ | 窗口移动前触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-will-move-macos-windows)
|
||||
`move` | 窗口移动到新位置时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-move)
|
||||
`moved` _(mac/win)_ | 当窗口移动到新位置时触发一次 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-moved-macos-windows)
|
||||
`enter-full-screen` | 窗口进入全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-enter-full-screen)
|
||||
`leave-full-screen` | 窗口离开全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-leave-full-screen)
|
||||
`enter-html-full-screen` | 窗口进入由HTML API 触发的全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-enter-html-full-screen)
|
||||
`leave-html-full-screen` | 窗口离开由HTML API触发的全屏状态时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-leave-html-full-screen)
|
||||
`always-on-top-changed` | 设置或取消设置窗口总是在其他窗口的顶部显示时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-always-on-top-changed)
|
||||
`app-command` | 请求一个应用程序命令时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-app-command-windows__linux)
|
||||
`scroll-touch-begin` _(mac)_ | 滚轮事件阶段开始时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-begin-macos)
|
||||
`scroll-touch-end` _(mac)_ | 滚轮事件阶段结束时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-end-macos)
|
||||
`scroll-touch-edge` _(mac)_ | 滚轮事件阶段到达元素边缘时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-scroll-touch-edge-macos)
|
||||
`swipe` | 三指滑动时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-swipe-macos)
|
||||
`rotate-gesture` _(mac)_ | 在触控板旋转手势上触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-rotate-gesture-macos)
|
||||
`sheet-begin` _(mac)_ | 窗口打开sheet(工作表) 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-sheet-begin-macos)
|
||||
`sheet-end` _(mac)_ | 窗口关闭sheet(工作表) 时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-sheet-end-macos)
|
||||
`new-window-for-tab` _(mac)_ | 当点击了系统的新标签按钮时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-new-window-for-tab-macos)
|
||||
`system-context-menu` _(win)_ | 当系统上下文菜单在窗口上触发时触发 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#事件-system-context-menu-windows)
|
||||
|
||||
### 实例方法
|
||||
<!--rehype:wrap-class=col-span-3 row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`win.destroy()` | 强制关闭窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#windestroy)
|
||||
`win.close()` | 尝试关闭窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclose)
|
||||
`win.focus()` | 聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocus)
|
||||
`win.blur()` | 取消窗口的聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winblur)
|
||||
`win.isFocused()` | 判断窗口是否聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfocused)
|
||||
`win.isDestroyed()` | 判断窗口是否被销毁 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisdestroyed)
|
||||
`win.show()` | 显示并聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshow)
|
||||
`win.showInactive()` | 显示但不聚焦于窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshowinactive)
|
||||
`win.hide()` | 隐藏窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhide)
|
||||
`win.isVisible()` | 判断窗口是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisvisible)
|
||||
`win.isModal()` | 判断是否为模态窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismodal)
|
||||
`win.maximize()` | 最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmaximize)
|
||||
`win.unmaximize()` | 取消窗口最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunmaximize)
|
||||
`win.isMaximized()` | 判断窗口是否最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismaximized)
|
||||
`win.minimize()` | 最小化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winminimize)
|
||||
`win.restore()` | 窗口最小化状态恢复到以前的状态 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winrestore)
|
||||
`win.isMinimized()` | 判断窗口是否最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisminimized)
|
||||
`win.setFullScreen(flag)` | 设置窗口是否应处于全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfullscreenflag)
|
||||
`win.isFullScreen()` | 窗口当前是否已全屏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfullscreen)
|
||||
`win.setSimpleFullScreen(flag)` _(mac)_ | 进入或离开简单的全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsimplefullscreenflag-macos)
|
||||
`win.isSimpleFullScreen()` | 窗口是否为简单全屏模式(pre-Lion) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winissimplefullscreen-macos)
|
||||
`win.isNormal()` | 窗口是否处于正常状态(未最大化,未最小化,不在全屏模式下) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisnormal)
|
||||
`win.setAspectRatio(aspectRatio[, extraSize])` | 为内容视图保持的宽高比 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetaspectratioaspectratio-extrasize)
|
||||
`win.setBackgroundColor(backgroundColor)` | 颜色,格式为 Hex,RGB,RGBA,HSL,HSLA 或 CSS 命名颜色 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetbackgroundcolorbackgroundcolor)
|
||||
`win.previewFile(path[, displayName])` _(mac)_ | 要用 QuickLook 预览的文件的绝对路径 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winpreviewfilepath-displayname-macos)
|
||||
`win.closeFilePreview()` _(mac)_ | 关闭当前打开的 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclosefilepreview-macos)
|
||||
`win.setBounds(bounds[, animate])` | 重置窗口,并且移动窗口到指定的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetboundsbounds-animate)
|
||||
`win.getBounds()` | 表示窗口的 `bounds` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbounds)
|
||||
`win.getBackgroundColor()` | 格式获取窗口的背景色,格式为 Hex (`#RRGGBB`) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbackgroundcolor)
|
||||
`win.setContentBounds(bounds[, animate])` | 调整窗口的工作区 (如网页) 的大小并将其移动到所提供的边界。 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentboundsbounds-animate)
|
||||
`win.getContentBounds()` | 窗口客户端区域的 `bounds` `对象` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetcontentbounds)
|
||||
`win.getNormalBounds()` | 包含正常状态下的窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetnormalbounds)
|
||||
`win.setEnabled(enable)` | 禁用或者启用窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetenabledenable)
|
||||
`win.isEnabled()` | 窗口是否启用 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisenabled)
|
||||
`win.setSize(width, height[, animate])` | 调整窗口的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsizewidth-height-animate)
|
||||
`win.getSize()` | 包含窗口的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetsize)
|
||||
`win.setContentSize(width, height[, animate])` | 将窗口的工作区 (如网页) 的大小调整为 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentsizewidth-height-animate)
|
||||
`win.getContentSize()` | 包含窗口的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetcontentsize)
|
||||
`win.setMinimumSize(width, height)` | 设置窗口最小化的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetminimumsizewidth-height)
|
||||
`win.getMinimumSize()` | 包含窗口最小化的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetminimumsize)
|
||||
`win.setMaximumSize(width, height)` | 设置窗口最大化的 `width` 和 `height` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmaximumsizewidth-height)
|
||||
`win.getMaximumSize()` | 包含窗口最大化的宽度和高度 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetmaximumsize)
|
||||
`win.setResizable(resizable)` | 设置用户是否可以手动调整窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetresizableresizable)
|
||||
`win.isResizable()` | 用户是否可以手动调整窗口大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisresizable)
|
||||
`win.setMovable(movable)` _(mac/win)_ | 设置用户是否可以移动窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmovablemovable-macos-windows)
|
||||
`win.isMovable()` _(mac/win)_ | 窗口是否可以被用户拖动,在 Linux 上总是返回 `true` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismovable-macos-windows)
|
||||
`win.setMinimizable(minimizable)` _(mac/win)_ | 设置用户是否可以手动将窗口最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetminimizableminimizable-macos-windows)
|
||||
`win.isMinimizable()` _(mac/win)_ | 用户是否可以手动最小化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisminimizable-macos-windows)
|
||||
`win.setMaximizable(maximizable)` _(mac/win)_ | 设置用户是否可以手动最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmaximizablemaximizable-macos-windows)
|
||||
`win.isMaximizable()` _(mac/win)_ | 窗口是否可以最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismaximizable-macos-windows)
|
||||
`win.setFullScreenable(fullscreenable)` | 设置最大化/缩放窗口按钮是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfullscreenablefullscreenable)
|
||||
`win.isFullScreenable()` | 最大化/缩放窗口按钮是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfullscreenable)
|
||||
`win.setClosable(closable)` _(mac/win)_ | 设置用户是否可以手动关闭窗口。 在Linux上不起作用 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetclosableclosable-macos-windows)
|
||||
`win.isClosable()` _(mac/win)_ | 窗口是否被用户关闭了 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisclosable-macos-windows)
|
||||
`win.setAlwaysOnTop(flag[, level][, relativeLevel])` | 设置窗口是否应始终显示在其他窗口的前面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetalwaysontopflag-level-relativelevel)
|
||||
`win.isAlwaysOnTop()` | 当前窗口是否始终在其它窗口之前 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisalwaysontop)
|
||||
`win.moveAbove(mediaSourceId)` | 将窗口按z轴顺序移动到源窗口前面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmoveabovemediasourceid)
|
||||
`win.moveTop()` | 无论焦点如何, 将窗口移至顶端(z轴上的顺序) [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovetop)
|
||||
`win.center()` | 将窗口移动到屏幕中央 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wincenter)
|
||||
`win.setPosition(x, y[, animate])` | 将窗口移动到 `x` 和 `y` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetpositionx-y-animate)
|
||||
`win.getPosition()` | 返回一个包含当前窗口位置的数组 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetposition)
|
||||
`win.setTitle(title)` | 将原生窗口的标题更改为 `title` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettitletitle)
|
||||
`win.getTitle()` | 网页的标题可以与原生窗口的标题不同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingettitle)
|
||||
`win.setSheetOffset(offsetY[, offsetX])` _(mac/win)_ | 改变macOS上sheet组件的附着点,默认情况下,sheet贴在窗口边框正下方 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetsheetoffsetoffsety-offsetx-macos)
|
||||
`win.flashFrame(flag)` | 启动或停止闪烁窗口, 以吸引用户的注意 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winflashframeflag)
|
||||
`win.setSkipTaskbar(skip)` _(mac/win)_ | 使窗口不显示在任务栏中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetskiptaskbarskip-macos-windows)
|
||||
`win.setKiosk(flag)` | 进入或离开 kiosk 模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetkioskflag)
|
||||
`win.isKiosk()` | 判断窗口是否处于kiosk模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winiskiosk)
|
||||
`win.isTabletMode()` _(win)_ | 此 API 返回 窗口是否在平板电脑模式下,并且 调整大小 事件可以用于监听对平板模式的更改 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winistabletmode-windows)
|
||||
`win.getMediaSourceId()` | DesktopCapturerSource 的 `id` 格式的窗口 `id` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetmediasourceid)
|
||||
`win.getNativeWindowHandle()` | 窗口的平台特定句柄 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetnativewindowhandle)
|
||||
`win.hookWindowMessage(message, callback)` _(win)_ | 钩住窗口消息。 当消息到达 WndProc 时调用 callback [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhookwindowmessagemessage-callback-windows)
|
||||
`win.isWindowMessageHooked(message)` _(win)_ | 返回 boolean - true 或false,具体取决于是否钩挂了消息 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winiswindowmessagehookedmessage-windows)
|
||||
`win.unhookWindowMessage(message)` _(win)_ | 取消窗口信息的钩子 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunhookwindowmessagemessage-windows)
|
||||
`win.unhookAllWindowMessages()` _(win)_ | 取消所有窗口信息的钩子 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winunhookallwindowmessages-windows)
|
||||
`win.setRepresentedFilename(filename)` _(mac)_ | 设置窗口所代表的文件的路径名,并且将这个文件的图标放在窗口标题栏上 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetrepresentedfilenamefilename-macos)
|
||||
`win.getRepresentedFilename()` _(mac)_ | 获取窗口当前文件路径 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetrepresentedfilename-macos)
|
||||
`win.setDocumentEdited(edited)` _(mac)_ | 明确指出窗口文档是否可以编辑,如果设置为true则将标题栏的图标变成灰色 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetdocumenteditededited-macos)
|
||||
`win.isDocumentEdited()` _(mac)_ | 判断当前窗口文档是否可编辑 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisdocumentedited-macos)
|
||||
`win.focusOnWebView()` | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocusonwebview)
|
||||
`win.blurWebView()` | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winblurwebview)
|
||||
`win.capturePage([rect])` | 在 rect 内捕获页面的快照 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wincapturepagerect)
|
||||
`win.loadURL(url[, options])` | 加载页面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winloadurlurl-options)
|
||||
`win.loadFile(filePath[, options])` | 加载页面 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winloadfilefilepath-options)
|
||||
`win.reload()` | 与 `webContents.reload` 相同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winreload)
|
||||
`win.setMenu(menu)` _(win/linux)_ | 将 `menu` 设置为窗口的菜单栏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmenumenu-linux-windows)
|
||||
`win.removeMenu()` _(win)_ | 删除窗口的菜单栏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winremovemenu-linux-windows)
|
||||
`win.setProgressBar(progress[, options])` | 设置进度条的进度值 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetprogressbarprogress-options)
|
||||
`win.setOverlayIcon(overlay, description)` _(win)_ | 设置进度条的进度值。 有效范围为 `[0, 1.0]` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetoverlayiconoverlay-description-windows)
|
||||
`win.setHasShadow(hasShadow)` | 设置窗口是否有阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsethasshadowhasshadow)
|
||||
`win.hasShadow()` | 判断窗口是否有阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winhasshadow)
|
||||
`win.setOpacity(opacity)` _(win/mac)_ | 设置窗口的不透明度。 在Linux上不起作用。 超出界限的数值被限制在 `[0, 1]` 范围内 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetopacityopacity-windows-macos)
|
||||
`win.getOpacity()` | 介于 `0.0` (完全透明) 和 `1.0` (完全不透明) 之间。在Linux上,始终返回 `1` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetopacity)
|
||||
`win.setShape(rects)` _(win/linux)_ | 对窗口形状的设置决定了窗口内系统允许绘制与用户交互的区域 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetshaperects-windows-linux-实验性)
|
||||
`win.setThumbarButtons(buttons)` _(win)_ | 将指定的一组按钮添加到菜单栏的缩图工具栏上 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbarbuttonsbuttons-windows)
|
||||
`win.setThumbnailClip(region)` _(win)_ | 将窗口的区域设置为在任务栏中悬停在窗口上方时显示的缩略图图像 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbnailclipregion-windows)
|
||||
`win.setThumbnailToolTip(toolTip)` _(win)_ | 设置在任务栏中悬停在窗口缩略图上时显示的工具提示 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetthumbnailtooltiptooltip-windows)
|
||||
`win.setAppDetails(options)` _(win)_ | 设置窗口任务栏按钮的属性 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetappdetailsoptions-windows)
|
||||
`win.showDefinitionForSelection()` _(mac)_ | 和 `webContents.showDefinitionForSelection()` 相同 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshowdefinitionforselection-macos)
|
||||
`win.setIcon(icon)` _(win/linux)_ | 设置窗口图标 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winseticonicon-windows-linux)
|
||||
`win.setWindowButtonVisibility(visible)` _(mac)_ | 设置是否窗口交通灯需要显示 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetwindowbuttonvisibilityvisible-macos)
|
||||
`win.setAutoHideMenuBar(hide)` _(win/linux)_ | 设置窗口菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetautohidemenubarhide-windows-linux)
|
||||
`win.isMenuBarAutoHide()` _(win/linux)_ | 判断窗口的菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismenubarautohide-windows-linux)
|
||||
`win.setMenuBarVisibility(visible)` _(win/linux)_ | 设置菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetmenubarvisibilityvisible-windows-linux)
|
||||
`win.isMenuBarVisible()` _(win/linux)_ | 判断窗口的菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winismenubarvisible-windows-linux)
|
||||
`win.setVisibleOnAllWorkspaces(visible[, options])` _(mac/linux)_ | 设置窗口是否在所有工作空间上可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetvisibleonallworkspacesvisible-options-macos-linux)
|
||||
`win.isVisibleOnAllWorkspaces()` _(mac/linux)_ | 判断窗口是否在所有工作空间上可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisvisibleonallworkspaces-macos-linux)
|
||||
`win.setIgnoreMouseEvents(ignore[, options])` | 忽略窗口内的所有鼠标事件 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetignoremouseeventsignore-options)
|
||||
`win.setContentProtection(enable)` _(mac/linux)_ | 防止窗口内容被其他应用捕获 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetcontentprotectionenable-macos-windows)
|
||||
`win.setFocusable(focusable)` _(mac/linux)_ | 设置窗口是否可聚焦 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetfocusablefocusable-macos-windows)
|
||||
`win.isFocusable()` _(mac/linux)_ | 返回当前窗口是否可以作为焦点被选中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winisfocusable-macos-windows)
|
||||
`win.setParentWindow(parent)` | 设置 `parent` 为当前窗口的父窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetparentwindowparent)
|
||||
`win.getParentWindow()` | 返回 BrowserWindow/null - 如果没有父窗口则为 `null` [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetparentwindow)
|
||||
`win.getChildWindows()` | 返回 `BrowserWindow[]` - 首页的子窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetchildwindows)
|
||||
`win.setAutoHideCursor(autoHide)` _(mac)_ | 设置输入时是否隐藏光标 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetautohidecursorautohide-macos)
|
||||
`win.selectPreviousTab()` _(mac)_ | 当启用本地选项卡,并且窗口中有另一个标签时,选择上一个选项卡 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winselectprevioustab-macos)
|
||||
`win.selectNextTab()` _(mac)_ | 当启用本地选项卡,并且窗口中有另一个标签时,选择下一个选项卡 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winselectnexttab-macos)
|
||||
`win.mergeAllWindows()` _(mac)_ | 当启用本地选项卡并且存在多个打开窗口时,将所有窗口合并到一个带有多个选项卡的窗口中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmergeallwindows-macos)
|
||||
`win.moveTabToNewWindow()` _(mac)_ | 如果启用了本机选项卡并且当前窗口中有多个选项卡,则将当前选项卡移动到新窗口中 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovetabtonewwindow-macos)
|
||||
`win.toggleTabBar()` _(mac)_ | 如果启用了本机选项卡并且当前窗口中只有一个选项卡,则切换选项卡栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wintoggletabbar-macos)
|
||||
`win.addTabbedWindow(browserWindow)` _(mac)_ | 在该窗口中添加一个窗口作为选项卡,位于窗口实例的选项卡之后 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaddtabbedwindowbrowserwindow-macos)
|
||||
`win.setVibrancy(type)` _(mac)_ | 在浏览器窗口中添加一个动态特效。 传递 null 或空字符串将会移除窗口上的动态效果 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetvibrancytype-macos)
|
||||
`win.setTrafficLightPosition(position)` _(mac)_ | 在无框窗口中设置自定义控制按钮的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettrafficlightpositionposition-macos)
|
||||
`win.getTrafficLightPosition()` _(mac)_ | 在无框窗口中自定义控制按钮的位置 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingettrafficlightposition-macos)
|
||||
`win.setTouchBar(touchBar)` _(mac)_ | 设置窗口的触摸条布局 设置为 null 或undefined将清除触摸条 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettouchbartouchbar-macos)
|
||||
`win.setBrowserView(browserView)` _(实验)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsetbrowserviewbrowserview-实验)
|
||||
`win.getBrowserView()` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbrowserview-实验功能)
|
||||
`win.addBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaddbrowserviewbrowserview-实验功能)
|
||||
`win.removeBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winremovebrowserviewbrowserview-实验功能)
|
||||
`win.setTopBrowserView(browserView)` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettopbrowserviewbrowserview-实验功能)
|
||||
`win.getBrowserViews()` _(实验功能)_ | [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wingetbrowserviews-实验功能)
|
||||
`win.setTitleBarOverlay(options)` _(win)_ | 在已开启 Window Controls Overlay 的窗口上,此方法将更新标题栏叠加层的样式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettitlebaroverlayoptions-windows)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
|
||||
### 静态方法
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`BrowserWindow.getAllWindows()` | 所有打开的窗口的数组 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowgetallwindows)
|
||||
`BrowserWindow.getFocusedWindow()` | 当前获得焦点的窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowgetfocusedwindow)
|
||||
`BrowserWindow.fromWebContents(webContents)` | 拥有给定 webContents 窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfromwebcontentswebcontents)
|
||||
`BrowserWindow.fromBrowserView(browserView)` | 拥有给定 browserView 窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfrombrowserviewbrowserview)
|
||||
`BrowserWindow.fromId(id)` | 带有给定 id 的窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#browserwindowfromidid)
|
||||
|
||||
### 实例属性
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
// 本例中 `win` 是我们的实例
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`win.webContents` | 此窗口拥有的 WebContents 对象 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winwebcontents-只读)
|
||||
`win.id` | 代表了窗口的唯一ID [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winid-只读)
|
||||
`win.autoHideMenuBar` | 决定窗口菜单栏是否自动隐藏 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winautohidemenubar)
|
||||
`win.simpleFullScreen` | 决定窗口是否处于简单(pre-Lion) 全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsimplefullscreen)
|
||||
`win.fullScreen` | 决定窗口是否处于全屏模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfullscreen)
|
||||
`win.focusable` | 确定窗口是否可作为焦点被选中的属性 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfocusable-windows-macos)
|
||||
`win.visibleOnAllWorkspaces` | 决定窗口是否在所有工作区中可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winvisibleonallworkspaces-macos-linux)
|
||||
`win.shadow` | 决定窗口是否显示阴影 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winshadow)
|
||||
`win.menuBarVisible` | 决定菜单栏是否可见 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmenubarvisible-windows-linux)
|
||||
`win.kiosk` | 决定窗口是否处于kiosk模式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winkiosk)
|
||||
`win.documentEdited` | 指明窗口文档是否已被编辑 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#windocumentedited-macos)
|
||||
`win.representedFilename` | 确定窗口代表的文件的路径名 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winrepresentedfilename-macos)
|
||||
`win.title` | 用于确定原生窗口的标题 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#wintitle)
|
||||
`win.minimizable` | 决定窗口是否可被用户手动最小化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winminimizable-macos-windows)
|
||||
`win.maximizable` | 决定窗口是否可被用户手动最大化 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmaximizable-macos-windows)
|
||||
`win.fullScreenable` | 决定是切换全屏模式还是最大化窗口 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winfullscreenable)
|
||||
`win.resizable` | 决定窗口是否可被用户手动调整大小 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winresizable)
|
||||
`win.closable` | 决定窗口是否可被用户手动关闭 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winclosable-macos-windows)
|
||||
`win.movable` | 决定窗口是否可被用户移动 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winmovable-macos-windows)
|
||||
`win.excludedFromShownWindowsMenu` | 决定窗口是否从 Windows 菜单排除 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winexcludedfromshownwindowsmenu-macos)
|
||||
`win.accessibleTitle` | 定义一个仅为辅助工具提供的替代标题 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winaccessibletitle)
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Electron 备忘清单](https://simulatedgreg.github.io/electron-cheatsheet/) _(simulatedgreg.github.io)_
|
2404
docs/emmet.md
Normal file
@ -1,7 +1,7 @@
|
||||
Find 备忘清单
|
||||
===
|
||||
|
||||
这是 Linux find 命令备忘单的快速参考列表,包含常用选项和示例。
|
||||
这是 Linux find 命令备忘清单的快速参考列表,包含常用选项和示例。
|
||||
|
||||
入门
|
||||
----
|
||||
|
34
docs/git.md
@ -328,25 +328,21 @@ Git 技巧
|
||||
|
||||
### 重命名分支
|
||||
|
||||
#### **重命名**为`new`
|
||||
|
||||
```shell
|
||||
$ git branch -m <new>
|
||||
$ git branch -m <old> <new> # 重命名分支
|
||||
```
|
||||
|
||||
#### **推送**并重置
|
||||
|
||||
```shell
|
||||
$ git push origin -u <new>
|
||||
```
|
||||
|
||||
#### **删除**远程分支
|
||||
|
||||
```shell
|
||||
$ git push origin --delete <old> # 方法1
|
||||
$ git push origin :oldBranchName # 方法2
|
||||
```
|
||||
- **重命名**为`new`
|
||||
```shell
|
||||
$ git branch -m <new>
|
||||
$ git branch -m <old> <new> #重命名分支
|
||||
```
|
||||
- **推送**并重置
|
||||
```shell
|
||||
$ git push origin -u <new>
|
||||
```
|
||||
- **删除**远程分支
|
||||
```shell
|
||||
$ git push origin --delete <old> #方法1
|
||||
$ git push origin :oldBranchName #方法2
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### Log
|
||||
|
||||
|
966
docs/golang.md
Normal file
@ -0,0 +1,966 @@
|
||||
Golang 备忘清单
|
||||
===
|
||||
|
||||
该备忘单提供了帮助您使用 [Golang](https://golang.org) 的基本语法和方法。
|
||||
|
||||
入门
|
||||
--------
|
||||
|
||||
### hello.go
|
||||
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
fmt.Println("Hello, world!")
|
||||
}
|
||||
```
|
||||
|
||||
直接运行
|
||||
|
||||
```shell
|
||||
$ go run hello.go
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
或者在 [Go repl](https://repl.it/languages/go) 中尝试一下
|
||||
|
||||
### 变量
|
||||
|
||||
```go
|
||||
var s1 string
|
||||
s1 = "Learn Go!"
|
||||
// 一次声明多个变量
|
||||
var b, c int = 1, 2
|
||||
var d = true
|
||||
```
|
||||
|
||||
简短声明
|
||||
|
||||
```go
|
||||
s1 := "Learn Go!" // string
|
||||
b, c := 1, 2 // int
|
||||
d := true // bool
|
||||
```
|
||||
|
||||
参见:[基本类型](#golang-基本类型)
|
||||
|
||||
### 函数
|
||||
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
// 程序的入口点
|
||||
func main() {
|
||||
fmt.Println("Hello world!")
|
||||
say("Hello Go!")
|
||||
}
|
||||
func say(message string) {
|
||||
fmt.Println("You said: ", message)
|
||||
}
|
||||
```
|
||||
|
||||
参见:[函数(Functions)](#golang-函数)
|
||||
|
||||
### 注释
|
||||
|
||||
```go
|
||||
// 单行注释
|
||||
/* 这是
|
||||
多行注释 */
|
||||
```
|
||||
|
||||
### 如果语句
|
||||
|
||||
```go
|
||||
if true {
|
||||
fmt.Println("Yes!")
|
||||
}
|
||||
```
|
||||
|
||||
参见:[条件控制](#golang-条件控制)
|
||||
|
||||
Golang 基本类型
|
||||
--------
|
||||
|
||||
### 字符串 Strings
|
||||
|
||||
```go
|
||||
s1 := "Hello" + "World"
|
||||
s2 := `A "raw" string literal
|
||||
can include line breaks.`
|
||||
// 输出:11
|
||||
fmt.Println(len(s1))
|
||||
// 输出:Hello
|
||||
fmt.Println(string(s1[0:5]))
|
||||
```
|
||||
|
||||
字符串的类型为 `字符串`
|
||||
|
||||
### 数字 Numbers
|
||||
|
||||
```go
|
||||
num := 3 // int
|
||||
num := 3. // float64
|
||||
num := 3 + 4i // complex128
|
||||
num := byte('a') // byte (alias: uint8)
|
||||
var u uint = 7 // uint (unsigned)
|
||||
var p float32 = 22.7 // 32-bit float
|
||||
```
|
||||
|
||||
#### 操作符 Operators
|
||||
|
||||
```go
|
||||
x := 5
|
||||
x++
|
||||
fmt.Println("x + 4 =", x + 4)
|
||||
fmt.Println("x * 4 =", x * 4)
|
||||
```
|
||||
|
||||
参见:[更多操作符](#运算符和标点符号)
|
||||
|
||||
### 布尔值 Booleans
|
||||
|
||||
```go
|
||||
isTrue := true
|
||||
isFalse := false
|
||||
```
|
||||
|
||||
#### 操作符
|
||||
|
||||
```go
|
||||
fmt.Println(true && true) // true
|
||||
fmt.Println(true && false) // false
|
||||
fmt.Println(true || true) // true
|
||||
fmt.Println(true || false) // true
|
||||
fmt.Println(!true) // false
|
||||
```
|
||||
|
||||
参见:[更多操作符](#运算符和标点符号)
|
||||
|
||||
### 数组 Arrays
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
┌────┬────┬────┬────┬─────┬─────┐
|
||||
| 2 | 3 | 5 | 7 | 11 | 13 |
|
||||
└────┴────┴────┴────┴─────┴─────┘
|
||||
0 1 2 3 4 5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
primes := [...]int{2, 3, 5, 7, 11, 13}
|
||||
fmt.Println(len(primes)) // => 6
|
||||
// 输出:[2 3 5 7 11 13]
|
||||
fmt.Println(primes)
|
||||
// 与 [:3] 相同,输出:[2 3 5]
|
||||
fmt.Println(primes[0:3])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
var a [2]string
|
||||
a[0] = "Hello"
|
||||
a[1] = "World"
|
||||
fmt.Println(a[0], a[1]) //=> Hello World
|
||||
fmt.Println(a) // => [Hello World]
|
||||
```
|
||||
|
||||
#### 2d array
|
||||
|
||||
```go
|
||||
var twoDimension [2][3]int
|
||||
for i := 0; i < 2; i++ {
|
||||
for j := 0; j < 3; j++ {
|
||||
twoDimension[i][j] = i + j
|
||||
}
|
||||
}
|
||||
// => 2d: [[0 1 2] [1 2 3]]
|
||||
fmt.Println("2d: ", twoDimension)
|
||||
```
|
||||
|
||||
### 指针(Pointers)
|
||||
|
||||
```go
|
||||
func main () {
|
||||
b := *getPointer()
|
||||
fmt.Println("Value is", b)
|
||||
}
|
||||
|
||||
func getPointer () (myPointer *int) {
|
||||
a := 234
|
||||
return &a
|
||||
}
|
||||
|
||||
a := new(int)
|
||||
*a = 234
|
||||
```
|
||||
|
||||
参见:[指针(Pointers)](https://tour.golang.org/moretypes/1)
|
||||
|
||||
### 切片(Slices)
|
||||
|
||||
```go
|
||||
s := make([]string, 3)
|
||||
s[0] = "a"
|
||||
s[1] = "b"
|
||||
s = append(s, "d")
|
||||
s = append(s, "e", "f")
|
||||
fmt.Println(s)
|
||||
fmt.Println(s[1])
|
||||
fmt.Println(len(s))
|
||||
fmt.Println(s[1:3])
|
||||
slice := []int{2, 3, 4}
|
||||
```
|
||||
|
||||
另见:[切片示例](https://gobyexample.com/slices)
|
||||
|
||||
### 常量(Constants)
|
||||
|
||||
```go
|
||||
const s string = "constant"
|
||||
const Phi = 1.618
|
||||
const n = 500000000
|
||||
const d = 3e20 / n
|
||||
fmt.Println(d)
|
||||
```
|
||||
|
||||
### 类型转换
|
||||
|
||||
```go
|
||||
i := 90
|
||||
f := float64(i)
|
||||
u := uint(i)
|
||||
// 将等于字符Z
|
||||
s := string(i)
|
||||
```
|
||||
|
||||
#### 如何获取int字符串?
|
||||
|
||||
```go
|
||||
i := 90
|
||||
// 需要导入“strconv”
|
||||
s := strconv.Itoa(i)
|
||||
fmt.Println(s) // Outputs: 90
|
||||
```
|
||||
|
||||
|
||||
Golang 字符串
|
||||
--------
|
||||
|
||||
### 字符串函数
|
||||
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
s "strings"
|
||||
)
|
||||
func main() {
|
||||
/* 需要将字符串导入为 s */
|
||||
fmt.Println(s.Contains("test", "e"))
|
||||
/* 内置 */
|
||||
fmt.Println(len("hello")) // => 5
|
||||
// 输出: 101
|
||||
fmt.Println("hello"[1])
|
||||
// 输出: e
|
||||
fmt.Println(string("hello"[1]))
|
||||
}
|
||||
```
|
||||
|
||||
### fmt.Printf
|
||||
<!--rehype:wrap-class=row-span-2 col-span-2-->
|
||||
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
type point struct {
|
||||
x, y int
|
||||
}
|
||||
func main() {
|
||||
p := point{1, 2}
|
||||
fmt.Printf("%v\n", p) // => {1 2}
|
||||
fmt.Printf("%+v\n", p) // => {x:1 y:2}
|
||||
fmt.Printf("%#v\n", p) // => main.point{x:1, y:2}
|
||||
fmt.Printf("%T\n", p) // => main.point
|
||||
fmt.Printf("%t\n", true) // => TRUE
|
||||
fmt.Printf("%d\n", 123) // => 123
|
||||
fmt.Printf("%b\n", 14) // => 1110
|
||||
fmt.Printf("%c\n", 33) // => !
|
||||
fmt.Printf("%x\n", 456) // => 1c8
|
||||
fmt.Printf("%f\n", 78.9) // => 78.9
|
||||
fmt.Printf("%e\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%E\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%s\n", "\"string\"") // => "string"
|
||||
fmt.Printf("%q\n", "\"string\"") // => "\"string\""
|
||||
fmt.Printf("%x\n", "hex this") // => 6.86578E+15
|
||||
fmt.Printf("%p\n", &p) // => 0xc00002c040
|
||||
fmt.Printf("|%6d|%6d|\n", 12, 345) // => | 12| 345|
|
||||
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // => | 1.20| 3.45|
|
||||
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // => |1.20 |3.45 |
|
||||
fmt.Printf("|%6s|%6s|\n", "foo", "b") // => | foo| b|
|
||||
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // => |foo |b |
|
||||
s := fmt.Sprintf("a %s", "string")
|
||||
fmt.Println(s)
|
||||
fmt.Fprintf(os.Stderr, "an %s\n", "error")
|
||||
}
|
||||
```
|
||||
|
||||
另见:[fmt](https://golang.org/pkg/fmt/)
|
||||
|
||||
### 函数实例
|
||||
|
||||
| 实例 | Result |
|
||||
|-------------------------------|-------------|
|
||||
| Contains("test", "es") | true |
|
||||
| Count("test", "t") | 2 |
|
||||
| HasPrefix("test", "te") | true |
|
||||
| HasSuffix("test", "st") | true |
|
||||
| Index("test", "e") | 1 |
|
||||
| Join([]string{"a", "b"}, "-") | a-b |
|
||||
| Repeat("a", 5) | aaaaa |
|
||||
| Replace("foo", "o", "0", -1) | f00 |
|
||||
| Replace("foo", "o", "0", 1) | f0o |
|
||||
| Split("a-b-c-d-e", "-") | [a b c d e] |
|
||||
| ToLower("TEST") | test |
|
||||
| ToUpper("test") | TEST |
|
||||
|
||||
Golang 条件控制
|
||||
--------
|
||||
|
||||
### 有条件的
|
||||
|
||||
```go
|
||||
a := 10
|
||||
if a > 20 {
|
||||
fmt.Println(">")
|
||||
} else if a < 20 {
|
||||
fmt.Println("<")
|
||||
} else {
|
||||
fmt.Println("=")
|
||||
}
|
||||
```
|
||||
|
||||
### if 中的语句
|
||||
|
||||
```go
|
||||
x := "hello go!"
|
||||
if count := len(x); count > 0 {
|
||||
fmt.Println("Yes")
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
if _, err := doThing(); err != nil {
|
||||
fmt.Println("Uh oh")
|
||||
}
|
||||
```
|
||||
|
||||
### Switch
|
||||
|
||||
```go
|
||||
x := 42.0
|
||||
switch x {
|
||||
case 0:
|
||||
case 1, 2:
|
||||
fmt.Println("Multiple matches")
|
||||
case 42: // Don't "fall through".
|
||||
fmt.Println("reached")
|
||||
case 43:
|
||||
fmt.Println("Unreached")
|
||||
default:
|
||||
fmt.Println("Optional")
|
||||
}
|
||||
```
|
||||
|
||||
参见:[Switch](https://github.com/golang/go/wiki/Switch)
|
||||
|
||||
### For loop
|
||||
|
||||
```go
|
||||
for i := 0; i <= 10; i++ {
|
||||
fmt.Println("i: ", i)
|
||||
}
|
||||
```
|
||||
|
||||
### 对于 Range 循环
|
||||
|
||||
```go
|
||||
nums := []int{2, 3, 4}
|
||||
sum := 0
|
||||
for _, num := range nums {
|
||||
sum += num
|
||||
}
|
||||
fmt.Println("sum:", sum)
|
||||
```
|
||||
|
||||
### While 循环
|
||||
|
||||
```go
|
||||
i := 1
|
||||
for i <= 3 {
|
||||
fmt.Println(i)
|
||||
i++
|
||||
}
|
||||
```
|
||||
|
||||
### Continue 关键字
|
||||
|
||||
```go
|
||||
for i := 0; i <= 5; i++ {
|
||||
if i % 2 == 0 {
|
||||
continue
|
||||
}
|
||||
fmt.Println(i)
|
||||
}
|
||||
```
|
||||
|
||||
### Break 关键字
|
||||
|
||||
```go
|
||||
for {
|
||||
fmt.Println("loop")
|
||||
break
|
||||
}
|
||||
```
|
||||
|
||||
Golang 结构和映射
|
||||
--------
|
||||
|
||||
### 定义
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
type Vertex struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
func main() {
|
||||
v := Vertex{1, 2}
|
||||
v.X = 4
|
||||
fmt.Println(v.X, v.Y) // => 4 2
|
||||
}
|
||||
```
|
||||
|
||||
参见:[结构(Structs)](https://tour.golang.org/moretypes/2)
|
||||
|
||||
### 字面量
|
||||
|
||||
```go
|
||||
v := Vertex{X: 1, Y: 2}
|
||||
// Field names can be omitted
|
||||
v := Vertex{1, 2}
|
||||
// Y is implicit
|
||||
v := Vertex{X: 1}
|
||||
```
|
||||
|
||||
您还可以输入字段名
|
||||
|
||||
### 映射
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
m := make(map[string]int)
|
||||
m["k1"] = 7
|
||||
m["k2"] = 13
|
||||
fmt.Println(m) // => map[k1:7 k2:13]
|
||||
v1 := m["k1"]
|
||||
fmt.Println(v1) // => 7
|
||||
fmt.Println(len(m)) // => 2
|
||||
delete(m, "k2")
|
||||
fmt.Println(m) // => map[k1:7]
|
||||
_, prs := m["k2"]
|
||||
fmt.Println(prs) // => false
|
||||
n := map[string]int{"foo": 1, "bar": 2}
|
||||
fmt.Println(n) // => map[bar:2 foo:1]
|
||||
```
|
||||
|
||||
### 指向结构的指针
|
||||
|
||||
```go
|
||||
v := &Vertex{1, 2}
|
||||
v.X = 2
|
||||
```
|
||||
|
||||
Doing `v.X` is the same as doing `(*v).X`, when `v` is a pointer.
|
||||
|
||||
Golang 函数
|
||||
--------
|
||||
|
||||
### 多个参数
|
||||
|
||||
```go
|
||||
func plus(a int, b int) int {
|
||||
return a + b
|
||||
}
|
||||
func plusPlus(a, b, c int) int {
|
||||
return a + b + c
|
||||
}
|
||||
fmt.Println(plus(1, 2))
|
||||
fmt.Println(plusPlus(1, 2, 3))
|
||||
```
|
||||
|
||||
### 多次返回
|
||||
|
||||
```go
|
||||
func vals() (int, int) {
|
||||
return 3, 7
|
||||
}
|
||||
a, b := vals()
|
||||
fmt.Println(a) // => 3
|
||||
fmt.Println(b) // => 7
|
||||
```
|
||||
|
||||
### 匿名函数
|
||||
|
||||
```go
|
||||
r1, r2 := func() (string, string) {
|
||||
x := []string{"hello", "world"}
|
||||
return x[0], x[1]
|
||||
}()
|
||||
// => hello world
|
||||
fmt.Println(r1, r2)
|
||||
```
|
||||
|
||||
### 命名返回
|
||||
|
||||
```go
|
||||
func split(sum int) (x, y int) {
|
||||
x = sum * 4 / 9
|
||||
y = sum - x
|
||||
return
|
||||
}
|
||||
x, y := split(17)
|
||||
fmt.Println(x) // => 7
|
||||
fmt.Println(y) // => 10
|
||||
```
|
||||
|
||||
### 变量函数
|
||||
|
||||
```go
|
||||
func sum(nums ...int) {
|
||||
fmt.Print(nums, " ")
|
||||
total := 0
|
||||
for _, num := range nums {
|
||||
total += num
|
||||
}
|
||||
fmt.Println(total)
|
||||
}
|
||||
sum(1, 2) //=> [1 2] 3
|
||||
sum(1, 2, 3) // => [1 2 3] 6
|
||||
nums := []int{1, 2, 3, 4}
|
||||
sum(nums...) // => [1 2 3 4] 10
|
||||
```
|
||||
|
||||
### 初始化函数
|
||||
|
||||
```go
|
||||
import --> const --> var --> init()
|
||||
```
|
||||
---
|
||||
|
||||
```go
|
||||
var num = setNumber()
|
||||
func setNumber() int {
|
||||
return 42
|
||||
}
|
||||
func init() {
|
||||
num = 0
|
||||
}
|
||||
func main() {
|
||||
fmt.Println(num) // => 0
|
||||
}
|
||||
```
|
||||
|
||||
### 作为值的函数
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// 将函数赋给名称
|
||||
add := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
// 使用名称调用函数
|
||||
fmt.Println(add(3, 4)) // => 7
|
||||
}
|
||||
```
|
||||
|
||||
### 关闭 1
|
||||
|
||||
```go
|
||||
func scope() func() int{
|
||||
outer_var := 2
|
||||
foo := func() int {return outer_var}
|
||||
return foo
|
||||
}
|
||||
// Outpus: 2
|
||||
fmt.Println(scope()())
|
||||
```
|
||||
|
||||
### 关闭 2
|
||||
|
||||
```go
|
||||
func outer() (func() int, int) {
|
||||
outer_var := 2
|
||||
inner := func() int {
|
||||
outer_var += 99
|
||||
return outer_var
|
||||
}
|
||||
inner()
|
||||
return inner, outer_var
|
||||
}
|
||||
inner, val := outer()
|
||||
fmt.Println(inner()) // => 200
|
||||
fmt.Println(val) // => 101
|
||||
```
|
||||
|
||||
Golang 包(Packages)
|
||||
--------
|
||||
|
||||
### 导入
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
import "fmt"
|
||||
import "math/rand"
|
||||
```
|
||||
|
||||
#### 等同于
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt" // 给 fmt.Println
|
||||
"math/rand" // 给 rand.Intn
|
||||
)
|
||||
```
|
||||
|
||||
另见:[导入](https://tour.golang.org/basics/1)
|
||||
|
||||
### 别名
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
import r "math/rand"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
r "math/rand"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
r.Intn()
|
||||
```
|
||||
|
||||
### Packages
|
||||
|
||||
```go
|
||||
package main
|
||||
// 一个内部包只能被另一个包导入
|
||||
// 那是在以内部目录的父级为根的树内
|
||||
package internal
|
||||
```
|
||||
|
||||
另见:[内部包](https://go.dev/doc/go1.4#internalpackages)
|
||||
|
||||
### 导出名称
|
||||
|
||||
```go
|
||||
// 以大写字母开头
|
||||
func Hello () {
|
||||
···
|
||||
}
|
||||
```
|
||||
|
||||
另见:[导出的名称](https://tour.golang.org/basics/3)
|
||||
|
||||
Golang 并发
|
||||
--------
|
||||
|
||||
### 协程
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
func f(from string) {
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Println(from, ":", i)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
f("direct")
|
||||
go f("goroutine")
|
||||
go func(msg string) {
|
||||
fmt.Println(msg)
|
||||
}("going")
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("done")
|
||||
}
|
||||
```
|
||||
|
||||
参见:[Goroutines](https://tour.golang.org/concurrency/1), [Channels](https://tour.golang.org/concurrency/2)
|
||||
|
||||
### WaitGroup
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```golang
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
func w(id int, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
fmt.Printf("%d starting\n", id)
|
||||
time.Sleep(time.Second)
|
||||
fmt.Printf("%d done\n", id)
|
||||
}
|
||||
func main() {
|
||||
var wg sync.WaitGroup
|
||||
for i := 1; i <= 5; i++ {
|
||||
wg.Add(1)
|
||||
go w(i, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
```
|
||||
|
||||
参见:[WaitGroup](https://golang.org/pkg/sync/#WaitGroup)
|
||||
|
||||
### Closing channels
|
||||
|
||||
```go
|
||||
ch <- 1
|
||||
ch <- 2
|
||||
ch <- 3
|
||||
close(ch) // 关闭频道
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
// 迭代通道直到关闭
|
||||
for i := range ch {
|
||||
···
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
// Closed if `ok == false`
|
||||
v, ok := <- ch
|
||||
```
|
||||
|
||||
参见:[范围和关闭](https://tour.golang.org/concurrency/4)
|
||||
|
||||
### 缓冲通道
|
||||
|
||||
```go
|
||||
ch := make(chan int, 2)
|
||||
ch <- 1
|
||||
ch <- 2
|
||||
ch <- 3
|
||||
// 致命错误:
|
||||
// 所有 goroutine 都处于休眠状态 - 死锁
|
||||
```
|
||||
|
||||
参见:[缓冲通道](https://tour.golang.org/concurrency/3)
|
||||
|
||||
Golang 错误控制
|
||||
--------
|
||||
|
||||
### 延迟函数
|
||||
|
||||
```go
|
||||
func main() {
|
||||
defer func() {
|
||||
fmt.Println("Done")
|
||||
}()
|
||||
fmt.Println("Working...")
|
||||
}
|
||||
```
|
||||
|
||||
### Lambda defer
|
||||
|
||||
```go
|
||||
func main() {
|
||||
var d = int64(0)
|
||||
defer func(d *int64) {
|
||||
fmt.Printf("& %v Unix Sec\n", *d)
|
||||
}(&d)
|
||||
fmt.Print("Done ")
|
||||
d = time.Now().Unix()
|
||||
}
|
||||
```
|
||||
|
||||
`defer` 函数使用当前值`d`,除非我们使用指针在 `main` 末尾获取最终值
|
||||
|
||||
### Defer
|
||||
|
||||
```go
|
||||
func main() {
|
||||
defer fmt.Println("Done")
|
||||
fmt.Println("Working...")
|
||||
}
|
||||
```
|
||||
|
||||
参见:[Defer, panic and recover](https://blog.golang.org/defer-panic-and-recover)
|
||||
|
||||
Golang 方法(Methods)
|
||||
--------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 接收器
|
||||
|
||||
```go
|
||||
type Vertex struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
func (v Vertex) Abs() float64 {
|
||||
return math.Sqrt(v.X * v.X + v.Y * v.Y)
|
||||
}
|
||||
|
||||
v := Vertex{1, 2}
|
||||
v.Abs()
|
||||
```
|
||||
|
||||
参见:[Methods](https://tour.golang.org/methods/1)
|
||||
|
||||
### Mutation
|
||||
|
||||
```go
|
||||
func (v *Vertex) Scale(f float64) {
|
||||
v.X = v.X * f
|
||||
v.Y = v.Y * f
|
||||
}
|
||||
|
||||
v := Vertex{6, 12}
|
||||
v.Scale(0.5)
|
||||
// `v` 已更新
|
||||
```
|
||||
|
||||
参见:[指针接收器](https://tour.golang.org/methods/4)
|
||||
|
||||
Golang 接口(Interfaces)
|
||||
--------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 基本接口(Interfaces)
|
||||
|
||||
```go
|
||||
type Shape interface {
|
||||
Area() float64
|
||||
Perimeter() float64
|
||||
}
|
||||
```
|
||||
|
||||
### 结构(Struct)
|
||||
|
||||
```go
|
||||
type Rectangle struct {
|
||||
Length, Width float64
|
||||
}
|
||||
```
|
||||
|
||||
结构 `Rectangle` 通过实现其所有方法隐式实现接口 `Shape`
|
||||
|
||||
### 方法(Methods)
|
||||
|
||||
```go
|
||||
func (r Rectangle) Area() float64 {
|
||||
return r.Length * r.Width
|
||||
}
|
||||
func (r Rectangle) Perimeter() float64 {
|
||||
return 2 * (r.Length + r.Width)
|
||||
}
|
||||
```
|
||||
|
||||
在 `Shape` 中定义的方法在`Rectangle`中实现
|
||||
|
||||
### 接口实例
|
||||
|
||||
```go
|
||||
func main() {
|
||||
var r Shape = Rectangle{Length: 3, Width: 4}
|
||||
fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter())
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
杂项
|
||||
-------------
|
||||
|
||||
### 关键字(Keywords)
|
||||
- break
|
||||
- default
|
||||
- func
|
||||
- interface
|
||||
- select
|
||||
- case
|
||||
- defer
|
||||
- go
|
||||
- map
|
||||
- struct
|
||||
- chan
|
||||
- else
|
||||
- goto
|
||||
- package
|
||||
- switch
|
||||
- const
|
||||
- fallthrough
|
||||
- if
|
||||
- range
|
||||
- type
|
||||
- continue
|
||||
- for
|
||||
- import
|
||||
- return
|
||||
- var
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
### 运算符和标点符号
|
||||
|
||||
| | | | | | | | | |
|
||||
|---|----|-----|-----|------|----|-----|---|---|
|
||||
| `+` | & | += | &= | && | == | != | ( | ) |
|
||||
| `-` | \| | -= | \|= | \|\| | < | <= | [ | ] |
|
||||
| `*` | ^ | *= | ^= | <- | > | >= | { | } |
|
||||
| `/` | << | /= | <<= | ++ | = | := | , | ; |
|
||||
| `%` | >> | %= | >>= | -- | ! | ... | . | : |
|
||||
| | &^ | &^= | | | | | | |
|
||||
|
||||
另见
|
||||
--------
|
||||
- [Devhints](https://devhints.io/go) _(devhints.io)_
|
||||
- [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_
|
||||
- [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_
|
||||
- [Effective Go](https://golang.org/doc/effective_go.html) _(golang.org)_
|
||||
- [Go by Example](https://gobyexample.com/) _(gobyexample.com)_
|
||||
- [Awesome Go](https://awesome-go.com/) _(awesome-go.com)_
|
||||
- [JustForFunc Youtube](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw) _(youtube.com)_
|
||||
- [Style Guide](https://github.com/golang/go/wiki/CodeReviewComments) _(github.com)_
|
179
docs/grep.md
Normal file
@ -0,0 +1,179 @@
|
||||
Grep 备忘清单
|
||||
===
|
||||
|
||||
本备忘单旨在快速提醒使用命令行程序 grep 所涉及的主要概念,并假设您已经了解其用法。
|
||||
|
||||
|
||||
入门
|
||||
------
|
||||
<!--rehype:body-class=cols-5-->
|
||||
|
||||
### 使用
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
搜索标准输出(即文本流)
|
||||
|
||||
```shell
|
||||
$ grep [options] search_string
|
||||
```
|
||||
|
||||
在文件中搜索确切的字符串:
|
||||
|
||||
```shell
|
||||
$ grep [options] search_string path/to/file
|
||||
```
|
||||
|
||||
打印 myfile.txt 中包含字符串“mellon”的行
|
||||
|
||||
```shell
|
||||
$ grep 'mellon' myfile.txt
|
||||
```
|
||||
|
||||
文件名中接受通配符。
|
||||
|
||||
|
||||
### 选项示例
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
选项 | 示例 | 说明
|
||||
:-|:-|:-
|
||||
| `-i` | grep -i ^DA demo.txt | 忘记区分大小写
|
||||
| `-w` | grep -w "of" demo.txt | 仅搜索完整的单词
|
||||
| `-A` | grep -A 3 'Exception' error.log | 匹配字符串后显示 3 行
|
||||
| `-B` | grep -B 4 'Exception' error.log | 在匹配字符串前显示 4 行
|
||||
| `-C` | grep -C 5 'Exception' error.log | 在匹配字符串周围显示 5 行
|
||||
| `-r` | grep -r 'github.io' /var/log/nginx/ | 递归搜索 _(在子目录内)_
|
||||
| `-v` | grep -v 'warning' /var/log/syslog | 返回所有与模式不匹配的行
|
||||
| `-e` | grep -e '^al' filename | 使用正则表达式 _(以'al'开头的行)_
|
||||
| `-E` | grep -E 'ja(s\|cks)on' filename | 扩展正则表达式 _(包含 jason 或 jackson 的行)_
|
||||
| `-c` | grep -c 'error' /var/log/syslog | 计算匹配数
|
||||
| `-l` | grep -l 'robot' /var/log/* | 打印匹配文件的名称
|
||||
| `-o` | grep -o search_string filename | 只显示字符串的匹配部分
|
||||
| `-n` | grep -n "go" demo.txt | 显示匹配的行号
|
||||
|
||||
|
||||
Grep 正则表达式
|
||||
-------
|
||||
|
||||
### 参考
|
||||
|
||||
- [Regex syntax](./regex.md) _(jaywcjlove.github.io)_
|
||||
- [Regex examples](./regex.md#正则表达式示例) _(jaywcjlove.github.io)_
|
||||
|
||||
有关更复杂的要求,请参阅完整版的正则表达式备忘单。
|
||||
|
||||
### 通配符(Wildcards)
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`.` | 任何字符
|
||||
`?` | 可选且只能出现一次
|
||||
`*` | 可选的,可以多次出现
|
||||
`+` | 必需并且可以多次出现
|
||||
|
||||
### 量词(Quantifiers)
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`{n}` | 前一项恰好出现 n 次
|
||||
`{n,}` | 上一个项目出现 n 次或更多
|
||||
`{,m}` | 上一个项目最多出现 n 次
|
||||
`{n,m}` | 上一项出现在 n 到 m 次之间
|
||||
|
||||
### POSIX
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`[:alpha:]` | 任何大小写字母
|
||||
`[:digit:]` | 任何数字
|
||||
`[:alnum:]` | 任何大小写字母或数字
|
||||
`[:space:]` | 任何空格
|
||||
|
||||
### 字符串
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`[A-Za-z]` | 任何大小写字母
|
||||
`[0-9]` | 任何数字
|
||||
`[0-9A-Za-z]` | 任何大小写字母或数字
|
||||
|
||||
|
||||
### 位置
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`^ ` | 行的开头
|
||||
`$ ` | 行结束
|
||||
`^$` | 空行
|
||||
`\<` | 词的开头
|
||||
`\>` | 词尾
|
||||
|
||||
更多示例
|
||||
----
|
||||
|
||||
### 搜索命令行历史记录
|
||||
|
||||
```bash
|
||||
history | grep git
|
||||
```
|
||||
|
||||
输入过 `git` 命令的记录
|
||||
|
||||
### 搜索多个文件并查找匹配文本在哪些文件中
|
||||
|
||||
```bash
|
||||
grep -l "text" file1 file2 file3...
|
||||
```
|
||||
|
||||
### 多级目录中对文本进行递归搜索
|
||||
|
||||
```bash
|
||||
grep "text" . -r -n
|
||||
```
|
||||
|
||||
`.` 表示当前目录。
|
||||
|
||||
### 搜索结果中包括或者排除指定文件
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
# 目录中所有的 .php 和 .html 文件中
|
||||
# 递归搜索字符 "main()"
|
||||
grep "main()" . -r --include *.{php,html}
|
||||
|
||||
# 在搜索结果中排除所有 README 文件
|
||||
grep "main()" . -r --exclude "README"
|
||||
|
||||
# 在搜索结果中排除 filelist 文件列表里的文件
|
||||
grep "main()" . -r --exclude-from filelist
|
||||
```
|
||||
|
||||
### 输出包含匹配字符串的行数 -n 选项
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
grep "text" -n file_name
|
||||
# 或
|
||||
cat file_name | grep "text" -n
|
||||
|
||||
#多个文件
|
||||
grep "text" -n file_1 file_2
|
||||
```
|
||||
|
||||
### 忽略匹配样式中的字符大小写
|
||||
|
||||
```bash
|
||||
echo "hello world" | grep -i "HELLO"
|
||||
# hello
|
||||
```
|
||||
|
||||
### 统计文件或文本中包含匹配字符串的行数 -c 选项
|
||||
|
||||
```
|
||||
grep -c "text" file_name
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [grep 中文文档](https://wangchujiang.com/linux-command/c/grep.html) _(jaywcjlove.github.io)_
|
903
docs/html.md
Normal file
@ -0,0 +1,903 @@
|
||||
HTML 备忘清单
|
||||
===
|
||||
|
||||
此 HTML 快速参考备忘单以可读布局列出了常见的 `HTML` 和 `HTML5` 标记。
|
||||
|
||||
入门
|
||||
------------
|
||||
|
||||
### hello.html
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>HTML5 Boilerplate</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world, hello 备忘清单!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
或者在 [jsfiddle](https://jsfiddle.net/Randy8080/1e4wz20b/)
|
||||
|
||||
### 注释 Comment
|
||||
|
||||
```html
|
||||
<!-- 这是代码注释 -->
|
||||
|
||||
<!--
|
||||
或者你可以注释掉一个
|
||||
大量的行。
|
||||
-->
|
||||
```
|
||||
|
||||
### 段落 Paragraph
|
||||
|
||||
```html
|
||||
<p>我来自快速参考</p>
|
||||
<p>分享快速参考备忘单。</p>
|
||||
```
|
||||
请参阅:[段落元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/p)
|
||||
|
||||
### HTML 链接
|
||||
|
||||
```html
|
||||
<a href="https://github.com/jaywcjlove/reference">
|
||||
Github
|
||||
</a>
|
||||
<a href="mailto:jack@abc.com">邮箱</a>
|
||||
<a href="tel:+123456789">电话</a>
|
||||
<a href="sms:+123456789&body=ha%20ha">
|
||||
短信
|
||||
</a>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`href` | 超链接指向的 URL |
|
||||
`rel` | 链接 URL 的关系 |
|
||||
`target` | 链接目标位置:`_self`/`_blank`/`_top`/`_parent` |
|
||||
|
||||
请参阅:[\<a> 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#attributes)
|
||||
|
||||
|
||||
|
||||
### Image 标签
|
||||
|
||||
```html
|
||||
<img loading="lazy"
|
||||
src="https://xxx.png"
|
||||
alt="在此处描述图像"
|
||||
width="400" height="400">
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
---
|
||||
|
||||
| | | |
|
||||
|---|-----------|------------------------------------------|
|
||||
| | `src` _(URL/路径)_ | 必填,图片位置 |
|
||||
| | `alt` | 描述图像 |
|
||||
| | `width` | 图像宽度 |
|
||||
| | `height` | 图像高度 |
|
||||
| | `loading` | 浏览器应该如何加载 |
|
||||
|
||||
请参阅:[图像嵌入元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img)
|
||||
|
||||
### 文本格式标签
|
||||
|
||||
```html
|
||||
<b>粗体文字</b>
|
||||
<strong>这段文字很重要</strong>
|
||||
<i>斜体文本</i>
|
||||
<em>这段文字被强调</em>
|
||||
<u>下划线文本</u>
|
||||
<pre>预格式化文本</pre>
|
||||
<code>源代码</code>
|
||||
<del>删除的文字</del>
|
||||
<mark>突出显示的文本 (HTML5)</mark>
|
||||
<ins>插入的文本</ins>
|
||||
<sup>使文本上标</sup>
|
||||
<sub>使文本下标</sub>
|
||||
<small>使文本变小</small>
|
||||
<pre>预格式化文本</pre>
|
||||
<kbd>Ctrl</kbd>
|
||||
<blockquote>文本块引用</blockquote>
|
||||
```
|
||||
|
||||
### 标题
|
||||
|
||||
```html
|
||||
<h1> 这是标题 1 </h1>
|
||||
<h2> 这是标题 2 </h2>
|
||||
<h3> 这是标题 3 </h3>
|
||||
<h4> 这是标题 4 </h4>
|
||||
<h5> 这是标题 5 </h5>
|
||||
<h6> 这是标题 6 </h6>
|
||||
```
|
||||
|
||||
您的页面上应该只有一个 `h1`
|
||||
|
||||
### Section Divisions
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`<div></div>` | 页面内容的划分或部分
|
||||
`<span></span>` | 其他内容中的文本部分
|
||||
`<p></p>` | 文本段落
|
||||
`<br>` | 换行
|
||||
`<hr>` | 水平分割线
|
||||
|
||||
这些标签用于将页面划分为多个部分
|
||||
|
||||
### 内部框架
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```html
|
||||
<iframe
|
||||
id="inlineFrameExample"
|
||||
title="Inline Frame Example"
|
||||
width="100%"
|
||||
height="200"
|
||||
frameborder="0"
|
||||
src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik">
|
||||
</iframe>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<iframe id="inlineFrameExample"
|
||||
title="Inline Frame Example"
|
||||
width="100%"
|
||||
height="200"
|
||||
frameborder="0"
|
||||
src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik">
|
||||
</iframe>
|
||||
|
||||
|
||||
请参阅:[内联框架元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe)
|
||||
|
||||
|
||||
### HTML 中的 JavaScript
|
||||
|
||||
```html
|
||||
<script type="text/javascript">
|
||||
let text = "Hello 快速参考";
|
||||
alert(text);
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
#### 外部 JavaScript
|
||||
|
||||
```html
|
||||
<body>
|
||||
...
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
|
||||
### HTML 中的 CSS
|
||||
|
||||
```html
|
||||
<style type="text/css">
|
||||
h1 {
|
||||
color: purple;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
#### 外部样式表
|
||||
|
||||
```html
|
||||
<head>
|
||||
...
|
||||
<link rel="stylesheet" href="style.css"/>
|
||||
</head>
|
||||
```
|
||||
|
||||
|
||||
|
||||
HTML5 标签
|
||||
-------------
|
||||
|
||||
### 页面
|
||||
|
||||
```html
|
||||
<body>
|
||||
<header>
|
||||
<nav>...</nav>
|
||||
</header>
|
||||
<main>
|
||||
<h1>快速参考</h1>
|
||||
</main>
|
||||
<footer>
|
||||
<p>©2023 快速参考</p>
|
||||
</footer>
|
||||
</body>
|
||||
```
|
||||
|
||||
|
||||
### 标题导航
|
||||
|
||||
```html
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="#">编辑页面</a></li>
|
||||
<li><a href="#">Twitter</a></li>
|
||||
<li><a href="#">Facebook</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
```
|
||||
|
||||
|
||||
### HTML5 Tags
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
[article](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/article) | 独立的内容
|
||||
[aside](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/aside) | 次要内容
|
||||
[audio](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/audio) | 嵌入声音或音频流
|
||||
[bdi](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/bdi) | 双向隔离元件
|
||||
[canvas](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/canvas) | 通过JavaScript绘制图形
|
||||
[data](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/data) | 机器可读内容
|
||||
[datalist](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/datalist) | 一组预定义选项
|
||||
[details](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/details) | 其他信息
|
||||
[dialog](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dialog) | 对话框或子窗口
|
||||
[embed](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/embed) | 嵌入外部应用程序
|
||||
[figcaption](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/figcaption) | 图形的标题或图例
|
||||
[figure](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/figure) | 插图
|
||||
[footer](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/footer) | 页脚或最不重要的
|
||||
[header](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/header) | 刊头或重要信息
|
||||
[main](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/main) | 文件的主要内容
|
||||
[mark](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/mark) | 突出显示的文本
|
||||
[meter](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/meter) | 已知范围内的标量值
|
||||
[nav](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/nav) | 导航链接的一部分
|
||||
[output](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/output) | 计算的结果
|
||||
[picture](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/picture) | 用于多个图像源的容器
|
||||
[progress](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/progress) | 任务的完成进度
|
||||
[rp](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/rp) | 提供回退括号
|
||||
[rt](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/rt) | 定义字符的发音
|
||||
[ruby](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ruby) | 表示ruby注释
|
||||
[section](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/section) | 一系列相关内容中的组
|
||||
[source](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/source) | 媒体元素的资源
|
||||
[summary](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/summary) | 元素的摘要
|
||||
[template](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/template) | 定义HTML片段
|
||||
[time](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/time) | 时间或日期
|
||||
[track](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/track) | 媒体元素的字幕信息
|
||||
[video](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video) | 嵌入视频
|
||||
[wbr](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/wbr) | 换行机会
|
||||
|
||||
|
||||
### HTML5 Video
|
||||
|
||||
```html
|
||||
<video controls="" width="100%">
|
||||
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
|
||||
很抱歉,您的浏览器不支持嵌入式视频。
|
||||
</video>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<video controls="" width="100%">
|
||||
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
|
||||
很抱歉,您的浏览器不支持嵌入式视频。
|
||||
</video>
|
||||
|
||||
### HTML5 Audio
|
||||
|
||||
```html
|
||||
<audio
|
||||
controls
|
||||
src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3">
|
||||
您的浏览器不支持音频元素。
|
||||
</audio>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<audio controls
|
||||
src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3">
|
||||
您的浏览器不支持音频元素。
|
||||
</audio>
|
||||
|
||||
### HTML5 Ruby
|
||||
|
||||
```html
|
||||
<ruby>
|
||||
汉 <rp>(</rp><rt>hàn</rt><rp>)</rp>
|
||||
字 <rp>(</rp><rt>zì</rt><rp>)</rp>
|
||||
拼 <rp>(</rp><rt>pīn</rt><rp>)</rp>
|
||||
音 <rp>(</rp><rt>yīn</rt><rp>)</rp>
|
||||
</ruby>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### ↓ 预览
|
||||
<!--rehype:wrap-style=text-align: center;-->
|
||||
|
||||
<ruby style="font-size: 4rem;">
|
||||
汉 <rp>(</rp><rt>hàn</rt><rp>)</rp>
|
||||
字 <rp>(</rp><rt>zì</rt><rp>)</rp>
|
||||
拼 <rp>(</rp><rt>pīn</rt><rp>)</rp>
|
||||
音 <rp>(</rp><rt>yīn</rt><rp>)</rp>
|
||||
</ruby>
|
||||
|
||||
|
||||
### HTML5 kdi
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li>User <bdi>hrefs</bdi>: 60 points</li>
|
||||
<li>User <bdi>jdoe</bdi>: 80 points</li>
|
||||
<li>User <bdi>إيان</bdi>: 90 points</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<ul>
|
||||
<li>User <bdi>hrefs</bdi>: 60 points</li>
|
||||
<li>User <bdi>jdoe</bdi>: 80 points</li>
|
||||
<li>User <bdi>إيان</bdi>: 90 points</li>
|
||||
</ul>
|
||||
|
||||
|
||||
### HTML5 progress
|
||||
|
||||
```html
|
||||
<progress value="50" max="100"></progress>
|
||||
```
|
||||
|
||||
<progress value="50" max="100" style="width: 100%"></progress>
|
||||
|
||||
### HTML5 mark
|
||||
|
||||
```html
|
||||
<p>我爱<mark>备忘清单</mark></p>
|
||||
```
|
||||
|
||||
<p>我爱<mark>备忘清单</mark></p>
|
||||
|
||||
|
||||
HTML 表格
|
||||
--------------
|
||||
|
||||
### Table 示例
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```html
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>age</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Roberta</td>
|
||||
<td>39</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Oliver</td>
|
||||
<td>25</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
### HTML表格标签
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
标签|说明
|
||||
:-|:-
|
||||
[\<table>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/table) | 定义表格
|
||||
[\<th>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th) | 定义表格中的标题单元格
|
||||
[\<tr>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tr) | 定义表中的行
|
||||
[\<td>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/td) | 定义表格中的单元格
|
||||
[\<caption>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/caption) | 定义表格标题
|
||||
[\<colgroup>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/colgroup) | 定义一组列
|
||||
[\<col>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/col) | 定义表中的列
|
||||
[\<thead>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/thead) | 对标题内容进行分组
|
||||
[\<tbody>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tbody) | 将正文内容分组
|
||||
[\<tfoot>](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/tfoot) | 对页脚内容进行分组
|
||||
|
||||
### \<td> 属性
|
||||
|
||||
属性|说明
|
||||
:-|:-
|
||||
`colspan` | 单元格应跨越的列数
|
||||
`headers` | 单元格与一个或多个标题单元格相关
|
||||
`rowspan` | 单元格应跨越的行数
|
||||
|
||||
请参阅:[td\#属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/td#attributes)
|
||||
|
||||
### \<th> 属性
|
||||
|
||||
属性|说明
|
||||
:-|:-
|
||||
`colspan` | 单元格应跨越的列数
|
||||
`headers` | 单元格与一个或多个标题单元格相关
|
||||
`rowspan` | 单元格应跨越的行数
|
||||
`abbr` | 单元格内容的描述
|
||||
[scope](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th#attr-scope) | 表头元素(在\<th>中定义)关联的单元格
|
||||
|
||||
请参阅:[th\#属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/th#attributes)
|
||||
|
||||
HTML 列表
|
||||
----
|
||||
|
||||
### 无序列表
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li>I'm an item</li>
|
||||
<li>I'm another item</li>
|
||||
<li>I'm another item</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
请参阅:[无序列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ul)
|
||||
|
||||
### 有序列表
|
||||
|
||||
```html
|
||||
<ol>
|
||||
<li>I'm the first item</li>
|
||||
<li>I'm the second item</li>
|
||||
<li>I'm the third item</li>
|
||||
</ol>
|
||||
```
|
||||
|
||||
请参阅:[有序列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/ol)
|
||||
|
||||
### 定义列表
|
||||
|
||||
```html
|
||||
<dl>
|
||||
<dt>A Term</dt>
|
||||
<dd>Definition of a term</dd>
|
||||
<dt>Another Term</dt>
|
||||
<dd>Definition of another term</dd>
|
||||
</dl>
|
||||
```
|
||||
|
||||
请参阅:[描述列表元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dl)
|
||||
|
||||
HTML 表单
|
||||
-----------
|
||||
|
||||
### Form 标签
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```html
|
||||
<form method="POST" action="api/login">
|
||||
<label for="mail">邮箱: </label>
|
||||
<input type="email" id="mail" name="mail">
|
||||
<br/>
|
||||
<label for="pw">密码:</label>
|
||||
<input type="password" id="pw" name="pw">
|
||||
<br/>
|
||||
<input type="submit" value="登录">
|
||||
<br/>
|
||||
<input type="checkbox" id="ck" name="ck">
|
||||
<label for="ck">记住我</label>
|
||||
</form>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form method="POST" action="api/login" style="padding: 20px;">
|
||||
<label for="email">邮箱: </label>
|
||||
<input type="email" id="email" name="email" class="border border-slate-400 mt-2">
|
||||
<br/>
|
||||
<label for="pwd">密码:</label>
|
||||
<input type="password" id="pwd" name="pwd" class="border border-slate-400 mt-2">
|
||||
<br/>
|
||||
<input type="submit" value="登录" class="mt-2">
|
||||
<br/>
|
||||
<input type="checkbox" id="ck" name="ck" class="mt-2">
|
||||
<label for="ck">记住我</label>
|
||||
</form>
|
||||
|
||||
|
||||
HTML `<form>` 元素用于收集信息并将其发送到外部源。
|
||||
|
||||
### Form 属性
|
||||
|
||||
属性|说明
|
||||
:-|:-
|
||||
`name` | 脚本形式的名称
|
||||
`action` | 表单脚本的URL
|
||||
`method` | HTTP方法,`POST`/`GET` _(默认)_
|
||||
`enctype` | 介质类型,请参见[enctype](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLFormElement/enctype)
|
||||
`onsubmit` | 提交表单时运行
|
||||
`onreset` | 在窗体重置时运行
|
||||
|
||||
### Label 标签
|
||||
|
||||
```html
|
||||
<!-- 嵌套标签 -->
|
||||
<label>Click me
|
||||
<input type="text" id="user" name="name"/>
|
||||
</label>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- 'for' 属性 -->
|
||||
<label for="user">Click me</label>
|
||||
<input id="user" type="text" name="name"/>
|
||||
```
|
||||
|
||||
`for`在标签中引用输入的`id`属性
|
||||
|
||||
### Input 标签
|
||||
|
||||
```html
|
||||
<label for="Name">Name:</label>
|
||||
<input type="text" name="Name" id="">
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px;">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" name="username" id="username" class="border border-slate-400">
|
||||
</form>
|
||||
|
||||
请参阅:[HTML输入标记](/html#html-input-tags)
|
||||
|
||||
### Textarea 标签
|
||||
|
||||
```html
|
||||
<textarea rows="2" cols="30" name="address" id="address"></textarea>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px;">
|
||||
<textarea rows="2" cols="30" name="address" id="address" class="border border-slate-400"style="width: 100%"></textarea>
|
||||
</form>
|
||||
|
||||
Textarea 是一个多行文本输入控件
|
||||
|
||||
### Radio Buttons
|
||||
|
||||
```html
|
||||
<input type="radio" name="gender" id="m">
|
||||
<label for="m">Male</label>
|
||||
<input type="radio" name="gender" id="f">
|
||||
<label for="f">Female</label>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px;">
|
||||
<input type="radio" name="gender" id="m">
|
||||
<label for="m">Male</label>
|
||||
<input type="radio" name="gender" id="f">
|
||||
<label for="f">Female</label>
|
||||
</form>
|
||||
|
||||
单选按钮用于让用户只选择一个
|
||||
|
||||
### Checkboxes
|
||||
```html
|
||||
<input type="checkbox" name="s" id="soc">
|
||||
<label for="soc">Soccer</label>
|
||||
<input type="checkbox" name="s" id="bas">
|
||||
<label for="bas">Baseball</label>
|
||||
```
|
||||
#### ↓ 预览
|
||||
<form style="padding: 20px;">
|
||||
<input type="checkbox" name="sports" id="soccer">
|
||||
<label for="soccer">Soccer</label>
|
||||
<input type="checkbox" name="sports" id="baseball">
|
||||
<label for="baseball">Baseball</label>
|
||||
</form>
|
||||
|
||||
复选框允许用户选择一个或多个
|
||||
|
||||
### Select 标签
|
||||
|
||||
```html
|
||||
<label for="city">City:</label>
|
||||
<select name="city" id="city">
|
||||
<option value="1">Sydney</option>
|
||||
<option value="2">Melbourne</option>
|
||||
<option value="3">Cromwell</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px">
|
||||
<label for="city">City:</label>
|
||||
<select name="city" id="city" class="border border-slate-400">
|
||||
<option value="1">Sydney</option>
|
||||
<option value="2">Melbourne</option>
|
||||
<option value="3">Cromwell</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
选择框是选项的下拉列表
|
||||
|
||||
### Fieldset 标签
|
||||
|
||||
```html
|
||||
<fieldset>
|
||||
<legend>Your favorite monster</legend>
|
||||
<input type="radio" id="kra" name="m">
|
||||
<label for="kraken">Kraken</label><br/>
|
||||
<input type="radio" id="sas" name="m">
|
||||
<label for="sas">Sasquatch</label>
|
||||
</fieldset>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px">
|
||||
<fieldset class="border border-slate-400" style="padding: 20px">
|
||||
<legend>Your favorite monster</legend>
|
||||
<input type="radio" id="kra" name="monster">
|
||||
<label for="kra">Kraken</label><br/>
|
||||
<input type="radio" id="sas" name="monster">
|
||||
<label for="sas">Sasquatch</label>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
### 数据列表标签(HTML5)
|
||||
|
||||
```html
|
||||
<label for="b">Choose a browser: </label>
|
||||
<input list="list" id="b" name="browser"/>
|
||||
<datalist id="list">
|
||||
<option value="Chrome">
|
||||
<option value="Firefox">
|
||||
<option value="Internet Explorer">
|
||||
<option value="Opera">
|
||||
<option value="Safari">
|
||||
<option value="Microsoft Edge">
|
||||
</datalist>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px">
|
||||
<label for="myBrowser">Choose a browser:</label>
|
||||
<input list="browsers" id="myBrowser" name="myBrowser"/>
|
||||
<datalist id="browsers">
|
||||
<option value="Chrome">
|
||||
<option value="Firefox">
|
||||
<option value="Internet Explorer">
|
||||
<option value="Opera">
|
||||
<option value="Safari">
|
||||
<option value="Microsoft Edge">
|
||||
</datalist>
|
||||
</form>
|
||||
|
||||
### 提交和重置按钮
|
||||
|
||||
```html
|
||||
<form action="register.php" method="post">
|
||||
<label for="foo">Name:</label>
|
||||
<input type="text" name="name" id="foo">
|
||||
<input type="submit" value="提交">
|
||||
<input type="reset" value="重置">
|
||||
</form>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form action="register.php" method="post" style="padding: 20px">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" name="name" id="name"">
|
||||
<input type="submit" value="提交">
|
||||
<input type="reset" value="重置">
|
||||
</form>
|
||||
|
||||
`将数据提交到服务器` 重置为默认值
|
||||
|
||||
|
||||
HTML input 标签
|
||||
-----------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### Input 属性
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
输入标记是一个空元素,用于标识要从用户处获取的特定类型的字段信息。
|
||||
|
||||
```html
|
||||
<input type="text" name="?" value="?" minlength="6" required />
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`type="…"` | 正在输入的数据类型
|
||||
`value="…"` | 默认值
|
||||
`name="…"` | 用于在 HTTP 请求中描述此数据
|
||||
`id="…"` | 其他 HTML 元素的唯一标识符
|
||||
`readonly` | 停止用户修改
|
||||
`disabled` | 停止任何交互
|
||||
`checked` | 单选或复选框是否选中
|
||||
`required` | 是强制性的,参阅[必填](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/required#example)
|
||||
`placeholder="…"` | 添加临时,请参阅[::placeholder](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::placeholder#examples)
|
||||
`autocomplete="off"` | 禁用自动完成
|
||||
`autocapitalize="none"` | 禁用自动大写
|
||||
`inputmode="…"` | 显示特定键盘,请参阅[inputmode](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/inputmode)
|
||||
`list="…"` | 关联的[datalist](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/datalist)的id
|
||||
`maxlength="…"` | 最大字符数
|
||||
`minlength="…"` | 最小字符数
|
||||
`min="…"` | 范围和编号上的最小数值
|
||||
`max="…"` | 范围和编号上的最大数值
|
||||
`step="…"` | 数字如何在范围和数字中递增
|
||||
`pattern="…"` | 指定一个[正则表达式](./regex.md),请参阅[pattern](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/pattern)
|
||||
`autofocus` | 集中精力
|
||||
`spellcheck` | 执行拼写检查
|
||||
`multiple` | 是否允许[多个](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/multiple)值
|
||||
`accept=""` | [file](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file) 中需要文件类型上载控件
|
||||
|
||||
请参阅:[\<input>元素 的属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input#attributes)
|
||||
|
||||
### Input 类型
|
||||
|
||||
| | |
|
||||
|---------------|------------------|
|
||||
`type="checkbox"` | <input type="checkbox">
|
||||
`type="radio"` | <input type="radio">
|
||||
`type="file"` | <input type="file">
|
||||
`type="hidden"` | <input type="hidden">
|
||||
`type="text"` | <input type="text">
|
||||
`type="password"` | <input type="password">
|
||||
`type="image"` | <input type="image" src="https://raw.githubusercontent.com/mdn/learning-area/master/html/forms/image-type-example/login.png" width="70">
|
||||
`type="reset"` | <input type="reset">
|
||||
`type="button"` | <input type="button">
|
||||
`type="submit"` | <input type="submit">
|
||||
|
||||
#### HTML5 中的新输入类型
|
||||
|
||||
| | |
|
||||
|---------------|------------------|
|
||||
| `type="color"` | <input type="color" value="#0FB881"> |
|
||||
| `type="date"` | <input type="date"> |
|
||||
| `type="time"` | <input type="time"> |
|
||||
| `type="month"` | <input type="month"> |
|
||||
| `type="datetime-local"` | <input type="datetime-local"> |
|
||||
| `type="week"` | <input type="week"> |
|
||||
| `type="email"` | <input type="email"> |
|
||||
| `type="tel"` | <input type="tel"> |
|
||||
| `type="url"` | <input type="url"> |
|
||||
| `type="number"` | <input type="number"> |
|
||||
| `type="search"` | <input type="search"> |
|
||||
| `type="range"` | <input type="range"> |
|
||||
|
||||
|
||||
### Input CSS 选择器
|
||||
|
||||
| | |
|
||||
|---------------|------------------|
|
||||
| `input:focus` | 当键盘聚焦时 |
|
||||
|
||||
HTML meta 标签
|
||||
-----------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### Meta 标签
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他材料。
|
||||
|
||||
```html
|
||||
<meta charset="utf-8">
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- 标题 -->
|
||||
<title>···</title>
|
||||
<meta property="og:title" content="···">
|
||||
<meta name="twitter:title" content="···">
|
||||
```
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- url -->
|
||||
<link rel="canonical" href="https://···">
|
||||
<meta property="og:url" content="https://···">
|
||||
<meta name="twitter:url" content="https://···">
|
||||
```
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- 描述 -->
|
||||
<meta name="description" content="···">
|
||||
<meta property="og:description" content="···">
|
||||
<meta name="twitter:description" content="···">
|
||||
```
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- image -->
|
||||
<meta property="og:image" content="https://···">
|
||||
<meta name="twitter:image" content="https://···">
|
||||
```
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- ua -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
```
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- viewport -->
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="viewport" content="width=1024">
|
||||
```
|
||||
|
||||
### Open Graph
|
||||
|
||||
```html
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:locale" content="en_CA">
|
||||
<meta property="og:title" content="HTML cheatsheet">
|
||||
<meta property="og:url" content="https://quickref.me/html">
|
||||
<meta property="og:image" content="https://xxx.com/image.jpg">
|
||||
<meta property="og:site_name" content="Name of your website">
|
||||
<meta property="og:description" content="Description of this page">
|
||||
```
|
||||
|
||||
Facebook、Instagram、Pinterest、LinkedIn 等使用。
|
||||
|
||||
### Twitter 卡片
|
||||
|
||||
```html
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@QuickRef_ME">
|
||||
<meta name="twitter:title" content="HTML cheatsheet">
|
||||
<meta name="twitter:url" content="https://quickref.me/html">
|
||||
<meta name="twitter:description" content="Description of this page">
|
||||
<meta name="twitter:image" content="https://xxx.com/image.jpg">
|
||||
```
|
||||
|
||||
请参阅:[Twitter 卡片文档](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary)
|
||||
|
||||
### Geotagging
|
||||
|
||||
```html
|
||||
<meta name="ICBM" content="45.416667,-75.7">
|
||||
<meta name="geo.position" content="45.416667;-75.7">
|
||||
<meta name="geo.region" content="ca-on">
|
||||
<meta name="geo.placename" content="Ottawa">
|
||||
```
|
||||
|
||||
请参阅:[Geotagging](https://en.wikipedia.org/wiki/Geotagging#HTML_pages)
|
||||
|
||||
另见
|
||||
--------
|
||||
|
||||
- [HTML 4.01 Specification](https://www.w3.org/TR/REC-html40/cover.html#minitoc) _(w3.org)_
|
||||
- [HTML Tutorial](https://wangchujiang.com/html-tutorial/) _(jaywcjlove.github.io)_
|
||||
- [Emmet 备忘清单,提升 HTML 和 CSS 代码编写的工具包](./emmet.md) _(jaywcjlove.github.io)_
|
111
docs/htop.md
Normal file
@ -0,0 +1,111 @@
|
||||
htop 备忘清单
|
||||
===
|
||||
|
||||
htop 是一个交互式流程查看器,此 htop 备忘清单包含 htop 命令
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### htop 用法
|
||||
|
||||
htop 是一个互动的进程查看器,动态观察系统进程状况
|
||||
|
||||
- [命令 htop 的官网](https://htop.sourceforge.net/)
|
||||
|
||||
```bash
|
||||
$ htop [-dChustv]
|
||||
```
|
||||
|
||||
#### 安装
|
||||
|
||||
```bash
|
||||
$ apt install htop # Debian
|
||||
$ dnf install htop # Fedora
|
||||
$ emerge sys-process/htop # Gentoo
|
||||
$ pacman -S htop # Arch Linux
|
||||
$ Compile htop # GoboLinux
|
||||
```
|
||||
|
||||
htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/downloads.html)
|
||||
|
||||
### 选项示例
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
长选项的强制参数对于短选项也是强制的
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`-d --delay=DELAY` | 更新之间的延迟,以十分之一秒为单位
|
||||
`-C --no-color --no-colour` | 以单色模式启动 `htop`
|
||||
`-h --help` | 显示帮助消息并退出
|
||||
`-p --pid=PID,PID...` | 仅显示给定的PID
|
||||
`-s --sort-key COLUMN` | 按此列排序(对列列表使用`--sort-key`帮助)
|
||||
`-u --user=USERNAME` | 仅显示给定用户的进程
|
||||
`-v --version` | 输出版本信息并退出
|
||||
`-t --tree` | 在树状视图中显示流程
|
||||
|
||||
### 状态
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`R` | 运行中
|
||||
`S` | 休眠
|
||||
`T` | 追踪/停止
|
||||
`Z` | 僵尸
|
||||
`D` | 磁盘睡眠
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 交互式命令
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`F1`, `h`, `?` | 转到帮助屏幕
|
||||
`F10`, `q` | 退出
|
||||
`Space` | 标记或取消标记进程
|
||||
`U` | 取消标记所有进程(删除所有使用 Space 键添加的标记)
|
||||
`s` | 跟踪进程系统调用:如果安装了 `strace(1)`,按下此键会将其附加到当前选定的进程,呈现进程发出的系统调用的实时更新
|
||||
`l` | 显示进程打开的文件:如果安装了 `lsof(1)`,按下该键将显示进程打开的文件描述符列表
|
||||
`F2`, `S` | 转到设置屏幕,您可以在其中配置屏幕顶部显示的仪表,设置各种显示选项,在配色方案中进行选择,并选择显示的列,以何种顺序显示
|
||||
`F3`, `/` | 逐步搜索所有显示进程的命令行。当前选定(突出显示)的命令将在您键入时更新。在搜索模式下,按 `F3` 将循环匹配出现的事件
|
||||
`F4`, `\` | 增量进程过滤:输入部分进程命令行,仅显示名称匹配的进程。要取消过滤,请再次输入过滤选项并按 `Esc`
|
||||
`F5`, `t` | 树视图:按父级组织进程,并将它们之间的关系布局为树。切换键将在树和您之前选择的排序视图之间切换。选择排序视图将退出树视图
|
||||
`F6` | 在排序视图上,选择一个字段进行排序,也可以通过 < 和 > 访问。当前排序字段由标题中的突出显示。在树视图中,展开或折叠当前子树。树节点中的“+”指示符表示它已折叠
|
||||
`F7`, `]` | 增加所选进程的优先级(从“nice”值中减去)。这只能由超级用户完成
|
||||
`F8`, `[` | 降低选定进程的优先级(添加到“nice”值)
|
||||
`F9`, `k` | “杀死”进程:向一个或一组进程发送一个在菜单中选择的信号。如果进程被标记,则将信号发送到所有标记的进程。如果没有标记,则发送到当前选定的进程
|
||||
`+`, `-` | 在树视图模式下,展开或折叠子树。
|
||||
`a` | (在多 CPU 机器上)设置 CPU 亲和性:标记允许进程使用的 CPU
|
||||
`u` | 仅显示指定用户拥有的进程
|
||||
`F` | “跟随”进程:如果排序顺序导致当前选定的进程在列表中移动,则使选择栏跟随它。这对于监控进程很有用:这样,您可以使进程始终在屏幕上可见。使用移动键时,“跟随”失效。
|
||||
`p` | 在适用的情况下显示运行程序的完整路径(这是一个切换键)
|
||||
`Ctrl-L` | 刷新:重绘屏幕并重新计算数值
|
||||
`Numbers` | PID搜索:输入进程ID,选择突出显示将移至它
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 排序/线程
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M` | 按`内存`使用情况排序 _(最高兼容性键)_
|
||||
`P` | 按`CPU`使用情况排序 _(最高兼容性键)_
|
||||
`T` | 按`时间`排序 _(最高兼容性键)_
|
||||
`I` | `反转`排序顺序
|
||||
`K` | 隐藏`内核`线程
|
||||
`H` | 隐藏`用户`线程
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 滚动
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`Up`, `Alt-k` | 在流程列表中选择(突出)`上`一个流程
|
||||
`Down`, `Alt-j` | 在流程列表中选择(突出)`下`一个流程
|
||||
`Left`, `Alt-h` | 向`左`滚动流程列表
|
||||
`Right`, `Alt-l` | 向`右`滚动进程列表
|
||||
`PgUp`, `PgDn` | 将流程列表`向上`或`向下`滚动一个窗口
|
||||
`Home` | 滚动到流程列表的`顶部` <br /> _选择第一个流程_
|
||||
`End` | 滚动到流程列表的`底部` <br /> _选择最后一个流程_
|
||||
`Ctrl-A`, `^` | 向`左`滚动到流程条目`开头` _(即行开头)_
|
||||
`Ctrl-E`, `$` | 向`右`滚动到流程条目`末尾` _(即行尾)_
|
||||
<!--rehype:className=shortcuts-->
|
@ -8,70 +8,70 @@ HTTP 状态码
|
||||
|
||||
### Means
|
||||
|
||||
- [1xx: Informational](#1xx-information) _这意味着已收到请求并且该过程正在继续。_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-successful) _这意味着该操作已成功接收、理解和接受。_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-redirection) _这意味着必须采取进一步行动才能完成请求。_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-client-error) _这意味着请求包含不正确的语法或无法完成。_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-server-error) _这意味着服务器未能满足明显有效的请求。_<!--rehype:tooltips-->
|
||||
- [1xx: Informational](#1xx-information) _这意味着已收到请求并且该过程正在继续_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-successful) _这意味着该操作已成功接收、理解和接受_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-redirection) _这意味着必须采取进一步行动才能完成请求_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-client-error) _这意味着请求包含不正确的语法或无法完成_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-server-error) _这意味着服务器未能满足明显有效的请求_<!--rehype:tooltips-->
|
||||
|
||||
### 2xx. 成功的
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
* [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题。_<!--rehype:tooltips-->
|
||||
* [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成,并创建了一个新资源。_<!--rehype:tooltips-->
|
||||
* [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理,但处理未完成。_<!--rehype:tooltips-->
|
||||
* [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本,而不是来自原始服务器。_<!--rehype:tooltips-->
|
||||
* [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头,但响应中没有实体主体。_<!--rehype:tooltips-->
|
||||
* [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入。_<!--rehype:tooltips-->
|
||||
* [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围。_<!--rehype:tooltips-->
|
||||
* [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题_<!--rehype:tooltips-->
|
||||
* [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成,并创建了一个新资源_<!--rehype:tooltips-->
|
||||
* [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理,但处理未完成_<!--rehype:tooltips-->
|
||||
* [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本,而不是来自原始服务器_<!--rehype:tooltips-->
|
||||
* [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头,但响应中没有实体主体_<!--rehype:tooltips-->
|
||||
* [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入_<!--rehype:tooltips-->
|
||||
* [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围_<!--rehype:tooltips-->
|
||||
|
||||
### 4xx. 客户端错误
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
* [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求。_<!--rehype:tooltips-->
|
||||
* [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码。_<!--rehype:tooltips-->
|
||||
* [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码。_<!--rehype:tooltips-->
|
||||
* [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面。_<!--rehype:tooltips-->
|
||||
* [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面。_<!--rehype:tooltips-->
|
||||
* [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的。_<!--rehype:tooltips-->
|
||||
* [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应。_<!--rehype:tooltips-->
|
||||
* [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证,然后才能提供此请求。_<!--rehype:tooltips-->
|
||||
* [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长。_<!--rehype:tooltips-->
|
||||
* [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突,请求无法完成。_<!--rehype:tooltips-->
|
||||
* [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用。_<!--rehype:tooltips-->
|
||||
* [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求。_<!--rehype:tooltips-->
|
||||
* [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false。_<!--rehype:tooltips-->
|
||||
* [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求,因为请求实体太大。_<!--rehype:tooltips-->
|
||||
* [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求,因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生。_<!--rehype:tooltips-->
|
||||
* [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求,因为不支持媒体类型。_<!--rehype:tooltips-->
|
||||
* [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围。_<!--rehype:tooltips-->
|
||||
* [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望。_<!--rehype:tooltips-->
|
||||
* [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求,但在客户端升级到不同协议后可能愿意这样做。_<!--rehype:tooltips-->
|
||||
* [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果。_<!--rehype:tooltips-->
|
||||
* [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求_<!--rehype:tooltips-->
|
||||
* [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码_<!--rehype:tooltips-->
|
||||
* [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码_<!--rehype:tooltips-->
|
||||
* [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面_<!--rehype:tooltips-->
|
||||
* [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面_<!--rehype:tooltips-->
|
||||
* [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的_<!--rehype:tooltips-->
|
||||
* [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应_<!--rehype:tooltips-->
|
||||
* [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证,然后才能提供此请求_<!--rehype:tooltips-->
|
||||
* [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长_<!--rehype:tooltips-->
|
||||
* [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突,请求无法完成_<!--rehype:tooltips-->
|
||||
* [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用_<!--rehype:tooltips-->
|
||||
* [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求_<!--rehype:tooltips-->
|
||||
* [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false_<!--rehype:tooltips-->
|
||||
* [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求,因为请求实体太大_<!--rehype:tooltips-->
|
||||
* [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求,因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生_<!--rehype:tooltips-->
|
||||
* [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求,因为不支持媒体类型_<!--rehype:tooltips-->
|
||||
* [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围_<!--rehype:tooltips-->
|
||||
* [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望_<!--rehype:tooltips-->
|
||||
* [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求,但在客户端升级到不同协议后可能愿意这样做_<!--rehype:tooltips-->
|
||||
* [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果_<!--rehype:tooltips-->
|
||||
|
||||
### 1xx. 信息
|
||||
|
||||
* [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分,但只要没有被拒绝,客户端就应该继续请求。_<!--rehype:tooltips-->
|
||||
* [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议。_<!--rehype:tooltips-->
|
||||
* [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应。_<!--rehype:tooltips-->
|
||||
* [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分,但只要没有被拒绝,客户端就应该继续请求_<!--rehype:tooltips-->
|
||||
* [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议_<!--rehype:tooltips-->
|
||||
* [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应_<!--rehype:tooltips-->
|
||||
|
||||
### 3xx. 重定向
|
||||
|
||||
* [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址。_<!--rehype:tooltips-->
|
||||
* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url 。_<!--rehype:tooltips-->
|
||||
* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url 。_<!--rehype:tooltips-->
|
||||
* [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到。_<!--rehype:tooltips-->
|
||||
* [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改。_<!--rehype:tooltips-->
|
||||
* [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问。_<!--rehype:tooltips-->
|
||||
* [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留。_<!--rehype:tooltips-->
|
||||
* [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url。_<!--rehype:tooltips-->
|
||||
* [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址_<!--rehype:tooltips-->
|
||||
* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url _<!--rehype:tooltips-->
|
||||
* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url _<!--rehype:tooltips-->
|
||||
* [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到_<!--rehype:tooltips-->
|
||||
* [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改_<!--rehype:tooltips-->
|
||||
* [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问_<!--rehype:tooltips-->
|
||||
* [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留_<!--rehype:tooltips-->
|
||||
* [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
|
||||
|
||||
### 5xx. 服务器错误
|
||||
|
||||
* [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。 服务器遇到了意外情况_<!--rehype:tooltips-->
|
||||
* [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。 服务器不支持所需的功能_<!--rehype:tooltips-->
|
||||
* [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。 服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
|
||||
* [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。 服务器暂时超载或停机_<!--rehype:tooltips-->
|
||||
* [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。服务器遇到了意外情况_<!--rehype:tooltips-->
|
||||
* [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。服务器不支持所需的功能_<!--rehype:tooltips-->
|
||||
* [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
|
||||
* [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。服务器暂时超载或停机_<!--rehype:tooltips-->
|
||||
* [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_<!--rehype:tooltips-->
|
||||
* [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_<!--rehype:tooltips-->
|
||||
|
||||
@ -79,41 +79,41 @@ HTTP 状态码
|
||||
|
||||
:- | -
|
||||
---- | ----
|
||||
`200` | 返回成功,GET,DELETE 请求成功。
|
||||
`204` | 无内容,POST 请求成功。
|
||||
`301` | 永久重定向。
|
||||
`302/307` | 临时重定向。
|
||||
`304` | 未修改,自上次请求以来。
|
||||
`331` | 用户名正确,需要密码。
|
||||
`332` | 需要登录帐户。
|
||||
`400` | 错误请求,缺少 API 请求的必需属性。
|
||||
`401` | 未授权,无效凭据进行身份验证将。
|
||||
`403` | 禁地,该请求不被允许。
|
||||
`404` | 未找到,无法访问资源
|
||||
`405` | 方法不允许,不支持该请求。
|
||||
`409` | 冲突,冲突资源已存在。
|
||||
`412` | 该请求被拒绝。
|
||||
`422` | 无法处理,无法处理该实体。
|
||||
`429` | 请求过多,用户超出了应用速率限制。
|
||||
`500` | 服务器错误,在处理请求时,服务器出现问题。
|
||||
`530` | 未登录。
|
||||
`200` | 返回成功,GET,DELETE 请求成功
|
||||
`204` | 无内容,POST 请求成功
|
||||
`301` | 永久重定向
|
||||
`302/307` | 临时重定向
|
||||
`304` | 未修改,自上次请求以来
|
||||
`331` | 用户名正确,需要密码
|
||||
`332` | 需要登录帐户
|
||||
`400` | 错误请求,缺少 API 请求的必需属性
|
||||
`401` | 未授权,无效凭据进行身份验证将
|
||||
`403` | 禁地,该请求不被允许
|
||||
`404` | 未找到,无法访问资
|
||||
`405` | 方法不允许,不支持该请求
|
||||
`409` | 冲突,冲突资源已存在
|
||||
`412` | 该请求被拒绝
|
||||
`422` | 无法处理,无法处理该实体
|
||||
`429` | 请求过多,用户超出了应用速率限制
|
||||
`500` | 服务器错误,在处理请求时,服务器出现问题
|
||||
`530` | 未登录
|
||||
|
||||
### 5xx 永久性否定
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | -
|
||||
---- | ----
|
||||
`500` | 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误。
|
||||
`501` | 在参数中有语法错误。
|
||||
`502` | 未执行命令。
|
||||
`503` | 错误的命令序列。
|
||||
`504` | 未执行该参数的命令。
|
||||
`530` | 未登录。
|
||||
`532` | 存储文件需要帐户。
|
||||
`550` | 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)。
|
||||
`551` | 请求的操作异常终止:未知的页面类型。
|
||||
`552` | 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)。
|
||||
`553` | 未执行请求的操作。不允许的文件名。
|
||||
`500` | 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误
|
||||
`501` | 在参数中有语法错误
|
||||
`502` | 未执行命令
|
||||
`503` | 错误的命令序列
|
||||
`504` | 未执行该参数的命令
|
||||
`530` | 未登录
|
||||
`532` | 存储文件需要帐户
|
||||
`550` | 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)
|
||||
`551` | 请求的操作异常终止:未知的页面类型
|
||||
`552` | 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)
|
||||
`553` | 未执行请求的操作。不允许的文件名
|
||||
|
||||
永久性否定的完成答复,该命令不成功,错误是永久性的。如果客户端重试命令,将再次出现同样的错误。
|
||||
|
||||
|
311
docs/jest.md
@ -1,14 +1,16 @@
|
||||
Jest 备忘清单
|
||||
===
|
||||
|
||||
Jest 是一款优雅、简洁的 JavaScript 测试框架。
|
||||
Jest 是一款优雅、简洁的 JavaScript 测试框架,这里介绍了它的入门和 一些 API 的索引。
|
||||
|
||||
入门
|
||||
----
|
||||
<!--rehype:body-class=cols-6-->
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
[Jest](https://jestjs.io/) 是一款优雅、简洁的 JavaScript 测试框架。
|
||||
[Jest v29](https://jestjs.io/) 是一款优雅、简洁的 JavaScript 测试框架。
|
||||
|
||||
- `无需配置` 大多数 JS 项目中即装即用,无需配置
|
||||
- `优秀接口` 从 `it` 到 `expect` - Jest 将工具包整合在一处。文档齐全、不断维护,非常不错。
|
||||
@ -16,9 +18,54 @@ Jest 是一款优雅、简洁的 JavaScript 测试框架。
|
||||
- `快照` 轻松编写持续追踪大型对象的测试,并在测试旁或代码内显示实时快照。
|
||||
- `代码覆盖` 无需其他操作,您仅需添加 `--coverage` 参数来生成代码覆盖率报告。
|
||||
|
||||
### 测试结构
|
||||
### 快速开始
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```bash
|
||||
npm install --save-dev jest
|
||||
```
|
||||
|
||||
Add to `package.json`
|
||||
|
||||
```js
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
```
|
||||
|
||||
运行你的测试
|
||||
|
||||
```bash
|
||||
npm test -- --watch
|
||||
```
|
||||
|
||||
查看: [Getting started](https://jestjs.io/docs/getting-started)
|
||||
|
||||
### 编写测试
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
describe('My work', () => {
|
||||
test('works', () => {
|
||||
expect(2).toEqual(2)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### BDD 语法
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js {2}
|
||||
describe('My work', () => {
|
||||
it('works', () => { // `it`是`test`的别名
|
||||
···
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 测试结构
|
||||
<!--rehype:wrap-class=col-span-3 row-span-2-->
|
||||
|
||||
```js
|
||||
describe('makePoniesPink', () => {
|
||||
beforeAll(() => {
|
||||
@ -40,6 +87,143 @@ describe('makePoniesPink', () => {
|
||||
})
|
||||
```
|
||||
|
||||
### 聚焦测试
|
||||
|
||||
```js
|
||||
describe.only(···)
|
||||
|
||||
it.only(···)
|
||||
// 别名: fit()
|
||||
```
|
||||
|
||||
查看: [test.only](https://jestjs.io/docs/api#testonlyname-fn-timeout)
|
||||
|
||||
### 可选参数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
| Flag | Description |
|
||||
| --------------------- | ---------------------------------------- |
|
||||
| `--coverage` | 查看测试覆盖率摘要 |
|
||||
| `--detectOpenHandles` | 查看未关闭端口的摘要 |
|
||||
| `--runInBand` | 一个接一个地运行所有测试 |
|
||||
| `--bail,-b` | 失败跳出测试 |
|
||||
|
||||
更多参数查看 [Jest CLI Options](https://jestjs.io/docs/next/cli#--bailn)
|
||||
|
||||
### 跳过测试
|
||||
|
||||
```js
|
||||
describe.skip(···)
|
||||
|
||||
it.skip(···)
|
||||
// 别名: xit()
|
||||
```
|
||||
|
||||
查看: [test.skip](https://jestjs.io/docs/next/api#testskipname-fn)
|
||||
|
||||
### 基本测试用例
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value).not.toBe(value)
|
||||
.toEqual(value)
|
||||
.toBeTruthy()
|
||||
// Errors 测试
|
||||
expect(value).toThrow(error)
|
||||
.toThrowErrorMatchingSnapshot()
|
||||
```
|
||||
|
||||
### 快照
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toMatchSnapshot()
|
||||
.toMatchInlineSnapshot()
|
||||
```
|
||||
|
||||
### Errors
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toThrow(error)
|
||||
.toThrowErrorMatchingSnapshot()
|
||||
```
|
||||
|
||||
### Objects
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toBeInstanceOf(Class)
|
||||
.toMatchObject(object)
|
||||
.toHaveProperty(keyPath, value)
|
||||
```
|
||||
|
||||
### Objects
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toContain(item)
|
||||
.toContainEqual(item)
|
||||
.toHaveLength(number)
|
||||
```
|
||||
|
||||
### Numbers
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toBeCloseTo(number, numDigits)
|
||||
.toBeGreaterThan(number)
|
||||
.toBeGreaterThanOrEqual(number)
|
||||
.toBeLessThan(number)
|
||||
.toBeLessThanOrEqual(number)
|
||||
```
|
||||
|
||||
### Booleans
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toBeFalsy()
|
||||
.toBeNull()
|
||||
.toBeTruthy()
|
||||
.toBeUndefined()
|
||||
.toBeDefined()
|
||||
```
|
||||
|
||||
### Strings
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect(value)
|
||||
.toMatch(regexpOrString)
|
||||
```
|
||||
|
||||
### NaN
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
test('当值为 NaN 时通过', () => {
|
||||
expect(NaN).toBeNaN();
|
||||
expect(1).not.toBeNaN();
|
||||
});
|
||||
```
|
||||
|
||||
### Others
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```js
|
||||
expect.extend(matchers)
|
||||
expect.any(constructor)
|
||||
expect.addSnapshotSerializer(serializer)
|
||||
|
||||
expect.assertions(1)
|
||||
```
|
||||
|
||||
匹配器
|
||||
----
|
||||
|
||||
@ -293,8 +477,6 @@ expect(fn).toThrowErrorMatchingSnapshot()
|
||||
### 实例
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
请参阅 Jest 文档中的 [更多示例](https://jestjs.io/docs/en/tutorial-async)。
|
||||
|
||||
在异步测试中指定一些预期的断言是一个很好的做法,所以如果你的断言根本没有被调用,测试将会失败。
|
||||
|
||||
```js
|
||||
@ -314,6 +496,7 @@ beforeEach(expect.hasAssertions)
|
||||
```
|
||||
|
||||
这将验证每个测试用例至少存在一个断言。 它还可以与更具体的 `expect.assertions(3)` 声明配合使用。
|
||||
请参阅 Jest 文档中的 [更多示例](https://jestjs.io/docs/en/tutorial-async)
|
||||
|
||||
### async/await
|
||||
|
||||
@ -337,8 +520,8 @@ test('async test', (done) => {
|
||||
|
||||
setTimeout(() => {
|
||||
try {
|
||||
const result = getAsyncOperationResult()
|
||||
expect(result).toBe(true)
|
||||
const res = getAsyncOperatResult()
|
||||
expect(res).toBe(true)
|
||||
done()
|
||||
} catch (err) {
|
||||
done.fail(err)
|
||||
@ -374,18 +557,28 @@ test('call the callback', () => {
|
||||
const callback = jest.fn()
|
||||
fn(callback)
|
||||
expect(callback).toBeCalled()
|
||||
expect(callback.mock.calls[0][1].baz).toBe('pizza') // 第一次调用的第二个参数
|
||||
expect(callback.mock.calls[0][1].baz)
|
||||
.toBe('pizza') // 第一次调用的第二个参数
|
||||
|
||||
// 匹配第一个和最后一个参数,但忽略第二个参数
|
||||
expect(callback).toHaveBeenLastCalledWith('meal', expect.anything(), 'margarita')
|
||||
expect(callback)
|
||||
.toHaveBeenLastCalledWith(
|
||||
'meal',
|
||||
expect.anything(),
|
||||
'margarita'
|
||||
)
|
||||
})
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
您还可以使用快照:
|
||||
|
||||
```js
|
||||
test('call the callback', () => {
|
||||
// mockName 在 Jest 22+ 中可用
|
||||
const callback = jest.fn().mockName('Unicorn')
|
||||
const callback = jest.fn()
|
||||
.mockName('Unicorn')
|
||||
|
||||
fn(callback)
|
||||
expect(callback).toMatchSnapshot()
|
||||
// ->
|
||||
@ -411,6 +604,7 @@ const callback = jest.fn(() => true)
|
||||
```js
|
||||
const callback
|
||||
= jest.fn().mockReturnValue(true)
|
||||
|
||||
const callbackOnce
|
||||
= jest.fn().mockReturnValueOnce(true)
|
||||
```
|
||||
@ -418,26 +612,29 @@ const callbackOnce
|
||||
或解析值:
|
||||
|
||||
```js
|
||||
const promise
|
||||
const promise
|
||||
= jest.fn().mockResolvedValue(true)
|
||||
const promiseOnce
|
||||
|
||||
const promiseOnce
|
||||
= jest.fn().mockResolvedValueOnce(true)
|
||||
```
|
||||
|
||||
他们甚至可以拒绝值:
|
||||
|
||||
```js
|
||||
const failedPromise
|
||||
= jest.fn().mockRejectedValue('Error')
|
||||
const failedPromiseOnce
|
||||
= jest.fn().mockRejectedValueOnce('Error')
|
||||
const failedPromise =
|
||||
jest.fn().mockRejectedValue('Error')
|
||||
|
||||
const failedPromiseOnce =
|
||||
jest.fn().mockRejectedValueOnce('Error')
|
||||
```
|
||||
|
||||
你甚至可以结合这些:
|
||||
|
||||
```js
|
||||
const callback
|
||||
= jest.fn().mockReturnValueOnce(false).mockReturnValue(true)
|
||||
const callback = jest.fn()
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValue(true)
|
||||
// ->
|
||||
// call 1: false
|
||||
// call 2+: true
|
||||
@ -446,13 +643,20 @@ const callback
|
||||
### 使用 `jest.mock` 方法模拟模块
|
||||
|
||||
```js
|
||||
jest.mock('lodash/memoize', () => (a) => a) // The original lodash/memoize should exist
|
||||
jest.mock('lodash/memoize', () => (a) => a, { virtual: true }) // The original lodash/memoize isn’t required
|
||||
// 原来的 lodash/memoize 应该存在
|
||||
jest.mock(
|
||||
'lodash/memoize',
|
||||
() => (a) => a
|
||||
)
|
||||
// 不需要原始的 lodash/memoize
|
||||
jest.mock(
|
||||
'lodash/memoize',
|
||||
() => (a) => a,
|
||||
{ virtual: true }
|
||||
)
|
||||
```
|
||||
|
||||
[jest.mock docs](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options)
|
||||
|
||||
> 注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。
|
||||
注意:当使用 `babel-jest` 时,对 [`jest.mock`](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options) 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。
|
||||
|
||||
### 使用模拟文件模拟模块
|
||||
|
||||
@ -468,22 +672,18 @@ module.exports = (a) => a
|
||||
jest.mock('lodash/memoize')
|
||||
```
|
||||
|
||||
注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。
|
||||
注意:当使用 `babel-jest` 时,对 `jest.mock` 的调用将自动提升到代码块的顶部。 如果您想明确避免这种行为,请使用 `jest.doMock`。[手动模拟文档](https://jestjs.io/docs/en/manual-mocks)
|
||||
|
||||
[手动模拟文档](https://jestjs.io/docs/en/manual-mocks)
|
||||
|
||||
### 模拟对象方法
|
||||
### 模拟 getters 和 setters
|
||||
|
||||
```js
|
||||
const spy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
||||
expect(console.log.mock.calls).toEqual([['dope'], ['nope']])
|
||||
spy.mockRestore()
|
||||
```
|
||||
|
||||
```js
|
||||
const spy = jest.spyOn(ajax, 'request').mockImplementation(() => Promise.resolve({ success: true }))
|
||||
expect(spy).toHaveBeenCalled()
|
||||
spy.mockRestore()
|
||||
const getTitle = jest.fn(() => 'pizza')
|
||||
const setTitle = jest.fn()
|
||||
const location = {}
|
||||
Object.defineProperty(location, 'title', {
|
||||
get: getTitle,
|
||||
set: setTitle,
|
||||
})
|
||||
```
|
||||
|
||||
### 模拟 getter 和 setter (Jest 22.1.0+)
|
||||
@ -508,8 +708,9 @@ const setTitle = jest
|
||||
jest.useFakeTimers()
|
||||
test('kill the time', () => {
|
||||
const callback = jest.fn()
|
||||
// 运行一些使用 setTimeout 或 setInterval 的代码
|
||||
const actual = someFunctionThatUseTimers(callback)
|
||||
// 运行使用 setTimeout或setInterval 的代码
|
||||
const actual
|
||||
= someFunctionThatUseTimers(callback)
|
||||
// 快进直到所有定时器都执行完毕
|
||||
jest.runAllTimers()
|
||||
// 同步检查结果
|
||||
@ -524,8 +725,9 @@ test('kill the time', () => {
|
||||
jest.useFakeTimers()
|
||||
test('kill the time', () => {
|
||||
const callback = jest.fn()
|
||||
// 运行一些使用 setTimeout 或 setInterval 的代码
|
||||
const actual = someFunctionThatUseTimers(callback)
|
||||
// 运行使用 setTimeout或setInterval 的代码
|
||||
const actual
|
||||
= someFunctionThatUseTimers(callback)
|
||||
// 快进 250 毫秒
|
||||
jest.advanceTimersByTime(250)
|
||||
// 同步检查结果
|
||||
@ -533,20 +735,29 @@ test('kill the time', () => {
|
||||
})
|
||||
```
|
||||
|
||||
对于特殊情况,请使用 [jest.runOnlyPendingTimers()](https://jestjs.io/docs/en/timer-mocks#run-pending-timers)。
|
||||
> 对于特殊情况,请使用 [jest.runOnlyPendingTimers()](https://jestjs.io/docs/en/timer-mocks#run-pending-timers)。
|
||||
|
||||
**注意:** 您应该在测试用例中调用 `jest.useFakeTimers()` 以使用其他假计时器方法。
|
||||
|
||||
### 模拟 getters 和 setters
|
||||
### 模拟对象方法
|
||||
|
||||
```js
|
||||
const getTitle = jest.fn(() => 'pizza')
|
||||
const setTitle = jest.fn()
|
||||
const location = {}
|
||||
Object.defineProperty(location, 'title', {
|
||||
get: getTitle,
|
||||
set: setTitle,
|
||||
})
|
||||
const spy = jest.spyOn(console, 'log')
|
||||
.mockImplementation(() => {})
|
||||
|
||||
expect(console.log.mock.calls)
|
||||
.toEqual([['dope'], ['nope']])
|
||||
spy.mockRestore()
|
||||
```
|
||||
|
||||
```js
|
||||
const spy = jest.spyOn(ajax, 'request')
|
||||
.mockImplementation(
|
||||
() => Promise.resolve({success: true})
|
||||
)
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
spy.mockRestore()
|
||||
```
|
||||
|
||||
### 清除和恢复模拟
|
||||
@ -558,8 +769,10 @@ Object.defineProperty(location, 'title', {
|
||||
// 清除模拟使用日期
|
||||
// (fn.mock.calls、fn.mock.instances)
|
||||
fn.mockClear()
|
||||
|
||||
// 清除并删除任何模拟的返回值或实现
|
||||
fn.mockReset()
|
||||
|
||||
// 重置并恢复初始实现
|
||||
fn.mockRestore()
|
||||
```
|
||||
|
568
docs/lerna.md
Normal file
@ -0,0 +1,568 @@
|
||||
Lerna 备忘清单
|
||||
===
|
||||
|
||||
本备忘单旨在快速理解 [Lerna v6](https://github.com/lerna/lerna) 所涉及的主要概念,显示了它的常用命令使用清单。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
现代构建系统,用于管理和发布来自同一存储库的多个 JavaScript/TypeScript 包。
|
||||
|
||||
```bash
|
||||
$ npx lerna@latest init
|
||||
```
|
||||
|
||||
下面是示例目录结构
|
||||
|
||||
```shell {15}
|
||||
├── README.md
|
||||
├── remixapp # web 应用 (remixapp)
|
||||
│ ├── src
|
||||
│ └── package.json
|
||||
│
|
||||
├── packages
|
||||
│ ├── footer # 组件(@remixapp/footer)
|
||||
│ │ ├── src
|
||||
│ │ └── package.json
|
||||
│ │
|
||||
│ └── header # 组件(@remixapp/header)
|
||||
│ ├── src
|
||||
│ └── package.json
|
||||
│
|
||||
├── lerna.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### 引导程序 (Bootstrap)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
它在 `package.json` 中依赖于它们,如下所示:
|
||||
|
||||
```json {3,4}
|
||||
"dependencies": {
|
||||
// ....
|
||||
"@remixapp/header": "*",
|
||||
"@remixapp/footer": "*"
|
||||
}
|
||||
```
|
||||
|
||||
`remixapp` 应用程序导入`页眉`和`页脚`库,如下所示:
|
||||
|
||||
```jsx
|
||||
import { Header } from "header";
|
||||
import { Footer } from "footer";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<div>Content!</div>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### useWorkspaces
|
||||
|
||||
```json {3}
|
||||
{
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.0.0"
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
在 `lerna.json` 中配置 `useWorkspaces` 告诉 `Lerna` 将包链接过程委托给你的包管理器 (此功能由 npm、yarn 和 pnpm 支持)。
|
||||
|
||||
### 任务运行
|
||||
|
||||
```bash
|
||||
npx lerna run test --scope=header # 单个
|
||||
```
|
||||
|
||||
多个任务运行
|
||||
|
||||
```bash
|
||||
npx lerna run test --scope=header,footer
|
||||
```
|
||||
|
||||
忽略 `header`,`footer` 其它包中运行任务运行
|
||||
|
||||
```bash
|
||||
npx lerna run build --ignore=header,footer
|
||||
```
|
||||
|
||||
命令索引
|
||||
---
|
||||
|
||||
### run/exec 运行命令
|
||||
|
||||
```bash
|
||||
# 在所有包含它的包中运行 npm run my-script
|
||||
$ lerna run <script> -- [..args]
|
||||
$ lerna run test
|
||||
$ lerna run build
|
||||
|
||||
# 观看所有包并在更改时转换,流式前缀输出
|
||||
$ lerna run --parallel watch
|
||||
|
||||
# 在所有包中运行命令
|
||||
$ lerna exec -- <command> [..args]
|
||||
$ lerna exec -- rm -rf ./node_modules
|
||||
$ lerna exec -- protractor conf.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--npm-client <client>` [#](https://github.com/lerna/lerna/tree/main/commands/run#--npm-client-client) | 必须是知道如何运行 npm 生命周期脚本的可执行文件,默认值是 `npm`
|
||||
`--stream` [#](https://github.com/lerna/lerna/tree/main/commands/run#--stream) | 立即从子进程流式输出,以原始包名称为前缀
|
||||
`--parallel` [#](https://github.com/lerna/lerna/tree/main/commands/run#--parallel) | 类似于 `--stream` 但完全忽略并发和拓扑排序,立即在所有匹配的包中运行给定的命令或脚本,并带有前缀流输出
|
||||
`--no-bail` [#](https://github.com/lerna/lerna/tree/main/commands/run#--no-bail) | 默认情况下,如果任何脚本运行返回非零退出代码,`lerna run` 将退出并出现错误。传递 `--no-bail` 以禁用此行为
|
||||
`--no-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/run#--no-prefix) | 当输出为流式传输(`--stream` 或 `--parallel`)时禁用包名称前缀。当将结果传送到其他进程(例如编辑器插件)时,此选项很有用
|
||||
`--profile` [#](https://github.com/lerna/lerna/tree/main/commands/run#--profile) | 分析脚本执行并生成性能配置文件
|
||||
`--profile-location <location>` [#](https://github.com/lerna/lerna/tree/main/commands/run#--profile-location-location) | 您可以为性能配置文件输出提供自定义位置。提供的路径将相对于当前工作目录进行解析。
|
||||
`useNx=false` [#](https://github.com/lerna/lerna/tree/main/commands/run#usenxfalse) | 通过将 `useNx` 设置为 `false`,您可以使用 `lerna` 中的遗留任务运行实现 (`p-map` 和 `p-queue`),而不是使用由 [Nx](https://nx.dev) 提供支持的默认现代任务运行器实现。
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### publish 发布包
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
# 发布自上次发布以来已更改的软件包
|
||||
$ lerna publish
|
||||
# 显式发布在当前提交中标记的包
|
||||
$ lerna publish from-git
|
||||
# 显式发布注册表中不存在最新版本的软件包
|
||||
$ lerna publish from-package
|
||||
# 使用下一个语义预发布版本,例如
|
||||
$ lerna publish --canary
|
||||
# 1.0.0 => 1.0.1-alpha.0+${SHA}
|
||||
# 自上次提交以来更改的包
|
||||
# 随后的金丝雀发布将产生1.0.1-alpha.1+${SHA}等
|
||||
|
||||
$ lerna publish --canary --preid beta
|
||||
# 1.0.0 => 1.0.1-beta.0+${SHA}
|
||||
|
||||
# 以下是等价的:
|
||||
$ lerna publish --canary minor
|
||||
$ lerna publish --canary preminor
|
||||
# 1.0.0 => 1.1.0-alpha.0+${SHA}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--canary` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--canary) | 使用此标志运行时,以更精细的方式(每次提交)发布包
|
||||
`--contents <dir>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--contents-dir) | 要发布的子目录。 必须适用于所有包,并且必须包含 `package.json` 文件
|
||||
`--dist-tag <tag>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--dist-tag-tag) | 使用此标志运行时,将使用给定的 `npm dist-tag`(默认为 `latest`)发布到 `npm`
|
||||
`--git-head <sha>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--git-head-sha) | 打包 `tarball` 时将显式 `SHA` 设置为清单上的 `gitHead`,仅允许使用 `from-package` 位置
|
||||
`--graph-type <all\|dependencies>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--graph-type-alldependencies) | 设置在构建包图时使用哪种依赖项。默认值是依赖项,即仅包含包的 `package.json` 的依赖项部分中列出的包
|
||||
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ignore-scripts) | 传递时,此标志将在 `lerna` 发布期间禁用运行[生命周期脚本](https://github.com/lerna/lerna/tree/main/commands/publish#lifecycle-scripts)
|
||||
`--ignore-prepublish` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ignore-prepublish) | 传递时,此标志将禁用在 `lerna` 发布期间运行[已弃用](https://docs.npmjs.com/cli/v8/using-npm/scripts#prepare-and-prepublish)的[预发布脚本](https://github.com/lerna/lerna/tree/main/commands/publish#lifecycle-scripts)
|
||||
`--legacy-auth` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--legacy-auth) | 发布需要身份验证的包时,您正在使用仅使用旧版 `Base64` `用户名:密码` 的内部托管 NPM 注册表。这与 NPM 发布 `_auth` 标志相同
|
||||
`--no-git-reset` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-git-reset) | 默认情况下,`lerna publish` 确保对工作树的任何更改都已重置
|
||||
`--no-granular-pathspec` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-granular-pathspec) | 默认情况下,`lerna publish` 将尝试(如果启用)`git checkout` 仅在发布过程中临时修改的叶包清单
|
||||
`--verify-access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--verify-access) | 从历史上看,`lerna` 试图通过使用给定令牌执行一些抢占式 `npm API` 请求来快速解决授权/身份验证问题
|
||||
`--otp` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--otp) | 发布需要双重身份验证的包时,您可以使用 `--otp` 指定一次性密码
|
||||
`--preid` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--preid) | 与同名的 `lerna` 版本选项不同,该选项只适用于 `--canary` 版本计算
|
||||
`--pre-dist-tag <tag>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--pre-dist-tag-tag) | 与 `--dist-tag` 的工作方式相同,但仅适用于使用预发布版本发布的软件包
|
||||
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--registry-url) | 使用此标志运行时,转发的 `npm` 命令将为您的包使用指定的注册表
|
||||
`--tag-version-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--tag-version-prefix) | 此选项允许提供自定义前缀而不是默认前缀:`v`
|
||||
`--temp-tag` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--temp-tag) | 传递时,此标志将更改默认发布过程,首先将所有更改的包发布到临时 `dist-tag(lerna-temp)`,然后将新版本移动到 `--dist-tag` 配置的 `dist-tag` (默认`latest`)
|
||||
`--yes` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--yes) | 使用此标志运行时,`lerna publish` 将跳过所有确认提示
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
#### 不推荐使用的选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--no-verify-access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--no-verify-access) | 旧的抢先访问验证现在默认关闭,因此不需要 `--no-verify-access`
|
||||
`--skip-npm` [#](https://github.com/lerna/lerna/tree/main/commands/publish#--skip-npm) | 直接调用 [lerna version](#version-修改版本号)
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
#### 每个包中的配置
|
||||
|
||||
```json
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "http://my-registry.com",
|
||||
"tag": "flippin-sweet",
|
||||
"directory": "dist"
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`access` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigaccess) | 要发布具有范围的包(例如,`@mycompany/rocks`)
|
||||
`registry` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigregistry) | 通过设置注册表来自定义每个包的注册表
|
||||
`tag` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigtag) | 您可以通过设置标签来自定义每个包的 `dist-tag`
|
||||
`directory` [#](https://github.com/lerna/lerna/tree/main/commands/publish#publishconfigtag) | 这个 _非标准_ 字段允许您像 `--contents` 一样自定义发布的子目录,但基于每个包
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### version 修改版本号
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
$ lerna version 1.0.1 # 明确的
|
||||
$ lerna version patch # semver 关键字
|
||||
$ lerna version # 从提示中选择
|
||||
|
||||
$ lerna version [major | minor | ...]
|
||||
# 使用下一个语义版本值
|
||||
# 这会跳过“为...选择新版本”提示
|
||||
# 强制所有包版本化
|
||||
$ lerna version --force-publish
|
||||
$ lerna version -m "chore(doc): publish %s"
|
||||
# 提交消息 = "chore(doc): publish v1.0.0"
|
||||
$ lerna version -m "chore(doc): publish %v"
|
||||
# 提交消息 = "chore(doc): publish 1.0.0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- `major` 重大的
|
||||
- `minor` 次要的
|
||||
- `patch` 修补
|
||||
- `premajor` 主要的
|
||||
- `preminor` 初级
|
||||
- `prepatch` 预补丁
|
||||
- `prerelease` 预发行
|
||||
<!--rehype:className=cols-2-->
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--allow-branch <glob>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--allow-branch-glob) | 与启用 `lerna version` 的 `git` 分支匹配的 `glob` 白名单
|
||||
`--amend` [#](https://github.com/lerna/lerna/tree/main/commands/version#--amend) | 使用此标志运行时,`lerna version` 将在当前提交上执行所有更改,而不是添加新的
|
||||
`--changelog-preset` [#](https://github.com/lerna/lerna/tree/main/commands/version#--changelog-preset) | 默认情况下,更改日志预设设置为 [angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular#angular-convention)
|
||||
`--conventional-commits` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-commits) | 使用常规提交规范来确定[版本 bump](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-recommended-bump) 并生成 CHANGELOG.md 文件
|
||||
`--conventional-graduate` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate) | 将使用 `*` 对指定的包(逗号分隔)或所有包进行分级
|
||||
`--conventional-prerelease` [#](https://github.com/lerna/lerna/tree/main/commands/version#--conventional-prerelease) | 预发布版本发布指定的包
|
||||
`--create-release <type>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--create-release-type) | 根据更改的包创建正式的 `GitHub` 或 `GitLab` 版本
|
||||
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/version#--exact) | 在更新的包中精确指定更新的依赖项(没有标点符号),而不是与 [semver](./semver.md) 兼容(使用`^`)
|
||||
`--force-publish` [#](https://github.com/lerna/lerna/tree/main/commands/version#--force-publish) | 强制发布指定的包
|
||||
`--git-remote <name>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--git-remote-name) | 把 `git` 更改推送到指定的远程位置,而不是`origin`
|
||||
`--ignore-changes` [#](https://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes) | 检测更改的包时忽略与 `glob` 匹配的文件中的更改
|
||||
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/version#--ignore-scripts) | 禁用在 `lerna version` 期间运行的生命周期脚本
|
||||
`--include-merged-tags` [#](https://github.com/lerna/lerna/tree/main/commands/version#--include-merged-tags) | 在检测到更改的包时包括来自合并分支的标签
|
||||
`--message <msg>` [#](https://github.com/lerna/lerna/tree/main/commands/version#--message-msg) | 此选项别名为 `-m` 以与 `git commit` 进行奇偶校验
|
||||
`--no-changelog` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-changelog) | 使用常规提交时,不要生成任何 CHANGELOG.md 文件
|
||||
`--no-commit-hooks` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-commit-hooks) | 允许 `git commit hooks` 在提交版本更改时运行。通过 `--no-commit-hooks` 禁用此行为
|
||||
`--no-git-tag-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-git-tag-version) | 将提交对 `package.json` 文件的更改并标记发布。通过 `--no-git-tag-version` 禁用该行为
|
||||
`--no-granular-pathspec` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-granular-pathspec) | 仅添加在版本控制过程中更改的叶包清单(可能还有变更日志)。这产生了 `git add --packages/*/package.json` 的等价物,但针对更改的内容量身定制
|
||||
`--no-private` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-private) | 在选择版本、提交和标记版本时包含私有包。通过 `--no-private` 禁用此行为
|
||||
`--no-push` [#](https://github.com/lerna/lerna/tree/main/commands/version#--no-push) | 将已提交和标记的更改推送到配置的 `git remote`。通过 `--no-push` 禁用此行为
|
||||
`--preid` [#](https://github.com/lerna/lerna/tree/main/commands/version#--preid) | 使用此标志运行时,lerna 版本将使用指定的[预发布标识符](https://semver.org/#spec-item-9)增加 `premajor`、`preminor`、`prepatch` 或 `prerelease` [semver](./semver.md) bumps
|
||||
`--sign-git-commit` [#](https://github.com/lerna/lerna/tree/main/commands/version#--sign-git-commit) | 此选项类似于同名的 npm 版本选项
|
||||
`--sign-git-tag` [#](https://github.com/lerna/lerna/tree/main/commands/version#--sign-git-tag) | 此选项类似于同名的 `npm` 版本选项
|
||||
`--force-git-tag` [#](https://github.com/lerna/lerna/tree/main/commands/version#--force-git-tag) | 此选项替换任何现有标记而不是失败
|
||||
`--tag-version-prefix` [#](https://github.com/lerna/lerna/tree/main/commands/version#--tag-version-prefix) | 此选项允许提供自定义前缀而不是默认前缀:`v`
|
||||
`--yes` [#](https://github.com/lerna/lerna/tree/main/commands/version#--yes) | 使用此标志运行时,`lerna` 版本将跳过所有确认提示
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
#### 不推荐使用的选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--cd-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--cd-version) | 将 `semver` 关键字传递给 [bump](https://github.com/lerna/lerna/tree/main/commands/version#semver-bump) 位置
|
||||
`--repo-version` [#](https://github.com/lerna/lerna/tree/main/commands/version#--repo-version) | 将明确的版本号传递给 [bump](https://github.com/lerna/lerna/tree/main/commands/version#semver-bump) 位置
|
||||
`--skip-git` [#](https://github.com/lerna/lerna/tree/main/commands/version#--skip-git) | 请改用 `--no-git-tag-version` 和 `--no-push`
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### bootstrap
|
||||
|
||||
将本地包`链接`在一起,并`安装`其余的包依赖项
|
||||
|
||||
```bash
|
||||
$ lerna bootstrap -- --production \
|
||||
--no-optional
|
||||
$ lerna bootstrap --hoist
|
||||
```
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--hoist [glob]` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--strict) | 在 `repo` 根目录安装与 `glob` 匹配的外部依赖项,以便它们可用于所有包
|
||||
`--strict` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--nohoist-glob) | 与提升 _(hoist)_ 一起使用时,会在发出版本警告后抛出错误并停止引导
|
||||
`--nohoist [glob]` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--nohoist-glob) | 不要在 `repo` 根目录安装与 `glob` 匹配的外部依赖项。这可用于选择不提升某些依赖项
|
||||
`--ignore` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore) | 当与 `bootstrap` 命令一起使用时,还可以在 `lerna` 中设置 `--ignore` 标志
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
#### 选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--ignore-prepublish` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore-prepublish) | 跳过默认在引导程序包中运行的预发布生命周期脚本
|
||||
`--ignore-scripts` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--ignore-scripts) | 跳过通常在引导程序包中运行(准备等)的任何生命周期脚本
|
||||
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--registry-url) | 指定 npm 包的仓库地址
|
||||
`--npm-client <client>` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--npm-client-client) | 必须是知道如何安装 `npm` 包依赖项的可执行文件
|
||||
`--use-workspaces` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--use-workspaces) | 启用与 `Yarn Workspaces` 的集成(从 `yarn@0.27+` 开始可用)
|
||||
`--no-ci` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--no-ci) | 在 `CI` 环境中调用 `npm ci` 而不是 `npm install`
|
||||
`--force-local` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--force-local) | 此标志会导致引导命令始终对本地依赖项进行符号链接,而不管匹配的版本范围如何
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
|
||||
### info 本地环境信息
|
||||
|
||||
```bash
|
||||
$ lerna info
|
||||
|
||||
lerna notice cli v6.0.0
|
||||
Environment info:
|
||||
|
||||
System(系统):
|
||||
OS: macOS 12.2
|
||||
CPU: (8) x64 Apple M1
|
||||
Binaries(二进制文件):
|
||||
Node: 16.17.0 - /usr/local/bin/node
|
||||
Yarn: 1.22.10 - /usr/local/bin/yarn
|
||||
npm: 8.5.0 - /usr/local/bin/npm
|
||||
Utilities(实用程序):
|
||||
Git: 2.33.0 - /opt/homebrew/bin/git
|
||||
npmPackages:
|
||||
lerna: ^6.0.0 => 6.0.0
|
||||
```
|
||||
|
||||
### 过滤选项
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```bash
|
||||
$ lerna exec --scope my-component -- ls -la
|
||||
$ lerna run --scope toolbar-* test
|
||||
$ lerna run --scope package-1 --scope *-2 lint
|
||||
|
||||
$ lerna exec --ignore package-{1,2,5} -- ls -la
|
||||
$ lerna run --ignore package-1 test
|
||||
$ lerna run --ignore package-@(1|2) --ignore package-3 lint
|
||||
|
||||
# 列出自最新标签以来已更改的包的内容
|
||||
$ lerna exec --since -- ls -la
|
||||
# 对自 main 以来发生更改的所有包运行测试
|
||||
$ lerna run test --since main
|
||||
# 列出自 some-branch 以来发生变化的所有包
|
||||
$ lerna ls --since some-branch
|
||||
|
||||
# my-component 及其所有依赖项将被引导
|
||||
$ lerna bootstrap --scope my-component --include-dependencies
|
||||
|
||||
$ lerna bootstrap --scope "package-*" --ignore "package-util-*" --include-dependencies
|
||||
# 所有匹配 “package-util-*” 的包都将被忽略,除非它们是
|
||||
# 依赖于名称与 “package-*” 匹配的包
|
||||
```
|
||||
|
||||
#### 选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--scope <glob>` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--scope-glob) | 仅包括名称与给定 `glob` 匹配的包
|
||||
`--ignore <glob>` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--ignore-glob) | 排除名称与给定 `glob` 匹配的包
|
||||
`--no-private` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--no-private) | 排除私有包
|
||||
`--since [ref]` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--since-ref) | 仅包括自指定 `ref` 以来已更改的包
|
||||
`--exclude-dependents` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--exclude-dependents) | 使用 `--since` 运行命令时排除所有传递依赖项,覆盖默认的“changed”算法
|
||||
`--include-dependents` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-dependents) | 无论 `--scope`、`--ignore` 或 `--since` 是什么,在运行命令时都包括所有传递依赖项
|
||||
`--include-dependencies` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-dependencies) | 无论 `--scope`、`--ignore` 或 `--since` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--since-ref) 是什么,在运行命令时都包括所有传递依赖项
|
||||
`--include-merged-tags` [#](https://github.com/lerna/lerna/tree/main/core/filter-options#--include-merged-tags) | 使用 `--since` 运行命令时包括来自合并分支的标签
|
||||
|
||||
### list
|
||||
|
||||
列出本地程序包,也尊重所有可用的[过滤选项](#过滤选项)
|
||||
|
||||
```bash
|
||||
# 与 lerna list 相同,它本身类似于 ls 命令
|
||||
lerna ls
|
||||
# 相当于 lerna ls -l,显示长输出
|
||||
lerna ll
|
||||
# 相当于 lerna ls -la,显示所有包(包括私有包)
|
||||
lerna la
|
||||
```
|
||||
|
||||
#### 选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--json` | 显示为 JSON [#](https://github.com/lerna/lerna/tree/main/commands/publish#--json)
|
||||
`--ndjson` | 换行符分隔 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--ndjson)
|
||||
`-a,--all` | 所有包 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--all)
|
||||
`-l,--long` | 显示扩展信息 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--long)
|
||||
`-p,--parseable` | 显示可解析的输出 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--parseable)
|
||||
`--toposort` | 按拓扑排序 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--toposort)
|
||||
`--graph` | JSON 格式邻接依赖关系图 [#](https://github.com/lerna/lerna/tree/main/commands/publish#--graph)
|
||||
|
||||
### changed
|
||||
|
||||
列出自上次标记版本以来已更改的本地软件包
|
||||
|
||||
- `lerna changed` 支持 `lerna ls` 支持的所有[选项](#选项-1)
|
||||
- 与 `lerna ls` 不同的是不支持过滤器选项
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
`lerna changed` 支持 `lerna version` 的以下选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--conventional-graduate` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate)
|
||||
`--force-publish` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--force-publish)
|
||||
`--ignore-changes` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes)
|
||||
`--include-merged-tags` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--include-merged-tags)
|
||||
|
||||
### init
|
||||
|
||||
创建新的 Lerna 仓库或将现有仓库升级到当前版本 Lerna
|
||||
|
||||
- 如果 `lerna` 不存在,请将其添加到 `package.json` 中的 `devDependency`
|
||||
- 创建一个 `lerna.json` 配置文件来存储版本号
|
||||
- 如果不存在 `.gitignore`,则生成一个忽略文件
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
----
|
||||
|
||||
```shell
|
||||
$ lerna init --independent
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--independent` [#](https://github.com/lerna/lerna/tree/main/commands/init#--independent) | 使用独立版本控制模式 [#](https://github.com/lerna/lerna/tree/main/commands/init#--independent)
|
||||
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/init#--exact) | 添加或更新 `lerna` 的本地版本时将使用插入符范围 [#](https://github.com/lerna/lerna/tree/main/commands/init#--exact)
|
||||
|
||||
它将配置 `lerna.json` 以强制所有后续执行完全匹配
|
||||
|
||||
```js
|
||||
{
|
||||
"command": {
|
||||
"init": {
|
||||
"exact": true
|
||||
}
|
||||
},
|
||||
"version": "0.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
### import
|
||||
|
||||
将一个包导入到带有提交历史的 `monorepo`
|
||||
|
||||
```bash
|
||||
# 开始使用 Lerna
|
||||
$ git init lerna-repo && cd lerna-repo
|
||||
$ npx lerna init
|
||||
$ npm install
|
||||
# 添加提交
|
||||
$ git add .
|
||||
# 如果没有提交,导入命令将失败
|
||||
$ git commit -m "Initial lerna commit"
|
||||
# 导入其他存储库
|
||||
$ npx lerna import <外部存储库的路径>
|
||||
$ npx lerna import ~/Product --flatten
|
||||
```
|
||||
|
||||
选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--flatten` [#](https://github.com/lerna/lerna/tree/main/commands/import#--flatten) | 当导入具有冲突的合并提交的存储库时,导入命令将无法尝试应用所有提交
|
||||
`--dest` [#](https://github.com/lerna/lerna/tree/main/commands/import#--dest) | 导入仓库时,可以通过 `lerna.json` 中列出的目录来指定目标目录
|
||||
`--preserve-commit` [#](https://github.com/lerna/lerna/tree/main/commands/import#--preserve-commit) | 每个 git 提交都有一个作者和一个提交者
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### add
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
将依赖项添加到匹配的包
|
||||
|
||||
```shell
|
||||
$ lerna add <package>[@version] \
|
||||
[--dev] [--exact] [--peer]
|
||||
```
|
||||
|
||||
选项
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--dev` [#](https://github.com/lerna/lerna/tree/main/commands/add#--dev) | 将新包添加到 `devDependencies`
|
||||
`--exact` [#](https://github.com/lerna/lerna/tree/main/commands/add#--exact) | 添加具有精确版本(例如 `1.0.1`)而不是默认 `^` semver 范围(例如 `^1.0.1`)的新包
|
||||
`--peer` [#](https://github.com/lerna/lerna/tree/main/commands/add#--peer) | 将新包添加到 `peerDependencies`
|
||||
`--registry <url>` [#](https://github.com/lerna/lerna/tree/main/commands/add#--registry-url) | 使用自定义注册表安装目标包
|
||||
`--no-bootstrap` [#](https://github.com/lerna/lerna/tree/main/commands/add#--no-bootstrap) | 跳过链式 `lerna bootstrap`
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
实例
|
||||
|
||||
```bash
|
||||
# 将 mod-1 包添加到“prefix-”前缀文件夹中的包中
|
||||
$ lerna add mod-1 packages/prefix-*
|
||||
# 将 mod-1 安装到mod-2
|
||||
$ lerna add mod-1 --scope=mod-2
|
||||
# 在 devDependencies 中安装 mod-1 到 mod-2
|
||||
$ lerna add mod-1 --scope=mod-2 --dev
|
||||
# 在 peerDependencies 中安装 mod-1 到 mod-2
|
||||
$ lerna add mod-1 --scope=mod-2 --peer
|
||||
# 在除 mod-1 之外的所有模块中安装 mod-1
|
||||
$ lerna add mod-1
|
||||
# 在所有模块中安装 babel-core
|
||||
$ lerna add babel-core
|
||||
```
|
||||
|
||||
### diff
|
||||
|
||||
比较自上次发布以来的所有包或单个包
|
||||
|
||||
```bash
|
||||
$ lerna diff [package]
|
||||
$ lerna diff
|
||||
$ lerna diff package-name # 区分一个特定的包
|
||||
```
|
||||
|
||||
类似于 `lerna changed`,此命令运行 `git diff`
|
||||
|
||||
|
||||
### clean
|
||||
|
||||
从所有包中删除 `node_modules` 目录
|
||||
|
||||
```bash
|
||||
$ lerna clean
|
||||
```
|
||||
|
||||
接受所有[过滤选项](#过滤选项)。`lerna clean` 不会从根 `node_modules` 目录中删除模块,即使您启用了 `--hoist` 选项
|
||||
|
||||
### add-caching
|
||||
|
||||
运行设置基本缓存选项的向导
|
||||
|
||||
```bash
|
||||
$ lerna add-caching
|
||||
```
|
||||
|
||||
### link
|
||||
|
||||
将所有相互依赖的包符号链接在一起
|
||||
|
||||
```bash
|
||||
$ lerna link
|
||||
```
|
||||
|
||||
[`--force-local`](https://github.com/lerna/lerna/tree/main/commands/link#--force-local) 设置会导致链接命令始终对本地依赖项进行符号链接
|
||||
|
||||
### repair
|
||||
|
||||
更新配置文件以匹配当前安装的 lerna 版本
|
||||
|
||||
```bash
|
||||
$ npm i lerna@latest
|
||||
$ lerna repair
|
||||
```
|
||||
|
||||
[`lerna repair`](https://github.com/lerna/lerna/tree/main/core/lerna/commands/repair#usage) 在升级后最有用,可确保应用新版本 lerna 的任何配置文件更改
|
@ -42,7 +42,7 @@ Header 2
|
||||
```
|
||||
|
||||
### 无序列表
|
||||
<!--rehype:wrap-style=grid-row: span 2/span 2;-->
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```markdown
|
||||
* Item 1
|
||||
@ -64,7 +64,7 @@ Header 2
|
||||
+ Item 1
|
||||
+ Item 2
|
||||
```
|
||||
或者
|
||||
或者**任务**列表
|
||||
|
||||
```markdown
|
||||
- [ ] Checkbox off
|
||||
@ -80,41 +80,27 @@ Header 2
|
||||
b. item 3b
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 链接
|
||||
|
||||
```markdown
|
||||
[link](http://google.com)
|
||||
```
|
||||
|
||||
```markdown
|
||||
[link][google]
|
||||
[google]: http://google.com
|
||||
```
|
||||
|
||||
```markdown
|
||||
<http://google.com>
|
||||
```
|
||||
|
||||
### 强调
|
||||
|
||||
```markdown
|
||||
*斜体*
|
||||
_斜体_
|
||||
```
|
||||
*斜体* _斜体_ **粗体** __粗体__
|
||||
|
||||
```markdown
|
||||
**粗体**
|
||||
__粗体__
|
||||
```
|
||||
|
||||
```markdown
|
||||
`内联代码`
|
||||
~~删除~~
|
||||
`内联代码` ~~删除~~
|
||||
```
|
||||
|
||||
### 水平线
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
连字符
|
||||
|
||||
@ -134,9 +120,15 @@ __粗体__
|
||||
___
|
||||
```
|
||||
|
||||
### 换行
|
||||
|
||||
```markdown
|
||||
在当前行的结尾加 2 个空格··
|
||||
这行就会新起一行\
|
||||
反斜杠也可以换行
|
||||
```
|
||||
|
||||
|
||||
尾部添加两个空格,或者添加 `\` 反斜杠
|
||||
|
||||
### 代码
|
||||
|
||||
@ -165,33 +157,49 @@ console.log("This is a block code")
|
||||
```
|
||||
|
||||
### 表格
|
||||
<!--rehype:wrap-style=grid-column: span 2/span 2;-->
|
||||
|
||||
```markdown
|
||||
| 左栏 | 中间栏 | 右栏 |
|
||||
|:------------|:-------------:|-------------:|
|
||||
| 单元格 1 | 居中 | $1600 |
|
||||
| 单元格 2 | 单元格 3 | $12 |
|
||||
| 左栏 | 中间栏 | 右栏 |
|
||||
| ----------| ------------ | --------- |
|
||||
| 单元格 1 | 居中 | $1600 |
|
||||
| 单元格 2 | 单元格 3 | $12 |
|
||||
```
|
||||
|
||||
简单的风格
|
||||
|
||||
```markdown
|
||||
左栏 | 中间栏 | 右栏
|
||||
:----------:|:-------------:|:-----------:
|
||||
单元格 1 | 居中 | $1600
|
||||
单元格 2 | 单元格 3 | $12
|
||||
左栏 | 中间栏 | 右栏
|
||||
:-------: | :-------:|:-------:
|
||||
单元格 1 | 居中 | $1600
|
||||
单元格 2 | 单元格 3 | $12
|
||||
```
|
||||
|
||||
Markdown 表格生成器:[tableconvert.com](https://tableconvert.com/)
|
||||
|
||||
### 图片
|
||||
<!--rehype:wrap-style=grid-column: span 2/span 2;-->
|
||||
### 脚注 (Footnotes)
|
||||
|
||||
```markdown
|
||||

|
||||
这是一个简单的脚注[^1]。
|
||||
|
||||

|
||||
一个脚注也可以有多行[^2]。
|
||||
|
||||
你也可以使用文字,更贴合你的写作风格[^note]。
|
||||
|
||||
[^1]:我的参考。
|
||||
[^2]:每个新行都应以 2 个空格为前缀。
|
||||
这允许你有一个多行的脚注。
|
||||
[^note]:
|
||||
推荐使用数字命名脚注,但文本更容易识别和链接。
|
||||
脚注使用了不同的语法,使用 4 个空格作为新行。
|
||||
```
|
||||
|
||||
### 图片
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```markdown
|
||||

|
||||
|
||||

|
||||
```
|
||||
|
||||
#### 带链接的图片
|
||||
@ -199,19 +207,19 @@ Markdown 表格生成器:[tableconvert.com](https://tableconvert.com/)
|
||||
```markdown
|
||||
[](https://github.com/)
|
||||
|
||||
[](link_url)
|
||||
[](link_url)
|
||||
```
|
||||
|
||||
#### 参考风格
|
||||
|
||||
```markdown
|
||||
![alt text][logo]
|
||||
![替代文字][logo]
|
||||
|
||||
[logo]: /images/logo.png "Logo Title"
|
||||
```
|
||||
|
||||
|
||||
### 反斜杠转义
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| 字符 | 转义 | 描述 |
|
||||
|------------|--------|-------------|
|
||||
@ -226,4 +234,16 @@ Markdown 表格生成器:[tableconvert.com](https://tableconvert.com/)
|
||||
| \+ | \\\+ | plus sign 加号 |
|
||||
| \- | \\\- | minus sign \(hyphen\) 减号(连字符) |
|
||||
| \. | \\\. | dot 点 |
|
||||
| \! | \\\! | exclamation mark 感叹号 |
|
||||
| \! | \\\! | exclamation mark 感叹号 |
|
||||
|
||||
### 行内 HTML 元素
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```html
|
||||
目前只支持部分段内 HTML 元素效果,包括 <kdb>, <b>, <i>, <em>, <sup>, <sub>, <br>
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [GitHub 风格的 Markdown 规范](https://github.github.com/gfm/) _(github.com)_
|
870
docs/nginx.md
Normal file
@ -0,0 +1,870 @@
|
||||
NGINX 备忘清单
|
||||
===
|
||||
|
||||
这个 nginx 快速参考备忘单显示了它的常用命和配置使用清单。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 服务管理
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
sudo systemctl status nginx # nginx当前状态
|
||||
sudo systemctl reload nginx # 重新加载 nginx
|
||||
sudo systemctl restart nginx # 重启nginx
|
||||
|
||||
sudo nginx -t # 检查语法
|
||||
nginx # 启动
|
||||
nginx -s reload # 重启
|
||||
nginx -s stop # 关闭进程
|
||||
nginx -s quit # 平滑关闭nginx
|
||||
nginx -V # 查看nginx的安装状态,
|
||||
```
|
||||
|
||||
### Docker 安装
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx
|
||||
```
|
||||
|
||||
### 简单代理
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
```
|
||||
|
||||
### 全局变量
|
||||
<!--rehype:wrap-class=col-span-2 row-span-4-->
|
||||
|
||||
| 变量 | 说明
|
||||
:- | :-
|
||||
`$args` | 这个变量等于请求行中的参数,同 `$query_string`
|
||||
`$remote_port` | 客户端的端口
|
||||
`$content_length` | 请求头中的 `Content-length` 字段
|
||||
`$remote_user` | 已经经过 `Auth Basic Module` 验证的用户名
|
||||
`$content_type` | 请求头中的 `Content-Type` 字段
|
||||
`$request_filename` | 当前请求的文件路径,由 `root` 或alias指令与URI请求生成
|
||||
`$document_root` | 当前请求在 `root` 指令中指定的值
|
||||
`$scheme` | HTTP方法(如http,https)
|
||||
`$host` | 请求主机头字段,否则为服务器名称
|
||||
`$hostname` | 主机名
|
||||
`$http_user_agent` | 客户端`agent`信息
|
||||
`$http_cookie` | 客户端`cookie`信息
|
||||
`$server_protocol` | 请求使用的协议,通常是`HTTP/1.0`或`HTTP/1.1`
|
||||
`$server_addr` | 服务器地址,在完成一次系统调用后可以确定这个值
|
||||
`$server_name` | 服务器名称
|
||||
`$server_port` | 请求到达服务器的端口号
|
||||
`$limit_rate` | 这个变量可以限制连接速率
|
||||
`$request_method` | 客户端请求的动作,如 GET/POST
|
||||
`$request_uri` | 包含请求参数的原始URI,不包含主机名,如:`/foo/bar.php?arg=baz`
|
||||
`$remote_addr` | 客户端的IP地址
|
||||
`$uri` | 不带请求参数的当前URI,`$uri`不包含主机名,如 `/foo/bar.html`
|
||||
`$document_uri` | 与 `$uri` 相同
|
||||
`$nginx_version` | `nginx` 版本
|
||||
|
||||
更多全局变量[查看官方文档](https://nginx.org/en/docs/varindex.html)
|
||||
|
||||
### 监听端口
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80; # 标准 HTTP 协议
|
||||
listen 443 ssl; # 标准 HTTPS 协议
|
||||
listen 443 ssl http2; # 对于 http2
|
||||
listen [::]:80; # 使用 IPv6 在 80 上收听
|
||||
# 仅收听使用 IPv6
|
||||
listen [::]:80 ipv6only=on;
|
||||
}
|
||||
```
|
||||
|
||||
### 域名 (server_name)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
# 监听 example.com
|
||||
server_name example.com;
|
||||
# 监听多个域
|
||||
server_name example.com www.example.com;
|
||||
# 监听所有子域
|
||||
server_name *.example.com;
|
||||
# 监听所有顶级域
|
||||
server_name example.*;
|
||||
# 监听未指定的主机名(监听 IP 地址本身)
|
||||
server_name "";
|
||||
}
|
||||
```
|
||||
|
||||
### 负载均衡(简单实例)
|
||||
|
||||
```nginx
|
||||
upstream node_js {
|
||||
server 0.0.0.0:3000;
|
||||
server 0.0.0.0:4000;
|
||||
server 127.155.142.421;
|
||||
}
|
||||
```
|
||||
|
||||
### 负载均衡(权重)
|
||||
|
||||
```nginx
|
||||
upstream test {
|
||||
server localhost:8080 weight=9;
|
||||
server localhost:8081 weight=1;
|
||||
}
|
||||
```
|
||||
|
||||
### upstream ip_hash
|
||||
|
||||
```nginx {2}
|
||||
upstream test {
|
||||
ip_hash;
|
||||
server localhost:8080;
|
||||
server localhost:8081;
|
||||
}
|
||||
```
|
||||
|
||||
解决负载均衡 `session` 的问题
|
||||
|
||||
### upstream fair
|
||||
|
||||
```nginx {2}
|
||||
upstream backend {
|
||||
fair;
|
||||
server localhost:8080;
|
||||
server localhost:8081;
|
||||
}
|
||||
```
|
||||
|
||||
响应时间短的优先分配
|
||||
|
||||
### server 可选参数
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`weight` | 访问权重数值越高,收到请求越多
|
||||
`fail_timeout` | 指定的时间内必须提供响应
|
||||
`max_fails` | 尝试失败服务器连接的最大次数
|
||||
`down` | 标记一个服务器不再接受任何请求
|
||||
`backup` | 有服务器宕机,标记的机器接收请求
|
||||
|
||||
配置示例
|
||||
|
||||
```nginx
|
||||
upstream test {
|
||||
server 127.0.0.1:83 weight=9; # 权重
|
||||
server 127.0.0.1:83 weight=1; # 权重
|
||||
# 失败超时时间
|
||||
server 127.0.0.1:83 max_fails=3;
|
||||
server 127.0.0.1:83 weight=3 down;
|
||||
}
|
||||
```
|
||||
|
||||
### upstream url_hash
|
||||
|
||||
```nginx {2,3}
|
||||
upstream backend {
|
||||
hash $request_uri;
|
||||
hash_method crc32;
|
||||
server localhost:8080;
|
||||
server localhost:8081;
|
||||
}
|
||||
```
|
||||
|
||||
按访问url的hash结果来分配请求
|
||||
|
||||
### upstream keepalive
|
||||
|
||||
```nginx {4}
|
||||
upstream memcached_backend {
|
||||
server 127.0.0.1:11211;
|
||||
server 10.0.0.2:11211;
|
||||
keepalive 32;
|
||||
}
|
||||
```
|
||||
|
||||
激活缓存以连接到上游服务器
|
||||
|
||||
### 子文件夹中的代理
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx {1,2}
|
||||
location /folder/ { # / 很重要!
|
||||
proxy_pass http://127.0.0.1:3000/; # / 很重要!
|
||||
proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
```
|
||||
|
||||
### 反向代理
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 基础
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://0.0.0.0:3000;
|
||||
# 其中 0.0.0.0:3000 是绑定在
|
||||
# 0.0.0.0端口3000 列表上的 Node.js 服务器
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 基础 + (upstream)
|
||||
|
||||
```nginx
|
||||
upstream node_js {
|
||||
server 0.0.0.0:3000;
|
||||
# 其中 0.0.0.0:3000 是绑定在
|
||||
# 0.0.0.0端口3000 列表上的 Node.js 服务器
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://node_js;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 升级连接(适用于支持 WebSockets 的应用程序)
|
||||
|
||||
```nginx
|
||||
upstream node_js {
|
||||
server 0.0.0.0:3000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://node_js;
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
适用于 Node.js、Streamlit、Jupyter 等
|
||||
|
||||
### 静态资源(传统 Web 服务器)
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
root /path/to/website;
|
||||
# root /www/data/ 示例,如果里面没有'root',它将寻找 /www/data/index.html
|
||||
location / {
|
||||
}
|
||||
location /images/ { # 如果里面没有“root”,它将寻找 /www/data/images/index.html
|
||||
}
|
||||
location /videos/ { # 由于里面有“root”,它会寻找 /www/media/videos/index.html
|
||||
root /www/media;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### HTTPS 协议
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
大多数 SSL 选项取决于您的应用程序做什么或需要什么
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name example.com;
|
||||
ssl on;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/privkey.pem;
|
||||
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_trusted_certificate /path/to/fullchain.pem;
|
||||
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
add_header Strict-Transport-Security max-age=15768000;
|
||||
}
|
||||
```
|
||||
|
||||
您可以使用 Let's Encrypt 轻松保护您的网站/应用程序。去 [lets-encrypt](https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx.html) 获取更多信息
|
||||
|
||||
|
||||
### 重定向(301永久)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
将 www.example.com 重定向到 example.com
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.example.com;
|
||||
return 301 http://example.com$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
将 http 重定向到 https
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
return 301 https://example.com$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
### 重定向(302临时)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com;
|
||||
return 302 http://otherdomain.com;
|
||||
}
|
||||
```
|
||||
|
||||
### 永久重定向到 HTTPS 安全域
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
### 重定向参数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`permanent` | 永久性重定向。日志中的状态码为 `301`
|
||||
`redirect` | 临时重定向。日志中的状态码为 `302`
|
||||
|
||||
### HTTP 请求端真实的IP
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
示例
|
||||
----
|
||||
<!--rehype:body-class=cols-6-->
|
||||
|
||||
### websocket 的代理 keepalive
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```nginx
|
||||
# Upstreams
|
||||
upstream backend {
|
||||
server 127.0.0.1:3000;
|
||||
keepalive 5;
|
||||
}
|
||||
# HTTP Server
|
||||
server {
|
||||
server_name your_hostname.com;
|
||||
error_log /var/log/nginx/rocketchat.access.log;
|
||||
location / {
|
||||
proxy_pass http://backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forward-Proto http;
|
||||
proxy_set_header X-Nginx-Proxy true;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### Apache 的反向代理
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name domain.tld;
|
||||
|
||||
access_log /log/domain.tld.access.log;
|
||||
error_log /log/domain.tld.error.log;
|
||||
root /var/www/domain.tld/htdocs;
|
||||
|
||||
# 将请求传递给 Apache 后端
|
||||
location / {
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
# 使用后备处理静态文件
|
||||
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|zip|webm|mp3|aac|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp)$ {
|
||||
add_header "Access-Control-Allow-Origin" "*";
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
expires max;
|
||||
try_files $uri @fallback;
|
||||
}
|
||||
# 如果找不到文件,则回退以将请求传递给 Apache
|
||||
location @fallback {
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### Gitlab 的反向代理
|
||||
<!--rehype:wrap-class=col-span-4 row-span-3-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
#侦听的80端口
|
||||
listen 80;
|
||||
server_name git.example.cn;
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
# 以下是一些反向代理的配置可删除
|
||||
proxy_redirect off;
|
||||
# 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
|
||||
proxy_set_header Host $host;
|
||||
client_max_body_size 10m; # 允许客户端请求的最大单文件字节数
|
||||
client_body_buffer_size 128k; # 缓冲区代理缓冲用户端请求的最大字节数
|
||||
proxy_connect_timeout 300; # nginx跟后端服务器连接超时时间(代理连接超时)
|
||||
proxy_send_timeout 300; # 后端服务器数据回传时间(代理发送超时)
|
||||
proxy_read_timeout 300; # 连接成功后,后端服务器响应时间(代理接收超时)
|
||||
# 设置代理服务器(nginx)保存用户头信息的缓冲区大小
|
||||
proxy_buffer_size 4k;
|
||||
# proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
|
||||
proxy_buffers 4 32k;
|
||||
# 高负荷下缓冲大小(proxy_buffers*2)
|
||||
proxy_busy_buffers_size 64k;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 重定向整个网站
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name old-site.com;
|
||||
return 301 $scheme://new-site.com$request_uri;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 重定向单页
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
location = /oldpage.html {
|
||||
return 301 http://example.org/newpage.html;
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 重定向整个子路径
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
location /old-site {
|
||||
rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 负载均衡
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```nginx
|
||||
upstream example {
|
||||
ip_hash;
|
||||
# upstream的负载均衡,weight是权重,可以根据机器配置定义权重。
|
||||
# weigth参数表示权值,权值越高被分配到的几率越大。
|
||||
server 192.168.122.11:8081 ;
|
||||
server 127.0.0.1:82 weight=3;
|
||||
server 127.0.0.1:83 weight=3 down;
|
||||
server 127.0.0.1:84 weight=3; max_fails=3 fail_timeout=20s;
|
||||
server 127.0.0.1:85 weight=4;;
|
||||
keepalive 32;
|
||||
}
|
||||
server {
|
||||
#侦听的80端口
|
||||
listen 80;
|
||||
server_name git.example.cn;
|
||||
location / {
|
||||
# 在这里设置一个代理,和 upstream 的名字一样
|
||||
proxy_pass http://example;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 内容缓存
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
允许浏览器基本上永久地缓存静态内容。 Nginx 将为您设置 Expires 和 Cache-Control 头信息
|
||||
|
||||
```nginx {3}
|
||||
location /static {
|
||||
root /data;
|
||||
expires max;
|
||||
}
|
||||
```
|
||||
|
||||
如果要求浏览器永远不会缓存响应(例如用于跟踪请求),请使用 `-1`
|
||||
|
||||
```nginx {3}
|
||||
location = /empty.gif {
|
||||
empty_gif;
|
||||
expires -1;
|
||||
}
|
||||
```
|
||||
|
||||
### 跨域问题
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.xxx.com;
|
||||
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,HEAD';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 重定向 URI 来解决跨域问题
|
||||
<!--rehype:wrap-class=col-span-3 row-span-2-->
|
||||
|
||||
```nginx
|
||||
upstream test {
|
||||
server 127.0.0.1:8080;
|
||||
server localhost:8081;
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.xxx.com;
|
||||
location / {
|
||||
root html; # 去请求../html文件夹里的文件
|
||||
index index.html index.htm; # 首页响应地址
|
||||
}
|
||||
# 用于拦截请求,匹配任何以 /api/开头的地址,
|
||||
# 匹配符合以后,停止往下搜索正则。
|
||||
location ^~/api/{
|
||||
# 代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用
|
||||
# 例如www.a.com/api/msg?meth=1&par=2重写,只对/api/msg重写。
|
||||
# rewrite后面的参数是一个简单的正则 ^/api/(.*)$,
|
||||
# $1代表正则中的第一个(),$2代表第二个()的值,以此类推。
|
||||
rewrite ^/api/(.*)$ /$1 break;
|
||||
|
||||
# 把请求代理到其他主机
|
||||
# 其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下
|
||||
# 如果你的请求地址是他 http://server/html/test.jsp
|
||||
# 配置一: http://www.b.com/ 后面有“/”
|
||||
# 将反向代理成 http://www.b.com/html/test.jsp 访问
|
||||
# 配置一: http://www.b.com 后面没有有“/”
|
||||
# 将反向代理成 http://www.b.com/test.jsp 访问
|
||||
proxy_pass http://test;
|
||||
|
||||
# 如果 proxy_pass URL 是 http://a.xx.com/platform/ 这种情况
|
||||
# proxy_cookie_path应该设置成 /platform/ / (注意两个斜杠之间有空格)。
|
||||
proxy_cookie_path /platfrom/ /;
|
||||
|
||||
# 设置 Cookie 头通过
|
||||
proxy_pass_header Set-Cookie;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 跳转到带 www 的域上面
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
# 配置正常的带www的域名
|
||||
server_name www.wangchujiang.com;
|
||||
root /home/www/wabg/download;
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html =404;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
# 将不带 www 的 wangchujiang.com
|
||||
# 永久性重定向到 https://www.wangchujiang.com
|
||||
server_name wangchujiang.com;
|
||||
rewrite ^(.*) https://www.wangchujiang.com$1 permanent;
|
||||
}
|
||||
```
|
||||
|
||||
### 代理转发
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```nginx
|
||||
upstream server-api {
|
||||
# api 代理服务地址
|
||||
server 127.0.0.1:3110;
|
||||
}
|
||||
upstream server-resource {
|
||||
# 静态资源 代理服务地址
|
||||
server 127.0.0.1:3120;
|
||||
}
|
||||
server {
|
||||
listen 3111;
|
||||
server_name localhost; # 这里指定域名
|
||||
root /home/www/server-statics;
|
||||
# 匹配 api 路由的反向代理到API服务
|
||||
location ^~/api/ {
|
||||
rewrite ^/(.*)$ /$1 break;
|
||||
proxy_pass http://server-api;
|
||||
}
|
||||
# 假设这里验证码也在API服务中
|
||||
location ^~/captcha {
|
||||
rewrite ^/(.*)$ /$1 break;
|
||||
proxy_pass http://server-api;
|
||||
}
|
||||
# 假设你的图片资源全部在另外一个服务上面
|
||||
location ^~/img/ {
|
||||
rewrite ^/(.*)$ /$1 break;
|
||||
proxy_pass http://server-resource;
|
||||
}
|
||||
# 路由在前端,后端没有真实路由,
|
||||
# 路由不存在的 404 状态的页面返回 /index.html
|
||||
# 使用场景,用在 React/Vue项目没有真实路由
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html =404;
|
||||
# 空格很重要 ^
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 屏蔽 IP
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
可以放到 `http`, `server`, `location`, `limit_except` 语句块
|
||||
|
||||
```nginx
|
||||
include blockip.conf;
|
||||
```
|
||||
|
||||
在 `blockip.conf` 里面输入内容,如:
|
||||
|
||||
```nginx
|
||||
deny 165.91.122.67;
|
||||
|
||||
deny IP; # 屏蔽单个 ip 访问
|
||||
allow IP; # 允许单个 ip 访问
|
||||
deny all; # 屏蔽所有 ip 访问
|
||||
allow all; # 允许所有 ip 访问
|
||||
deny 123.0.0.0/8; # 屏蔽整个段即从 123.0.0.1 到 123.255.255.254 访问的命令
|
||||
deny 124.45.0.0/16; # 屏蔽IP段即从 123.45.0.1 到 123.45.255.254 访问的命令
|
||||
deny 123.45.6.0/24; # 屏蔽IP段即从 123.45.6.1 到 123.45.6.254 访问的命令
|
||||
|
||||
# 如果你想实现这样的应用,除了几个IP外,其他全部拒绝
|
||||
allow 1.1.1.1;
|
||||
allow 1.1.1.2;
|
||||
deny all;
|
||||
```
|
||||
|
||||
### 强制将 http 重定向到 https
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
rewrite ^ https://$http_host$request_uri? permanent; # 强制将 http 重定向到 https
|
||||
# 在错误页面和“服务器”响应头字段中启用或禁用发射nginx版本。 防止黑客利用版本漏洞攻击
|
||||
server_tokens off;
|
||||
}
|
||||
```
|
||||
|
||||
### 代理转发连接替换
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
location ^~/api/upload {
|
||||
rewrite ^/(.*)$ /wfs/v1/upload break;
|
||||
proxy_pass http://wfs-api;
|
||||
}
|
||||
```
|
||||
|
||||
将地址 `/api/upload` 替换为 `/wfs/v1/upload`
|
||||
|
||||
### 爬虫 User-Agent 过滤
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {
|
||||
return 503;
|
||||
}
|
||||
# 正常处理
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
### 图片防盗链
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
location ~* \.(gif|jpg|png|swf|flv)$ {
|
||||
root html;
|
||||
|
||||
valid_referers none blocked *.nginx.com;
|
||||
|
||||
if ($invalid_referer) {
|
||||
rewrite ^/ www.nginx.cn;
|
||||
# return 404;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 虚拟目录配置
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
location /img/ {
|
||||
alias /var/www/image/;
|
||||
}
|
||||
# 访问 /img/ 目录里面的文件时,
|
||||
# 会自动去 /var/www/image/ 目录找文件
|
||||
location /img/ {
|
||||
root /var/www/image;
|
||||
}
|
||||
# 访问 /img/ 目录下的文件时,
|
||||
# 会去 /var/www/image/img/ 目录下找文件
|
||||
```
|
||||
|
||||
### 屏蔽文件目录
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
通用备份和归档文件
|
||||
|
||||
```nginx
|
||||
location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
拒绝访问 `.git` 和 `.svn` 目录
|
||||
|
||||
```nginx
|
||||
location ~ (.git|.svn) {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
拒绝访问隐藏文件和目录
|
||||
|
||||
```nginx
|
||||
location ~ /\.(?!well-known\/) {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
### 防盗图配置
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
```nginx
|
||||
location ~ \/public\/(css|js|img)\/.*\.(js|css|gif|jpg|jpeg|png|bmp|swf) {
|
||||
valid_referers none blocked *.jslite.io;
|
||||
if ($invalid_referer) {
|
||||
rewrite ^/ http://wangchujiang.com/piratesp.png;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 阻止常见攻击
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
#### base64编码的网址
|
||||
|
||||
```nginx
|
||||
location ~* "(base64_encode)(.*)(\()" {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
#### javascript eval() url
|
||||
|
||||
```nginx
|
||||
location ~* "(eval\()" {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
### Gzip 配置
|
||||
<!--rehype:wrap-class=col-span-4 row-span-2-->
|
||||
|
||||
```nginx
|
||||
gzip on;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_comp_level 6;
|
||||
gzip_http_version 1.1;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied any;
|
||||
gzip_vary on;
|
||||
gzip_types
|
||||
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
|
||||
text/javascript application/javascript application/x-javascript
|
||||
text/x-json application/json application/x-web-app-manifest+json
|
||||
text/css text/plain text/x-component
|
||||
font/opentype application/x-font-ttf application/vnd.ms-fontobject
|
||||
image/x-icon;
|
||||
gzip_disable "msie6";
|
||||
```
|
||||
|
||||
### 使网站不可索引
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```nginx
|
||||
add_header X-Robots-Tag "noindex";
|
||||
|
||||
location = /robots.txt {
|
||||
return 200 "User-agent: *\nDisallow: /\n";
|
||||
}
|
||||
```
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Nginx 安装维护入门学习笔记](https://jaywcjlove.github.io/nginx-tutorial) _(jaywcjlove.github.io)_
|
||||
- [](https://virtubox.github.io/advanced-nginx-cheatsheet/) _(virtubox.github.io)_
|
10
docs/npm.md
@ -138,6 +138,16 @@ npm unpublish <package-name>@<version>
|
||||
|
||||
注意:如果您取消发布整个包,则必须在 24 小时后才能发布该包的任何新版本。
|
||||
|
||||
### 发布包 npmjs.org
|
||||
|
||||
```bash
|
||||
npm publish
|
||||
# 第一次需要指定公开参数
|
||||
npm publish --access public
|
||||
```
|
||||
|
||||
发布公开包,到 npmjs.org
|
||||
|
||||
配置
|
||||
---
|
||||
|
||||
|
@ -101,7 +101,7 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
|
||||
鼓励使用开源 [(OSI-approved)](https://opensource.org/licenses/alphabetical) 许可证,除非你有特别的原因不用它。 如果你开发的包是你工作的一部分,最好和公司讨论后再做决定。
|
||||
|
||||
**license字段必须是以下之一:**
|
||||
#### **license字段必须是以下之一**
|
||||
|
||||
- 如果你使用标准的许可证,需要一个有效地 [SPDX 许可证标识](https://spdx.org/licenses/)。
|
||||
- 如果你用多种标准许可证,需要有效的 [SPDX 许可证表达式2.0语法表达式](https://www.npmjs.com/package/spdx)。
|
||||
@ -475,8 +475,19 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
|
||||
这些是只在你的包开发期间需要,但是生产环境不会被安装的包。
|
||||
|
||||
### `overrides`
|
||||
|
||||
```json
|
||||
{
|
||||
"overrides": {
|
||||
"foo": "1.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
对依赖项的依赖项进行特定更改,例如用已知的安全问题替换依赖项的版本
|
||||
|
||||
### `peerDependencies`
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```json
|
||||
{
|
||||
@ -530,6 +541,8 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
}
|
||||
```
|
||||
|
||||
它允许对等依赖项标记为可选
|
||||
|
||||
系统
|
||||
----
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
Quick Reference 备忘清单
|
||||
===
|
||||
|
||||
这是您可以在 Quick Reference 备忘单上使用的样式参考,快速参与贡献!
|
||||
这是您可以在 Quick Reference 备忘单上使用的样式参考,快速参与[贡献](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)!
|
||||
|
||||
入门
|
||||
---
|
||||
@ -51,8 +51,8 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
|
||||
#### 语法
|
||||
|
||||
`<!--rehype:` + `key=value` + `&` + `key=value` + `-->`
|
||||
`标识开始` + `参数` + `分隔符` + `参数` + `标识结束`
|
||||
`<!--rehype:` _+_ `key=value` _+_ **`&`** _+_ `key=value` _+_ `-->`
|
||||
`标识开始` + `参数` + `分隔符(&)` + `参数` + `标识结束`
|
||||
|
||||
#### 示例
|
||||
|
||||
@ -72,7 +72,6 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
|
||||
#### 参数说明
|
||||
|
||||
类 | 说明
|
||||
@ -142,6 +141,8 @@ export const Student = (
|
||||
```jsx {1,4-5}
|
||||
```
|
||||
|
||||
代码行高亮可以和代码行号一起使用。
|
||||
|
||||
### Tooltips
|
||||
|
||||
[鼠标移动到上面有提示](https://github.com/jaywcjlove/reference) _Tooltips 的提示内容_<!--rehype:tooltips-->
|
||||
@ -180,11 +181,17 @@ export const Student = (
|
||||
### 代码行号
|
||||
|
||||
```jsx showLineNumbers
|
||||
export const Student = (
|
||||
<div className="Student"></div>
|
||||
);
|
||||
export const Student = <div>学生</div>;
|
||||
const school = <div>学校</div>;
|
||||
```
|
||||
|
||||
下面是 `Markdown` 代码示例
|
||||
|
||||
```markdown
|
||||
```jsx showLineNumbers
|
||||
```
|
||||
|
||||
标记语言后面添加 `showLineNumbers` 标识
|
||||
|
||||
### 内置类样式
|
||||
|
||||
@ -194,6 +201,7 @@ export const Student = (
|
||||
`wrap-text` | 超出换行
|
||||
`show-header` | 展示表头
|
||||
`style-none` | 隐藏 `<ul>` 列表样式
|
||||
`style-list` | `<table>` 单元格行展示
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 颜色标签
|
||||
@ -203,6 +211,7 @@ export const Student = (
|
||||
`<yel>` | <yel>黄色</yel>
|
||||
`<pur>` | <pur>紫色</pur>
|
||||
`<code>` 或 <code>\`\`</code> | <code>绿</code>`色`
|
||||
`<del>` 或 `~~删除~~` | <del>~~红色~~</del>
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
@ -241,6 +250,7 @@ H2 部分
|
||||
`cols-3` | `3` 栏卡片布局
|
||||
`cols-4` | `4` 栏卡片布局
|
||||
`cols-5` | `5` 栏卡片布局
|
||||
`cols-{1~6}` | `1~6` 栏卡片布局
|
||||
<!--rehype:className=show-header -->
|
||||
|
||||
### 占位布局 style 写法
|
||||
@ -279,9 +289,11 @@ H2 部分
|
||||
`col-span-2` | `2` 列占位
|
||||
`col-span-3` | `3` 列占位
|
||||
`col-span-4` | `4` 列占位
|
||||
`col-span-5` | `5` 列占位
|
||||
`row-span-2` | `2` 行占位
|
||||
`row-span-3` | `3` 行占位
|
||||
`row-span-4` | `4` 行占位
|
||||
`row-span-5` | `5` 行占位
|
||||
<!--rehype:className=show-header -->
|
||||
|
||||
### 卡片合并行布局 1
|
||||
@ -517,16 +529,16 @@ H2 部分
|
||||
|
||||
#### Date
|
||||
|
||||
| | |
|
||||
| ---- | ---- |
|
||||
:- | :-
|
||||
:- | :-
|
||||
`%m/%d/%Y` | 06/05/2013
|
||||
`%A, %B %e, %Y` | Sunday, June 5, 2013
|
||||
`%b %e %a` | Jun 5 Sun
|
||||
|
||||
#### Time
|
||||
|
||||
| | |
|
||||
| ---- | ---- |
|
||||
:- | :-
|
||||
:- | :-
|
||||
`%H:%M` | 23:05
|
||||
`%I:%M %p` | 11:05 PM
|
||||
|
||||
@ -534,8 +546,8 @@ H2 部分
|
||||
|
||||
### 快捷键
|
||||
|
||||
| | |
|
||||
| ---- | ---- |
|
||||
:- | :-
|
||||
:- | :-
|
||||
`V` | Vector
|
||||
`P` | Pencil
|
||||
`T` | Text
|
||||
@ -555,6 +567,28 @@ H2 部分
|
||||
|
||||
`<!--rehype:className=show-header-->`
|
||||
|
||||
### 列表样式展示表格
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
|
||||
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
`<!--rehype:className=style-list-->`
|
||||
|
||||
### 列表箭头样式展示表格
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
|
||||
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
`<!--rehype:className=style-list-arrow-->`
|
||||
|
||||
列表
|
||||
---
|
||||
|
||||
@ -578,6 +612,25 @@ H2 部分
|
||||
|
||||
`<!--rehype:className=cols-4-->`
|
||||
|
||||
### 列表步骤
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
- **重命名为 new_name**
|
||||
```bash
|
||||
$ git branch -m <new_name>
|
||||
```
|
||||
- 推送和**重置**
|
||||
```bash
|
||||
$ git push origin -u <new_name>
|
||||
```
|
||||
- 删除远程分支
|
||||
```bash
|
||||
$ git push origin --delete <old>
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
`<!--rehype:className=style-timeline-->`
|
||||
|
||||
### 没有标记
|
||||
|
||||
- Item 1
|
||||
@ -586,10 +639,31 @@ H2 部分
|
||||
- Item 4
|
||||
- Item 5
|
||||
- Item 6
|
||||
- Item 7
|
||||
- Item 8
|
||||
- Item 9
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
`<!--rehype:className=cols-3 style-none-->`
|
||||
|
||||
### 圆圈标记
|
||||
|
||||
- Item 1
|
||||
- Item 2
|
||||
- Item 3
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
`<!--rehype:className=style-round-->`
|
||||
|
||||
### 箭头标记
|
||||
|
||||
- Item 1
|
||||
- Item 2
|
||||
- Item 3
|
||||
<!--rehype:className=style-arrow-->
|
||||
|
||||
`<!--rehype:className=style-arrow-->`
|
||||
|
||||
H2 部分 - 5列效果展示
|
||||
---
|
||||
<!--rehype:body-class=cols-5-->
|
||||
|
322
docs/react.md
@ -12,9 +12,9 @@ React 备忘清单
|
||||
React 是一个用于构建用户界面的 JavaScript 库。
|
||||
|
||||
- [React 官方文档](https://reactjs.org/) _(reactjs.org)_
|
||||
- [Styled Components 备忘清单](./styled-components.md) _(jaywcjlove.github.io)_
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import {createRoot} from 'react-dom/client'
|
||||
import App from './App'
|
||||
```
|
||||
@ -46,14 +46,15 @@ import ReactDOM from 'react-dom'
|
||||
export class Hello extends Component {
|
||||
...
|
||||
}
|
||||
export default function World() {
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
使用 `export` 或者 `export default` 导出 `Hello` 组件
|
||||
使用 `export` 导出 **`Hello`**,`export default` 导出 **`World`** 组件
|
||||
|
||||
```jsx
|
||||
import { Hello } from './hello.js';
|
||||
|
||||
const Example = <Hello />;
|
||||
import World, { Hello } from './hello.js';
|
||||
```
|
||||
|
||||
使用 `import` 导入 `Hello` 组件,在示例中使用。
|
||||
@ -327,7 +328,7 @@ const Student = () => (
|
||||
|
||||
从 `v16.2.0` 开始 `Fragment` 可用于返回多个子节点,而无需向 DOM 添加额外的包装节点。或者使用 `<></>` 效果是一样的。
|
||||
|
||||
```jsx
|
||||
```jsx {2,5}
|
||||
const Student = () => (
|
||||
<>
|
||||
<Avatar src="./demo.jpg" />
|
||||
@ -340,7 +341,7 @@ const Student = () => (
|
||||
|
||||
### 返回字符串
|
||||
|
||||
```jsx
|
||||
```jsx {2}
|
||||
render() {
|
||||
return 'Look ma, no spans!';
|
||||
}
|
||||
@ -1011,12 +1012,313 @@ Menu.Item = ({ children }) => (
|
||||
<Menu>
|
||||
```
|
||||
|
||||
生命周期
|
||||
---
|
||||
|
||||
Hooks
|
||||
---
|
||||
|
||||
### Hooks API 参考
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### 基础 Hook
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`useState` | 返回一个 `state`,更新 `state` 的函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate)
|
||||
`useEffect` | 可能有副作用代码的函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useeffect)
|
||||
`useContext` | 接收并返回该 `context` 的当前值 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usecontext)
|
||||
|
||||
#### 额外的 Hook
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`useReducer` | `useState` 的替代方案 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate)
|
||||
`useCallback` | 返回一个回调函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback)
|
||||
`useMemo` | 返回一个 [memoized](https://en.wikipedia.org/wiki/Memoization) 值[#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usememo)
|
||||
`useRef` | 返回一个可变的 `ref` 对象 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useref)
|
||||
`useImperativeHandle` | 暴露给父组件的实例值 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useimperativehandle)
|
||||
`useLayoutEffect` | DOM 变更后同步调用函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#uselayouteffect)
|
||||
`useDebugValue` | 开发者工具中显示标签 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usedebugvalue)
|
||||
`useDeferredValue` | 接受并返回该值的新副本 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usedeferredvalue)
|
||||
`useTransition` | 过渡任务的等待状态 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usetransition)
|
||||
`useId` | 用于生成唯一 ID [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useid)
|
||||
|
||||
#### Library Hooks
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`useSyncExternalStore` | 读取和订阅外部数据源 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usesyncexternalstore)
|
||||
`useInsertionEffect` | DOM 突变之前 同步触发 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usesyncexternalstore)
|
||||
|
||||
### 函数式更新
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```jsx
|
||||
function Counter({ initialCount }) {
|
||||
const [count, setCount] = useState(initialCount);
|
||||
return (
|
||||
<>
|
||||
Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button>
|
||||
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
|
||||
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### useRef
|
||||
|
||||
```jsx
|
||||
function TextInputWithFocusButton() {
|
||||
const $input = useRef(null);
|
||||
const onButtonClick = () => {
|
||||
$input.current.focus();
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<input ref={$input} type="text" />
|
||||
<button onClick={onButtonClick}>
|
||||
聚焦输入
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
`current` 指向已挂载到 DOM 上的文本输入元素
|
||||
|
||||
### useImperativeHandle
|
||||
|
||||
```jsx
|
||||
function FancyInput(props, ref) {
|
||||
const inputRef = useRef();
|
||||
useImperativeHandle(ref, () => ({
|
||||
focus: () => {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}));
|
||||
return <input ref={inputRef} />;
|
||||
}
|
||||
FancyInput = forwardRef(FancyInput);
|
||||
```
|
||||
|
||||
父组件使用
|
||||
|
||||
```jsx
|
||||
<FancyInput ref={inputRef} />
|
||||
inputRef.current.focus()
|
||||
```
|
||||
|
||||
### useEffect
|
||||
|
||||
```jsx
|
||||
useEffect(() => {
|
||||
const subs = props.source.subscribe();
|
||||
return () => {
|
||||
subs.unsubscribe();
|
||||
};
|
||||
}, [props.source]);
|
||||
```
|
||||
|
||||
### useCallback
|
||||
|
||||
```jsx
|
||||
const memoizedCallback = useCallback(
|
||||
() => {
|
||||
doSomething(a, b);
|
||||
},
|
||||
[a, b],
|
||||
);
|
||||
```
|
||||
|
||||
### useMemo
|
||||
|
||||
```jsx
|
||||
const memoizedValue = useMemo(
|
||||
() => {
|
||||
return computeExpensiveValue(a, b)
|
||||
},
|
||||
[a, b]
|
||||
);
|
||||
```
|
||||
|
||||
### useId
|
||||
|
||||
```jsx
|
||||
function Checkbox() {
|
||||
const id = useId();
|
||||
return (
|
||||
<>
|
||||
<label htmlFor={id}>
|
||||
你喜欢React吗?
|
||||
</label>
|
||||
<input id={id} type="checkbox" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
用于生成跨服务端和客户端稳定的唯一 `ID` 的同时避免 `hydration` 不匹配
|
||||
|
||||
### useDebugValue
|
||||
|
||||
```jsx
|
||||
function useFriendStatus(friendID) {
|
||||
const [
|
||||
isOnline, setIsOnline
|
||||
] = useState(null);
|
||||
// ...
|
||||
// 在开发者工具中的这个 Hook 旁边显示标签
|
||||
// e.g. "FriendStatus: Online"
|
||||
useDebugValue(
|
||||
isOnline ? 'Online' : 'Offline'
|
||||
);
|
||||
return isOnline;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
不推荐你向每个自定义 `Hook` 添加 `debug` 值
|
||||
|
||||
### componentDidMount & componentWillUnmount
|
||||
|
||||
```jsx
|
||||
useEffect(
|
||||
() => {
|
||||
// componentDidMount
|
||||
// 组件挂载时,可以在这里完成你的任务
|
||||
return () => {
|
||||
// componentWillUnmount
|
||||
// 卸载时执行,清除 effect
|
||||
};
|
||||
},
|
||||
[ ]
|
||||
);
|
||||
```
|
||||
|
||||
这是一个类似 `class` 组件中 `componentDidMount` & `componentWillUnmount` 两个生命周期函数的写法。
|
||||
|
||||
生命周期
|
||||
---
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 挂载
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`constructor` _(props)_ | 渲染前 [#](https://zh-hans.reactjs.org/docs/react-component.html#constructor)
|
||||
`static getDerivedStateFromProps()` | 调用 `render` 方法之前调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops)
|
||||
`render()` | `class` 组件中唯一必须实现的方法 [#](https://reactjs.org/docs/react-component.html#render)
|
||||
`componentDidMount()` | 在组件挂载后(插入 DOM 树中)立即调用 [#](https://reactjs.org/docs/react-component.html#componentdidmount)
|
||||
`UNSAFE_componentWillMount()` | 在挂载之前被调用,建议使用 `constructor()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillmount)
|
||||
|
||||
在 `constructor()` 上设置初始状态。在 `componentDidMount()` 上添加 DOM 事件处理程序、计时器(等),然后在 `componentWillUnmount()` 上删除它们。
|
||||
|
||||
### 卸载
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`componentWillUnmount()` | 在组件卸载及销毁之前直接调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentwillunmount)
|
||||
|
||||
### 过时 API
|
||||
|
||||
过时方法 | 新方法
|
||||
:- | -
|
||||
~~`componentWillMount()`~~ | `UNSAFE_componentWillMount()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillmount)
|
||||
~~`componentWillReceiveProps()`~~ | `UNSAFE_componentWillReceiveProps()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops)
|
||||
~~`componentWillUpdate()`~~ | `UNSAFE_componentWillUpdate()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillupdate)
|
||||
|
||||
17+ 之后不再支持,在 `17` 版本之后,只有新的 `UNSAFE_` 生命周期名称可以使用。
|
||||
|
||||
### 更新
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`static getDerivedStateFromProps(props, state)` | 调用 `render` 之前调用,在初始挂载及后续更新时都会被调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops)
|
||||
`shouldComponentUpdate(nextProps, nextState)` | 如果返回 `false`,则跳过 `render()` [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops)
|
||||
`render()` | 在不修改组件 `state` 的情况下,每次调用时都返回相同的结果 [#](https://zh-hans.reactjs.org/docs/react-component.html#render)
|
||||
`getSnapshotBeforeUpdate()` | 在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置) [#](https://zh-hans.reactjs.org/docs/react-component.html#getsnapshotbeforeupdate)
|
||||
`componentDidUpdate()` | 这里使用 `setState()`,但记得比较 `props`。首次渲染不会执行此方法 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentdidupdate)
|
||||
|
||||
### 错误处理
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
方法 | 描述
|
||||
:- | -
|
||||
`static getDerivedStateFromError(error)` | 后代组件抛出错误后被调用,它将抛出的错误作为参数,并返回一个值以更新 `state` [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromerror)
|
||||
`componentDidCatch(error, info)` | 在后代组件抛出错误后被调用,会在“提交”阶段被调用,因此允许执行副作用 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentdidcatch)
|
||||
|
||||
### render()
|
||||
|
||||
```jsx {2}
|
||||
class Welcome extends React.Component {
|
||||
render() {
|
||||
return <h1>Hello, {this.props.name}</h1>;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### constructor()
|
||||
|
||||
```jsx {1}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// 不要在这里调用 this.setState()
|
||||
this.state = { counter: 0 };
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
```
|
||||
|
||||
### static getDerivedStateFromError()
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```jsx {7,13}
|
||||
class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
// 更新 state 使下一次渲染可以显降级 UI
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// 你可以渲染任何自定义的降级 UI
|
||||
return <h1>Something went wrong.</h1>;
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### componentDidUpdate()
|
||||
|
||||
```jsx {1}
|
||||
componentDidUpdate(prevProps) {
|
||||
// 典型用法(不要忘记比较 props):
|
||||
if (this.props.uid !== prevProps.uid) {
|
||||
this.fetchData(this.props.uid);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### getSnapshotBeforeUpdate()
|
||||
|
||||
```jsx
|
||||
getSnapshotBeforeUpdate(prevProps, prevState) {
|
||||
// 我们是否在 list 中添加新的 items ?
|
||||
// 捕获滚动位置以便我们稍后调整滚动位置。
|
||||
if (prevProps.list.length < this.props.list.length) {
|
||||
const list = this.listRef.current;
|
||||
return list.scrollHeight - list.scrollTop;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
PropTypes 属性类型检查
|
||||
---
|
||||
|
201
docs/regex.md
@ -65,7 +65,7 @@ RegEX 备忘清单
|
||||
- \$
|
||||
- \\
|
||||
- \?
|
||||
<!--rehype:className=cols-3-->
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
使用 `\` 转义这些特殊字符
|
||||
|
||||
@ -175,6 +175,33 @@ RegEX 备忘清单
|
||||
`(?(?=...)yes\|no)` | 有条件的前瞻
|
||||
`(?(?<=...)yes\|no)` | 有条件的往后看
|
||||
|
||||
### 递归
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`(?R)` | 递归整个模式
|
||||
`(?1)` | 递归第一个子模式
|
||||
`(?+1)` | 递归第一个相对子模式
|
||||
`(?&name)` | 递归子模式`name`
|
||||
`(?P=name)` | 匹配子模式`name`
|
||||
`(?P>name)` | 递归子模式`name`
|
||||
|
||||
### 标志/修饰符
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`g` | 全部
|
||||
`m` | 多行
|
||||
`i` | 不区分大小写
|
||||
`x` | 忽略空格
|
||||
`s` | 单线
|
||||
`u` | 统一码
|
||||
`X` | 扩展
|
||||
`U` | 不贪心
|
||||
`A` | 锚
|
||||
`J` | 重复的组名
|
||||
`d` | 结果包含捕获组子字符串开始和结束的索引
|
||||
|
||||
### 零宽度断言
|
||||
|
||||
:-|-
|
||||
@ -190,34 +217,6 @@ RegEX 备忘清单
|
||||
|
||||
零宽度断言 允许您在主模式之前(向后看)或之后(lookahead)匹配一个组,而不会将其包含在结果中。
|
||||
|
||||
### 标志/修饰符
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`g` | 全球的
|
||||
`m` | 多行
|
||||
`i` | 不区分大小写
|
||||
`x` | 忽略空格
|
||||
`s` | 单线
|
||||
`u` | 统一码
|
||||
`X` | 扩展
|
||||
`U` | 不贪心
|
||||
`A` | 锚
|
||||
`J` | 重复的组名
|
||||
|
||||
|
||||
### 递归
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`(?R)` | 递归整个模式
|
||||
`(?1)` | 递归第一个子模式
|
||||
`(?+1)` | 递归第一个相对子模式
|
||||
`(?&name)` | 递归子模式`name`
|
||||
`(?P=name)` | 匹配子模式`name`
|
||||
`(?P>name)` | 递归子模式`name`
|
||||
|
||||
|
||||
### POSIX 字符类
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -287,6 +286,27 @@ RegEX 备忘清单
|
||||
使用 `\` 搜索这些特殊字符:<br> `[ \ ^ $ . | ? * + ( ) { }`
|
||||
|
||||
|
||||
### 速记类
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`\w ` | “单词”字符 <br> _(字母、数字或下划线)_
|
||||
`\d ` | 数字
|
||||
`\s ` | 空格 <br> _(空格、制表符、vtab、换行符)_
|
||||
`\W, \D, or \S ` | 不是单词、数字或空格
|
||||
`[\D\S] ` | 表示不是数字或空格,两者都匹配
|
||||
`[^\d\s] ` | 禁止数字和空格
|
||||
|
||||
### 出现次数
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`colou?r` | 匹配 <yel>color</yel> 或 <yel>color</yel>
|
||||
`[BW]ill[ieamy's]*` | 匹配 <yel>Bill</yel>、<yel>Willy</yel>、<yel>William's</yel> 等。
|
||||
`[a-zA-Z]+` | 匹配 1 个或多个字母
|
||||
`\d{3}-\d{2}-\d{4}` | 匹配 SSN
|
||||
`[a-z]\w{1,7}` | 匹配 UW NetID
|
||||
|
||||
### 备择方案
|
||||
|
||||
范例 | 说明
|
||||
@ -309,28 +329,6 @@ RegEX 备忘清单
|
||||
|
||||
在 `[ ]` 中总是转义 `. \ ]` 有时是 `^ - .`
|
||||
|
||||
|
||||
### 速记类
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`\w ` | “单词”字符 <br> _(字母、数字或下划线)_
|
||||
`\d ` | 数字
|
||||
`\s ` | 空格 <br> _(空格、制表符、vtab、换行符)_
|
||||
`\W, \D, or \S ` | 不是单词、数字或空格
|
||||
`[\D\S] ` | 表示不是数字或空格,两者都匹配
|
||||
`[^\d\s] ` | 禁止数字和空格
|
||||
|
||||
### 出现次数
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`colou?r` | 匹配 <yel>color</yel> 或 <yel>color</yel>
|
||||
`[BW]ill[ieamy's]*` | 匹配 <yel>Bill</yel>、<yel>Willy</yel>、<yel>William's</yel> 等。
|
||||
`[a-zA-Z]+` | 匹配 1 个或多个字母
|
||||
`\d{3}-\d{2}-\d{4}` | 匹配 SSN
|
||||
`[a-z]\w{1,7}` | 匹配 UW NetID
|
||||
|
||||
### 贪婪与懒惰
|
||||
|
||||
范例 | 说明
|
||||
@ -340,7 +338,6 @@ RegEX 备忘清单
|
||||
`*? +? {n,}?`<br>_lazy_ | 尽可能少匹配
|
||||
`<.+?>` | 在 \<<yel>b</yel>>bold\<<yel>\/b</yel>> 中找到 2 个匹配项
|
||||
|
||||
|
||||
### 范围
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -370,7 +367,6 @@ RegEX 备忘清单
|
||||
`(?-x)` | 自由空间模式关闭
|
||||
/regex/`ismx` | 修改整个字符串的模式
|
||||
|
||||
|
||||
### 组
|
||||
|
||||
范例 | 说明
|
||||
@ -394,7 +390,7 @@ RegEX 备忘清单
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`on(?:click\|load)` | 快于:<br>`on(click\|load)`
|
||||
`on(?:click\|load)` | 快于:`on(click\|load)`
|
||||
|
||||
尽可能使用非捕获或原子组
|
||||
|
||||
@ -543,8 +539,11 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
如果想要匹配句子中的 `.` 则要写成 `\.` 以下这个例子 `\.?` 是选择性匹配.
|
||||
|
||||
### 锚点
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### `^` 号
|
||||
匹配指定开头或结尾的字符串就要使用到锚点。
|
||||
|
||||
#### `^` 号 (符串的开头)
|
||||
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
@ -552,32 +551,32 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
`^(T\|t)he` | `The` car is parked in the garage.
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
#### `$` 号
|
||||
#### `$` 号 (否是最后一个)
|
||||
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
`(at\.)` | The fat c`at.` s`at.` on the m`at.`
|
||||
`(at\.)$` | The fat cat. sat. on the m`at`.
|
||||
`(at\.)$` | The fat cat. sat. on the m`at.`
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 简写字符集
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
|简写|描述|
|
||||
|:----:|----|
|
||||
|`.`|除换行符外的所有字符|
|
||||
|`\w`|匹配所有字母数字,等同于 `[a-zA-Z0-9_]`|
|
||||
|`\W`|匹配所有非字母数字,即符号,等同于: `[^\w]`|
|
||||
|`\w`|匹配所有字母数字<br />等同于 `[a-zA-Z0-9_]`|
|
||||
|`\W`|匹配所有非字母数字,即符号<br />等同于: `[^\w]`|
|
||||
|`\d`|匹配数字: `[0-9]`|
|
||||
|`\D`|匹配非数字: `[^\d]`|
|
||||
|`\s`|匹配所有空格字符,等同于: `[\t\n\f\r\p{Z}]`|
|
||||
|`\s`|匹配所有空格字符<br />等同于:`[\t\n\f\r\p{Z}]`|
|
||||
|`\S`|匹配所有非空格字符: `[^\s]`|
|
||||
|`\f`|匹配一个换页符|
|
||||
|`\n`|匹配一个换行符|
|
||||
|`\r`|匹配一个回车符|
|
||||
|`\t`|匹配一个制表符|
|
||||
|`\v`|匹配一个垂直制表符|
|
||||
|`\p`|匹配 CR/LF(等同于 `\r\n`),用来匹配 DOS 行终止符|
|
||||
|`\p`|匹配 CR/LF(等同于 `\r\n`)<br />用来匹配 DOS 行终止符|
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
正则表达式提供一些常用的字符集简写。
|
||||
@ -756,6 +755,38 @@ False
|
||||
JavaScript 中的正则表达式
|
||||
---------------
|
||||
|
||||
### RegExp
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
#### 属性
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`dotAll` | 是否使用了 `s` 修饰符
|
||||
`flags` | 返回标志的字符串
|
||||
`global` | 是否使用了 `g` (全部)修饰符
|
||||
`hasIndices` | 是否使用了 `d` 修饰符
|
||||
`ignoreCase` | 匹配文本的时候是否忽略大小写 `i`
|
||||
`multiline` | 是否进行多行搜索 `m`
|
||||
`lastIndex` | 该索引表示从哪里开始下一个匹配
|
||||
`source` | 正则表达式的文本
|
||||
`sticky` | 搜索是否是 sticky
|
||||
`unicode` | Unicode 功能是否开启
|
||||
|
||||
#### 方法
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`match()` | 获取匹配结果
|
||||
`matchAll()` | 所有匹配项
|
||||
`replace()` | 替换所有符合正则模式的匹配项
|
||||
`search()` | 搜索以取得匹配正则模式的项
|
||||
`split()` | 切割字符串返回字符串数组
|
||||
~~`compile()`~~ | (重新)编译正则表达式
|
||||
`exec()` | 指定字符串中执行一个搜索匹配
|
||||
`test()` | 正则表达式与指定的字符串是否匹配
|
||||
`toString()` | 返回该正则表达式的字符串
|
||||
|
||||
### test()
|
||||
|
||||
```javascript
|
||||
@ -763,11 +794,8 @@ let textA = 'I like APPles very much';
|
||||
let textB = 'I like APPles';
|
||||
let regex = /apples$/i
|
||||
|
||||
// Output: false
|
||||
console.log(regex.test(textA));
|
||||
|
||||
// Output: true
|
||||
console.log(regex.test(textB));
|
||||
console.log(regex.test(textA)); // false
|
||||
console.log(regex.test(textB)); // true
|
||||
```
|
||||
|
||||
### search()
|
||||
@ -776,29 +804,22 @@ console.log(regex.test(textB));
|
||||
let text = 'I like APPles very much';
|
||||
let regexA = /apples/;
|
||||
let regexB = /apples/i;
|
||||
|
||||
// Output: -1
|
||||
console.log(text.search(regexA));
|
||||
|
||||
// Output: 7
|
||||
console.log(text.search(regexB));
|
||||
```
|
||||
|
||||
console.log(text.search(regexA)); // -1
|
||||
console.log(text.search(regexB)); // 7
|
||||
```
|
||||
|
||||
### exec()
|
||||
|
||||
```javascript
|
||||
let text = 'Do you like apples?';
|
||||
let regex= /apples/;
|
||||
|
||||
// Output: apples
|
||||
console.log(regex.exec(text)[0]);
|
||||
|
||||
// Output: Do you like apples?
|
||||
console.log(regex.exec(text).input);
|
||||
```
|
||||
|
||||
|
||||
### match()
|
||||
|
||||
```javascript
|
||||
@ -809,7 +830,6 @@ let regex = /apples/gi;
|
||||
console.log(text.match(regex));
|
||||
```
|
||||
|
||||
|
||||
### split()
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -844,15 +864,33 @@ let result = text.replace(regex, 'mangoes');
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
### 属性示例
|
||||
|
||||
```javascript
|
||||
/d/s.dotAll; // => true
|
||||
/d/g.global; // => true
|
||||
/d/ig.flags; // => "gi"
|
||||
/d/d.hasIndices; // => true
|
||||
/d/i.ignoreCase; // => true
|
||||
```
|
||||
|
||||
### 多行文本中使用正则表达式
|
||||
|
||||
```js
|
||||
let s = "Please yes\nmake my day!";
|
||||
|
||||
s.match(/yes[^]*day/);
|
||||
// 返回 'yes\nmake my day'
|
||||
```
|
||||
|
||||
### replaceAll()
|
||||
|
||||
```javascript
|
||||
let regex = /apples/gi;
|
||||
let text = 'Here are apples and apPleS';
|
||||
// Output: Here are mangoes and mangoes
|
||||
let result = text.replaceAll(regex, "mangoes");
|
||||
console.log(result);
|
||||
|
||||
text.replaceAll(regex, "mangoes");
|
||||
// 返回: Here are mangoes and mangoes
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
@ -879,6 +917,7 @@ PHP中的正则表达式
|
||||
```php
|
||||
$str = "Visit Microsoft!";
|
||||
$regex = "/microsoft/i";
|
||||
|
||||
// Output: Visit QuickRef!
|
||||
echo preg_replace($regex, "QuickRef", $str);
|
||||
```
|
||||
|
141
docs/screen.md
Normal file
@ -0,0 +1,141 @@
|
||||
Screen 备忘清单
|
||||
====
|
||||
|
||||
这是 screen 命令的快速参考指南备忘单。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 快速开始
|
||||
|
||||
```shell
|
||||
$ screen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
1\. 按 <kbd>Ctrl-A</kbd> <kbd>D</kbd> 分离会话
|
||||
|
||||
---
|
||||
|
||||
2\. 列出所有屏幕会话
|
||||
|
||||
```shell
|
||||
$ screen -ls
|
||||
```
|
||||
|
||||
3\. 重新附加屏幕会话
|
||||
|
||||
```shell
|
||||
$ screen -r <name/pid>
|
||||
```
|
||||
|
||||
|
||||
### 选项
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
选项 | 示例 | 说明
|
||||
:-|:-|:-
|
||||
`-S` | screen -S debug | 使用会话名称启动新会话
|
||||
`-ls` | screen -ls | 列出正在运行的会话/屏幕
|
||||
`-x` | screen -x | 附加到正在运行的会话
|
||||
`-r` | screen -r debug | 使用名称附加到正在运行的会话
|
||||
`-R` | screen -R debug | 附加到会话 _(如果它不存在将创建)_
|
||||
`-d` | screen -d -m wget xxxx.com/large.file | 分离模式下的开始屏幕
|
||||
`-X` | screen -X -S debug kill | 终止正在运行的会话
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 进入
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`screen -S <name>` | 使用会话名称开始新的屏幕会话
|
||||
`screen -ls` | 列出正在运行的会话/屏幕
|
||||
`screen -x` | 附加到正在运行的会话
|
||||
`screen -r <name>` | 使用名称附加到正在运行的会话
|
||||
`screen -dRR` | “终极附加”
|
||||
|
||||
### 窗口管理
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`Ctrl-A` `C` | 创建新窗口
|
||||
`Ctrl-A` `Ctrl-A` | 更改为上次访问的活动窗口
|
||||
`Ctrl-A` `0...9` | 按编号切换到窗口
|
||||
`Ctrl-A` `'` `<0...9 or title>` | 按编号或名称更改为窗口
|
||||
`Ctrl-A` `N` or `Ctrl-A` `<space>` | 切换到列表中的下一个窗口
|
||||
`Ctrl-A` `P` or `Ctrl-A` `<backspace>` | 切换到列表中的上一个窗口
|
||||
`Ctrl-A` `"` | 查看窗口列表
|
||||
`Ctrl-A` `W` | 显示窗口栏
|
||||
`Ctrl-A` `K` | 杀死当前窗口 _(不推荐)_
|
||||
`Ctrl-A` `\` | 杀死所有窗口 _(不推荐)_
|
||||
`Ctrl-A` `A` | 重命名当前窗口
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 出去
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`Ctrl-A` `D` | 分离
|
||||
`Ctrl-A` `D` `D` | 分离和注销 <br> _(快速退出)_
|
||||
`Ctrl-A` `:` | 退出所有会话
|
||||
`Ctrl-A` `C-\` | 强制退出屏幕<br> _(不推荐)_
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 帮助
|
||||
|
||||
| Command | Description |
|
||||
|--------------|--------------------------------|
|
||||
| `Ctrl-A` `?` | 查看帮助 _(列出键绑定)_ |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 杂项
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`Ctrl-A` `C-l` | 重绘窗口
|
||||
`Ctrl-A` `[` | 复制模式
|
||||
`Ctrl-A` `ESC` | 复制模式
|
||||
`Ctrl-A` `]` | 粘贴
|
||||
`Ctrl-A` `M` | 活动监控窗口
|
||||
`Ctrl-A` `_` | 静音监控窗口
|
||||
`Ctrl-A` `Ctrl-V` | 输入二合字母 _(非 ASCII 字符)_
|
||||
`Ctrl-A` `X` | 锁定(密码保护)显示
|
||||
`Ctrl-A` `:` | 输入屏幕命令
|
||||
`Ctrl-A` `H` | 在屏幕会话中启用日志记录
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
### 分屏
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`Ctrl-A` `S` | 水平分割显示
|
||||
`Ctrl-A` `V` | 垂直分割显示
|
||||
`Ctrl-A` `\|` | 垂直拆分显示
|
||||
`Ctrl-A` `TAB` | 跳转到下一个显示区域
|
||||
`Ctrl-A` `X` | 删除当前区域
|
||||
`Ctrl-A` `Q` | 删除除当前区域之外的所有区域
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
### 滚动
|
||||
|
||||
Command | Description
|
||||
:-|:-
|
||||
`Ctrl-a esc` | 进入滚动模式
|
||||
`Ctrl-u` | 向上滑动
|
||||
`Ctrl-d` | 向下滚动
|
||||
`esc esc` | 退出滚动模式
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 屏幕技巧
|
||||
|
||||
[SSH](./ssh.md) 并附加在一行中
|
||||
|
||||
```shell
|
||||
$ ssh -t user@host screen -x <name/pid>
|
||||
```
|
@ -1,6 +1,8 @@
|
||||
Sed 备忘清单
|
||||
====
|
||||
|
||||
Sed 是一个流编辑器,此 Sed 备忘清单包含 Sed 命令和一些常见的 Sed 技巧。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
|
1110
docs/styled-components.md
Normal file
150
docs/sublime-text.md
Normal file
@ -0,0 +1,150 @@
|
||||
Sublime Text 备忘清单
|
||||
===
|
||||
|
||||
这个 [Sublime Text](https://www.sublimetext.com/) 快速参考备忘单显示了它的键盘快捷键和命令。
|
||||
|
||||
## 快捷键
|
||||
|
||||
### 文本编辑初学者
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
[Sublime Text](https://www.sublimetext.com/) 是一个用于代码、标记的复杂文本编辑器。
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘ D` | 选择单词(重复包括单词的下一个实例)
|
||||
`⌘ L` | 选择行(重复以包括下一行)
|
||||
`⌘ ⇧ L` | 将选择拆分为多行(多行编辑)
|
||||
`⌘ ⇧ A` | 选择标签内的文本(重复以展开)
|
||||
`⌃ ⇧ M` | 选择大括号或尖括号(重复展开)
|
||||
`⌘ X` | 剪切一行
|
||||
`⌃ M` | 转到匹配的括号
|
||||
`⌃ ↩︎` or `↩︎` | 在后面插入行
|
||||
`⌘ ↵` | 在后面插入行
|
||||
`⇧ ⌘ ↵` | 在前面插入行
|
||||
`⇧ ⌥ ▲` | 选择当前行光标之前
|
||||
`⇧ ⌥ ▼` | 选择当前行光标之后
|
||||
`⇧ ⌃ M` | 选择当前括号的所有内容
|
||||
`⌥ ⇠/⇢` | 进行逐词移动,相应的
|
||||
`⌥ ⇧ ⇠/⇢` | 进行逐词选择
|
||||
`⌘ U` | 返回到历史光标位置(撤销)
|
||||
`⌃ M` | 快速的在起始括号和结尾括号间切换
|
||||
`⌃ ⇧ M` | 则可以快速选择括号间的内容
|
||||
`⌃ ⇧ J` | 对于缩进型语言(例如Python)可以使用
|
||||
`⌃ ⌘ D` | 复制整行
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
查看:[Sublime Text](https://www.sublimetext.com/) 官网
|
||||
|
||||
### 代码折叠
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘ Alt [` | 折叠最近的块
|
||||
`⌘ Alt ]` | 展开最近的块
|
||||
`⌘ K ⌘ 1` | 折叠所有第一级代码块
|
||||
`⌘ K ⌘ 2` | 折叠所有二级代码块
|
||||
`⌘ K ⌘ 3` | 折叠所有第三级代码块(等)
|
||||
`⌘ K ⌘ T` | 折叠所有 HTML 属性
|
||||
`⌘ K ⌘ 0` | 展开一切
|
||||
`⌘ K 0` | 代码展开
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### macOS 键盘符号
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘` | Command()
|
||||
`⌃` | Control
|
||||
`⌥` | Option(alt)
|
||||
`⇧` | Shift
|
||||
`⇪` | Caps Lock(大写)
|
||||
`fn` | 功能键就是fn
|
||||
`↩︎` | return/Enter
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 编辑
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘ ⇧ D` | 复制当前行/选择
|
||||
`⌘ ⇧ K` | 删除当前行/选择
|
||||
`⇧ del` | 删除当前行/选择
|
||||
`⌘ ⇧ ▲` | 移动队列
|
||||
`⌘ ⇧ ▼` | 下移一行
|
||||
`⌘ ▼/▲`| 移动到首行/尾行
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 转到
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘ P` | 去任何地方
|
||||
`⌘ G` | 转到行号
|
||||
`⌘ R` | 转到符号
|
||||
`⌘ P, :` | 转到行号(`:`之后输入数字)
|
||||
`⌘ P, #` | 转到并列出字符串模糊匹配(`#`之后输入字符)
|
||||
`⌘ P, @` | 转到并列出符号(`@`之后开始输入符号名称)
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 选择(Selecting)
|
||||
|
||||
- `⌘ + D`
|
||||
选择光标所在的单词,并高亮该词出现的所有位置
|
||||
- `⌘ + D`
|
||||
择该词出现的下一个位置
|
||||
- `⌘ + U` 进行回退,使用Esc退
|
||||
<!--rehype:className=style-timeline shortcuts-->
|
||||
|
||||
----
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌃ K` / `⌘ K K` | 从光标处删除到行末尾
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 拆分窗口
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⇧ ⌥ 2` | 将视图拆分为两列
|
||||
`⇧ ⌥ 1` | 将视图还原为单列
|
||||
`⇧ ⌥ 5` | 将视图设置为网格(4 组)
|
||||
`⌃ 2` | 跳到第 2 组
|
||||
`⇧ ⌃ 2` | 将文件移动到组 2
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 文本操作
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌃ K ⌃ L` | 转换为小写
|
||||
`⌃ K ⌃ U` | 转换为大写
|
||||
`⇧ ⌃ K` | 删除行
|
||||
`⌃BACKSPACE` | 向后删除单词
|
||||
`⌃DEL` | 删除单词转发
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 命令行中启动编辑器
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl\
|
||||
/usr/local/bin/subl
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### 在命令行中使用 **subl** 命令
|
||||
|
||||
```bash
|
||||
$ subl .
|
||||
$ subl README.md
|
||||
```
|
||||
|
||||
软链放到这个目录 `/usr/local/bin/subl`,这是因为 `Rootless` 机制,不能存放到 ~~`/usr/bin/subl`~~ 位置。
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Sublime Text 官网](https://www.sublimetext.com/) _(sublimetext.com)_
|
||||
- [Sublime 编辑器快捷键](https://jaywcjlove.github.io/handbook/Shortcuts/sublime.html) _(jaywcjlove.github.io)_
|
@ -1258,6 +1258,7 @@ class MyComponent extends React.Component<Props, {}> {
|
||||
```
|
||||
|
||||
### 泛型组件
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```tsx
|
||||
// 一个泛型组件
|
||||
|
2074
docs/vue2.md
Normal file
524
docs/yaml.md
Normal file
@ -0,0 +1,524 @@
|
||||
YAML 备忘清单
|
||||
====
|
||||
|
||||
这是理解和编写 YAML 格式配置文件的快速参考备忘单。
|
||||
|
||||
入门
|
||||
-----------
|
||||
|
||||
### 介绍
|
||||
|
||||
[YAML](https://yaml.org/) 是一种数据序列化语言,旨在供人类直接读写
|
||||
|
||||
- YAML 不允许使用制表符
|
||||
- 元素部分之间必须有空间
|
||||
- YAML 区分大小写
|
||||
- 以 `.yaml` 或 `.yml` 扩展名结束您的 YAML 文件
|
||||
- YAML 是 JSON 的超集
|
||||
- Ansible playbook 是 YAML 文件
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
|
||||
### 标量类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```yaml
|
||||
n1: 1 # 整数
|
||||
n2: 1.234 # 浮点
|
||||
s1: 'abc' # 字符串
|
||||
s2: "abc" # 字符串
|
||||
s3: abc # 字符串
|
||||
b: false # 布尔类型
|
||||
d: 2015-04-05 # 日期类型
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"n1": 1,
|
||||
"n2": 1.234,
|
||||
"s1": "abc",
|
||||
"s2": "abc",
|
||||
"s3": "abc",
|
||||
"b": false,
|
||||
"d": "2015-04-05"
|
||||
}
|
||||
```
|
||||
|
||||
使用空格缩进。 元素部分之间必须有空间。
|
||||
|
||||
### 变量
|
||||
|
||||
```yaml
|
||||
some_thing: &VAR_NAME foobar
|
||||
other_thing: *VAR_NAME
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json {.wrap}
|
||||
{
|
||||
"some_thing": "foobar",
|
||||
"other_thing": "foobar"
|
||||
}
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```yaml
|
||||
# A single line comment example
|
||||
# block level comment example
|
||||
# comment line 1
|
||||
# comment line 2
|
||||
# comment line 3
|
||||
```
|
||||
|
||||
### 多行字符串
|
||||
|
||||
```yaml
|
||||
description: |
|
||||
hello
|
||||
world
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json {.wrap}
|
||||
{"description": "hello\nworld\n"}
|
||||
```
|
||||
|
||||
### 继承
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```yaml
|
||||
parent: &defaults
|
||||
a: 2
|
||||
b: 3
|
||||
child:
|
||||
<<: *defaults
|
||||
b: 4
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json {.wrap}
|
||||
{
|
||||
"parent": {
|
||||
"a": 2,
|
||||
"b": 3
|
||||
},
|
||||
"child": {
|
||||
"a": 2,
|
||||
"b": 4
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 参考
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```yaml
|
||||
values: &ref
|
||||
- Will be
|
||||
- reused below
|
||||
|
||||
other_values:
|
||||
i_am_ref: *ref
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json {.wrap}
|
||||
{
|
||||
"values": [
|
||||
"Will be",
|
||||
"reused below"
|
||||
],
|
||||
"other_values": {
|
||||
"i_am_ref": [
|
||||
"Will be",
|
||||
"reused below"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 折叠的字符串
|
||||
|
||||
```yaml
|
||||
description: >
|
||||
hello
|
||||
world
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json {.wrap}
|
||||
{"description": "hello world\n"}
|
||||
```
|
||||
|
||||
### 两份文件
|
||||
|
||||
```yaml
|
||||
---
|
||||
document: this is doc 1
|
||||
---
|
||||
document: this is doc 2
|
||||
```
|
||||
|
||||
YAML使用`---`将指令与文档内容分开。
|
||||
|
||||
YAML Collections
|
||||
-----------
|
||||
|
||||
### 序列
|
||||
|
||||
```yaml
|
||||
- Mark McGwire
|
||||
- Sammy Sosa
|
||||
- Ken Griffey
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
[
|
||||
"Mark McGwire",
|
||||
"Sammy Sosa",
|
||||
"Ken Griffey"
|
||||
]
|
||||
```
|
||||
|
||||
### 映射
|
||||
|
||||
```yaml
|
||||
hr: 65 # Home runs
|
||||
avg: 0.278 # Batting average
|
||||
rbi: 147 # Runs Batted In
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"hr": 65,
|
||||
"avg": 0.278,
|
||||
"rbi": 147
|
||||
}
|
||||
```
|
||||
|
||||
### 映射到序列
|
||||
|
||||
```yaml
|
||||
attributes:
|
||||
- a1
|
||||
- a2
|
||||
methods: [getter, setter]
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"attributes": ["a1", "a2"],
|
||||
"methods": ["getter", "setter"]
|
||||
}
|
||||
```
|
||||
|
||||
### 映射序列
|
||||
|
||||
```yaml
|
||||
children:
|
||||
- name: Jimmy Smith
|
||||
age: 15
|
||||
- name: Jimmy Smith
|
||||
age: 15
|
||||
-
|
||||
name: Sammy Sosa
|
||||
age: 12
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"children": [
|
||||
{"name": "Jimmy Smith", "age": 15},
|
||||
{"name": "Jimmy Smith", "age": 15},
|
||||
{"name": "Sammy Sosa", "age": 12}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 序列的序列
|
||||
|
||||
```yaml
|
||||
my_sequences:
|
||||
- [1, 2, 3]
|
||||
- [4, 5, 6]
|
||||
-
|
||||
- 7
|
||||
- 8
|
||||
- 9
|
||||
- 0
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"my_sequences": [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9, 0]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 映射的映射
|
||||
|
||||
```yaml
|
||||
Mark McGwire: {hr: 65, avg: 0.278}
|
||||
Sammy Sosa: {
|
||||
hr: 63,
|
||||
avg: 0.288
|
||||
}
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"Mark McGwire": {
|
||||
"hr": 65,
|
||||
"avg": 0.278
|
||||
},
|
||||
"Sammy Sosa": {
|
||||
"hr": 63,
|
||||
"avg": 0.288
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 嵌套集合
|
||||
|
||||
```yaml
|
||||
Jack:
|
||||
id: 1
|
||||
name: Franc
|
||||
salary: 25000
|
||||
hobby:
|
||||
- a
|
||||
- b
|
||||
location: {country: "A", city: "A-A"}
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"Jack": {
|
||||
"id": 1,
|
||||
"name": "Franc",
|
||||
"salary": 25000,
|
||||
"hobby": ["a", "b"],
|
||||
"location": {
|
||||
"country": "A", "city": "A-A"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 无序集
|
||||
|
||||
```yaml
|
||||
set1: !!set
|
||||
? one
|
||||
? two
|
||||
set2: !!set {'one', "two"}
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"set1": {"one": null, "two": null},
|
||||
"set2": {"one": null, "two": null}
|
||||
}
|
||||
```
|
||||
|
||||
集合表示为一个映射,其中每个键都与一个空值相关联
|
||||
|
||||
|
||||
### 有序映射
|
||||
|
||||
```yaml
|
||||
ordered: !!omap
|
||||
- Mark McGwire: 65
|
||||
- Sammy Sosa: 63
|
||||
- Ken Griffy: 58
|
||||
```
|
||||
|
||||
#### ↓ 等效的 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"ordered": [
|
||||
{"Mark McGwire": 65},
|
||||
{"Sammy Sosa": 63},
|
||||
{"Ken Griffy": 58}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
YAML 参考
|
||||
--------------
|
||||
|
||||
### 条款
|
||||
|
||||
- 序列又名数组或列表
|
||||
- 标量又名字符串或数字
|
||||
- 映射又名哈希或字典
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
基于 YAML.org [refcard](https://yaml.org/refcard.html)。
|
||||
|
||||
### 文档指标
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`%` | 指令指标
|
||||
`---` | 文档标题
|
||||
`...` | 文档终结者
|
||||
|
||||
### 收集指标
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`?` | 关键指标
|
||||
`:` | 价值指标
|
||||
`-` | 嵌套系列条目指示器
|
||||
`,` | 单独的内联分支条目
|
||||
`[]` | 环绕串联系列分支
|
||||
`{}` | 环绕在线键控分支
|
||||
|
||||
### 别名指标
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`&` | 锚属性
|
||||
`*` | 别名指示符
|
||||
|
||||
### 特殊键
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`=` | 默认“值”映射键
|
||||
`<<` | 合并来自另一个映射的键
|
||||
|
||||
### 标量指标
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`''` | 环绕内联未转义标量
|
||||
`"` | 环绕内嵌转义标量
|
||||
`|` | 块标量指示器
|
||||
`>` | 折叠标量指示器
|
||||
`-` | 剥离 chomp 修饰符(`|-` 或 `>-`)
|
||||
`+` | 保留 chomp 修饰符(`|+` 或 `>+`)
|
||||
`1-9` | 显式缩进修饰符(`|1` 或 `>2`)。 <br/> 修饰符可以组合(`|2-`, `>+1`)
|
||||
|
||||
### 标签属性(通常未指定)
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`none` | 未指定的标签(由应用程序自动解析)
|
||||
`!` | 非特定标签(默认情况下,`!!map`/`!!seq`/`!!str`)
|
||||
`!foo` | 主要(按照惯例,表示本地 `!foo` 标记)
|
||||
`!!foo` | 次要的(按照惯例,表示 `tag:yaml.org,2002:foo`)
|
||||
`!h!foo` | 需要 `%TAG !h! <prefix>`(然后表示 `<prefix>foo`)
|
||||
`!<foo>` | 逐字标记(始终表示“foo”)
|
||||
|
||||
### 杂项指标
|
||||
|
||||
| | |
|
||||
|-----|-----------------------------|
|
||||
| `#` | 一次性评论指示器 |
|
||||
| <code>\`@</code> | 两者都保留供将来使用 |
|
||||
|
||||
|
||||
### 核心类型(默认自动标签)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| | |
|
||||
|---------|------------------------------------------|
|
||||
| `!!map` | `{Hash table, dictionary, mapping}` |
|
||||
| `!!seq` | `{List, array, tuple, vector, sequence}` |
|
||||
| `!!str` | Unicode 字符串 |
|
||||
|
||||
### 转义码
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### Numeric
|
||||
|
||||
- `\x12` (8-bit)
|
||||
- `\u1234` (16-bit)
|
||||
- `\U00102030` (32-bit)
|
||||
<!--rehype:className=cols-2 style-none-->
|
||||
|
||||
#### Protective
|
||||
|
||||
- `\\` (\\)
|
||||
- `\"` (")
|
||||
- `\ ` ( )
|
||||
- `\<TAB>` (TAB)
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
#### C
|
||||
- `\0` (NUL)
|
||||
- `\a` (BEL)
|
||||
- `\b` (BS)
|
||||
- `\f` (FF)
|
||||
- `\n` (LF)
|
||||
- `\r` (CR)
|
||||
- `\t` (TAB)
|
||||
- `\v` (VTAB)
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
#### 额外的
|
||||
|
||||
- `\e` (ESC)
|
||||
- `\_` (NBSP)
|
||||
- `\N` (NEL)
|
||||
- `\L` (LS)
|
||||
- `\P` (PS)
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
### 更多类型
|
||||
|
||||
| | |
|
||||
|----------|-----------------------------|
|
||||
| `!!set` | `{cherries, plums, apples}` |
|
||||
| `!!omap` | `[one: 1, two: 2]` |
|
||||
|
||||
### 与语言无关的标量类型
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
| | |
|
||||
|---------------------------|--------------------------------------------|
|
||||
| `{~, null}` | 空(无值)。 |
|
||||
| `[1234, 0x4D2, 02333]` | [十进制整数、十六进制整数、八进制整数] |
|
||||
| `[1_230.15, 12.3015e+02]` | [固定浮点数,指数浮点数] |
|
||||
| `[.inf, -.Inf, .NAN]` | [无穷大(浮点数),负数,不是数字] |
|
||||
| `{Y, true, Yes, ON}` | 布尔真 |
|
||||
| `{n, FALSE, No, off}` | 布尔假 |
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [YAML Reference Card](https://yaml.org/refcard.html) _(yaml.org)_
|
||||
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/yaml/) _(learnxinyminutes.com)_
|
||||
- [YAML lint online](http://www.yamllint.com/) _(yamllint.com)_
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reference",
|
||||
"version": "1.0.0",
|
||||
"name": "@wcj/reference",
|
||||
"version": "1.4.0",
|
||||
"description": "为开发人员分享快速参考备忘单(主要是方便自己)。",
|
||||
"author": "jaywcjlove",
|
||||
"license": "MIT",
|
||||
|
3
scripts/assets/c.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 38 42">
|
||||
<path fill="currentColor" fill-rule="evenodd" d="M20.096,0.28575 C21.6507561,1.15835976 24.653163,2.84381008 27.7615951,4.58873655 L28.7451648,5.14086432 C32.0250464,6.98202246 35.2659268,8.80121341 36.903,9.71975 C37.582,10.09975 38,10.80375 38,11.56575 L38,30.43275 C38,31.19475 37.582,31.89875 36.903,32.27975 C35.3482439,33.1523598 32.345837,34.8378101 29.2374049,36.5827365 L28.2538352,37.1348643 C24.9739536,38.9760225 21.7330732,40.7952134 20.096,41.71375 C19.417,42.09475 18.581,42.09475 17.903,41.71375 C16.3482439,40.8411402 13.345837,39.1556899 10.2374049,37.4107635 L9.2538352,36.8586357 C5.9739536,35.0174775 2.73307317,33.1982866 1.096,32.27975 C0.418,31.89875 0,31.19575 0,30.43375 L0,11.56675 C0,10.80475 0.418,10.10075 1.097,9.71975 C4.451,7.83675 14.549,2.16875 17.903,0.28575 C18.582,-0.09525 19.418,-0.09525 20.096,0.28575 Z M19,6.99975 C11.273,6.99975 5,13.27275 5,20.99975 C5,28.72675 11.273,34.99975 19,34.99975 C24.2106279,34.99975 28.7600712,32.1471979 31.1706024,27.9198213 L25.0359394,24.544542 C23.8185152,26.6113911 21.5699125,27.99975 19,27.99975 C15.137,27.99975 12,24.86275 12,20.99975 C12,17.13575 15.136,13.99975 19,13.99975 C21.527968,13.99975 23.7450291,15.3427307 24.9755084,17.353858 L31.0544381,13.8798146 C28.6157645,9.76264004 24.1280833,6.99975 19,6.99975 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
3
scripts/assets/css.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512" height="1em" width="1em">
|
||||
<path d="m64 32 35 403.22L255.77 480 413 435.15 448 32Zm290.68 334.9L256.07 395l-98.46-28.24-6.75-77.76h48.26l3.43 39.56 53.59 15.16.13.28 53.47-14.85 5.64-64.15H203l-4-50h120.65l4.35-51H140l-4-49h240.58Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 325 B |
5
scripts/assets/electron.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" height="1em" width="1em">
|
||||
<path d="M86.76 255a9.89 9.89 0 0 0 4.87-1.29 9.82 9.82 0 0 0 3.65-13.43c-16.46-28.56-17.81-52.12-7.45-70 14.26-24.57 53.61-33.65 105.27-24.29a9.86 9.86 0 0 0 11.45-7.9 9.84 9.84 0 0 0-7.93-11.44c-29.19-5.28-56-5.18-77.39.3-22.3 5.71-39 17.28-48.45 33.48-14 24.19-12.7 54.73 7.42 89.62a9.85 9.85 0 0 0 8.56 4.95Zm274.85-111.27c32.24.42 52.61 9.31 62.79 26.86 14.21 24.48 2.52 62.81-31.27 102.52a9.82 9.82 0 0 0 7.51 16.18 9.88 9.88 0 0 0 7.52-3.46c19.12-22.47 32.35-45.54 38.25-66.71 6.14-22 4.43-42.21-5-58.38-13.8-23.78-40.13-36.15-79.59-36.67h-.14a9.83 9.83 0 0 0-.12 19.66Zm-35.14 271.16a9.88 9.88 0 0 0-13.5 3.35c-16.41 27.15-36.57 42.1-56.77 42.1-28.49 0-56-29.31-73.73-78.42a9.87 9.87 0 0 0-12.59-5.92 9.83 9.83 0 0 0-6 12.58c10 27.77 23.47 50.75 39 66.46 16.11 16.34 34.55 25 53.32 25 27.38 0 53.54-18.33 73.65-51.61a9.81 9.81 0 0 0-3.38-13.5Zm105.23-76.35a32.14 32.14 0 0 0-29.9 44.33c-41.8 19.5-119.8 4.79-191.87-36.62-32.91-18.9-62.16-41.86-84.6-66.39a9.9 9.9 0 0 0-13.91-.65 9.8 9.8 0 0 0-.65 13.9c23.79 26 54.68 50.28 89.33 70.18 40.28 23.13 82.27 38.63 121.43 44.81a225.54 225.54 0 0 0 35 2.91c23.12 0 43-4.3 58.51-12.79a32.2 32.2 0 1 0 16.7-59.68Zm0 44.66a12.6 12.6 0 0 1-7.82-2.72 10 10 0 0 0-2.2-2.21 12.61 12.61 0 1 1 10 4.93Z"/>
|
||||
<path d="M82.09 338.59c.57-21.26 12.41-47 33.68-73.16 23.19-28.45 56.69-56 94.34-77.65 33.25-19.1 65.2-31.9 98.07-38.91a9.83 9.83 0 1 0-4.12-19.22c-34.85 7.43-68.78 21-103.79 41.09C116.09 219.09 59.9 289.88 62.46 343.9a32.32 32.32 0 1 0 19.63-5.31ZM80.3 383.2a12.5 12.5 0 1 1 12.59-12.5 12.56 12.56 0 0 1-12.59 12.5Z"/>
|
||||
<path d="M256.2 96.32a32.23 32.23 0 0 0 26.53-13.81c17.89 11.69 34 35 45.81 66.12 13 34.39 19.84 75.38 19.84 118.54 0 37.18-5.19 72.35-15 103.6a9.72 9.72 0 0 0 .66 7.49 9.82 9.82 0 0 0 5.8 4.84 9.89 9.89 0 0 0 12.34-6.44c10.42-33.14 15.93-70.34 15.93-109.49 0-47.17-7.77-91.77-22.47-129-14.41-36.48-34.13-62.4-57.14-75.16a32.3 32.3 0 1 0-32.3 33.31Zm0-44.66a12.5 12.5 0 1 1-12.59 12.5 12.56 12.56 0 0 1 12.59-12.5Zm-5.2 191.7a24.35 24.35 0 0 0 5.16 48.16 24.68 24.68 0 0 0 5.16-.55A24.36 24.36 0 1 0 251 243.36Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
3
scripts/assets/emmet.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em" viewBox="0 0 153 151">
|
||||
<path d="M76.2378757,0 C118.342892,0 152.475751,33.7082594 152.475751,75.2895046 C152.475751,116.87075 118.342892,150.579009 76.2378757,150.579009 C34.1328596,150.579009 0,116.87075 0,75.2895046 C0,33.7082594 34.1328596,0 76.2378757,0 Z M60.5934369,46.9019586 L19.8384036,56.9645627 L92.6150779,128.835332 L102.803239,88.5872762 L94.3131047,80.2021662 L87.0356763,108.950356 L70.5395345,92.6594199 L75.3909542,73.9732442 L56.2267408,78.5252622 L39.7305989,62.2343264 L68.8415078,55.0474265 L60.5934369,46.9019586 Z M116.873372,33.007443 L76.1189361,43.0694569 L84.367007,51.2149248 L102.561176,47.1421909 L98.1944795,64.8703887 L106.684613,73.2549084 L116.873372,33.007443 Z" transform="translate(0 .421)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 824 B |
1
scripts/assets/golang.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 120 120"><path fill="currentColor" d="M60,0 C93.137085,-6.08718376e-15 120,26.862915 120,60 C120,93.137085 93.137085,120 60,120 C26.862915,120 4.05812251e-15,93.137085 0,60 C-4.05812251e-15,26.862915 26.862915,6.08718376e-15 60,0 Z M66.9375,44.8284375 C63.140625,42.2503125 58.921875,41.7346875 54.515625,42.5315625 C49.125,43.5159375 44.71875,46.2815625 41.390625,50.6409375 C38.296875,54.6721875 36.796875,59.2659375 37.40625,64.3753125 C37.921875,68.6878125 39.890625,72.1565625 43.359375,74.7815625 C47.109375,77.5940625 51.375,78.4846875 55.96875,77.8753125 C61.546875,77.1253125 65.953125,74.3596875 69.328125,69.9065625 C70.0941964,68.8967411 70.7503316,67.8351849 71.2989326,66.7266981 C72.0855742,69.5828677 73.6756442,72.0358799 75.984375,74.0315625 C79.265625,76.8440625 83.15625,78.0628125 87.421875,78.1565625 C88.640625,78.0159375 89.90625,77.9690625 91.171875,77.7346875 C95.53125,76.8440625 99.328125,74.8753125 102.421875,71.7346875 C106.78125,67.3284375 108.609375,62.1721875 107.8125,55.8440625 C107.203125,51.3440625 104.90625,47.9221875 101.203125,45.3909375 C97.125,42.6253125 92.625,42.1565625 87.84375,43.0003125 C82.265625,43.9846875 78.140625,46.3284375 74.71875,50.8284375 C73.2524636,52.7475477 72.1531891,54.7757695 71.4756823,56.9222289 L56.390625,56.9221875 C55.6875,56.9221875 55.359375,57.3909375 55.21875,57.6721875 C54.5625,58.8909375 53.4375,61.3284375 52.828125,62.7815625 C52.5,63.5784375 52.734375,64.1878125 53.71875,64.1878125 L62.765625,64.1878125 C62.296875,64.8440625 61.921875,65.4065625 61.5,65.9221875 C59.390625,68.3128125 56.71875,69.4378125 53.53125,69.0159375 C49.828125,68.5003125 47.25,65.4065625 47.203125,61.6565625 C47.15625,57.8596875 48.796875,54.8128125 51.984375,52.7503125 C54.65625,51.0159375 57.515625,50.5940625 60.46875,52.0471875 C61.453125,52.5159375 61.96875,53.0315625 62.671875,53.8284375 C63.28125,54.5315625 63.328125,54.4846875 64.03125,54.2971875 C66.9375,53.5471875 68.953125,52.9846875 71.90625,52.2346875 C72.46875,52.0940625 72.65625,51.8596875 72.375,51.4378125 C71.203125,48.7190625 69.421875,46.4690625 66.9375,44.8284375 Z M88.875,51.4378125 C93.328125,50.4065625 97.59375,53.0315625 98.4375,57.6721875 C98.53125,58.1409375 98.53125,58.6096875 98.578125,59.2190625 C98.34375,63.2503125 96.328125,66.2503125 92.625,68.1721875 C90.140625,69.4378125 87.5625,69.5784375 84.984375,68.4534375 C81.609375,66.9534375 79.828125,63.2503125 80.671875,59.5940625 C81.703125,55.1878125 84.515625,52.4221875 88.875,51.4378125 Z M33.609375,59.9690625 L24.234375,59.9690625 C24.046875,59.9690625 23.859375,60.1096875 23.765625,60.2503125 L23.109375,61.4221875 C23.015625,61.5628125 23.0625,61.7034375 23.25,61.7034375 L33.46875,61.7503125 C33.609375,61.7503125 33.796875,61.6096875 33.796875,61.4221875 L33.890625,60.2971875 C33.890625,60.1096875 33.796875,59.9690625 33.609375,59.9690625 Z M34.640625,55.6565625 L13.265625,55.6565625 C13.078125,55.6565625 12.84375,55.7503125 12.75,55.8909375 L11.765625,57.1565625 C11.671875,57.2971875 11.71875,57.3909375 11.90625,57.3909375 L34.078125,57.3440625 C34.265625,57.3440625 34.453125,57.2503125 34.5,57.0628125 L34.875,55.9378125 C34.921875,55.7971875 34.828125,55.6565625 34.640625,55.6565625 Z M37.078125,51.3440625 L20.34375,51.3440625 C20.15625,51.3440625 19.921875,51.4378125 19.828125,51.5784375 L18.84375,52.8440625 C18.75,52.9846875 18.796875,53.0784375 18.984375,53.0784375 L35.953125,53.1253125 C36.09375,53.1253125 36.328125,52.9846875 36.421875,52.8440625 L37.21875,51.6253125 C37.3125,51.4846875 37.265625,51.3440625 37.078125,51.3440625 Z"/></svg>
|
After Width: | Height: | Size: 3.6 KiB |
3
scripts/assets/grep.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" height="1em" width="1em">
|
||||
<path d="M5 3a2 2 0 0 0-2 2v4.758A4.5 4.5 0 0 1 9.973 13h3.529a.5.5 0 0 1 0 1h-3.53a4.499 4.499 0 0 1-.411 1.439L11.122 17h3.879a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5Zm2.5 4.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm2-.25h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1 0-1ZM9 10.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5Zm-6.615 1.405A3.5 3.5 0 0 0 7.6 16.3l2.543 2.558a.5.5 0 0 0 .707-.708L8.3 15.6a3.5 3.5 0 1 0-5.916-3.695Zm5.194.206a2.5 2.5 0 1 1-4.157 2.778 2.5 2.5 0 0 1 4.157-2.778Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 601 B |
3
scripts/assets/html.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512" height="1em" width="1em">
|
||||
<path d="m64 32 34.94 403.21L255.77 480 413 435.15 448 32Zm308 132H188l4 51h176l-13.51 151.39L256 394.48l-98.68-28-6.78-77.48h48.26l3.42 39.29L256 343.07l53.42-14.92L315 264H148l-12.59-149.59H376.2Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 319 B |
3
scripts/assets/htop.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" height="1em" width="1em">
|
||||
<path d="M16.19 2H7.81C4.17 2 2 4.17 2 7.81v8.37C2 19.83 4.17 22 7.81 22h8.37c3.64 0 5.81-2.17 5.81-5.81V7.81C22 4.17 19.83 2 16.19 2ZM7.63 18.15c0 .41-.34.75-.75.75s-.75-.34-.75-.75v-2.07c0-.41.34-.75.75-.75s.75.34.75.75v2.07Zm5.12 0c0 .41-.34.75-.75.75s-.75-.34-.75-.75V14c0-.41.34-.75.75-.75s.75.34.75.75v4.15Zm5.12 0c0 .41-.34.75-.75.75s-.75-.34-.75-.75v-6.22c0-.41.34-.75.75-.75s.75.34.75.75v6.22Zm0-9.38c0 .41-.34.75-.75.75s-.75-.34-.75-.75V7.8a19.532 19.532 0 0 1-9.31 5.36c-.06.02-.12.02-.18.02-.34 0-.64-.23-.73-.57-.1-.4.14-.81.55-.91a18.07 18.07 0 0 0 8.75-5.11H14.2c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h2.93c.04 0 .07.02.11.02.05.01.1.01.15.03.05.02.09.05.14.08.03.02.06.03.09.05.01.01.01.02.02.02.04.04.07.08.1.12.03.04.06.07.07.11.02.04.02.08.03.13.01.05.03.1.03.16 0 .01.01.02.01.03v2.93h-.01Z" fill="currentColor"/>
|
||||
</svg>
|
After Width: | Height: | Size: 940 B |
3
scripts/assets/lerna.svg
Normal file
After Width: | Height: | Size: 224 KiB |
3
scripts/assets/nginx.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em" viewBox="0 0 46 52">
|
||||
<path d="M21.6686953,0.373850863 C22.4859141,-0.124616954 23.5140859,-0.124616954 24.3575391,0.373850863 L44.6555781,12.0199042 C45.4992109,12.491911 46,13.3837179 46,14.3541925 L46,37.6459416 C46,38.6164162 45.4992109,39.5084019 44.6555781,39.9804087 L24.3575391,51.6262832 C23.5403203,52.1245723 22.5123281,52.1245723 21.6686953,51.6262832 L1.37083594,39.9804087 C0.948929687,39.7444053 0.606265625,39.4295553 0.369078125,39.009934 C0.105476562,38.5903128 0,38.1444094 0,37.672045 L0,14.3541925 C0,13.3837179 0.500789062,12.491911 1.37101563,12.0199042 Z M32.1078203,14.5377872 C31.4147694,14.5348957 30.749258,14.8075453 30.2591927,15.2951641 C29.7691273,15.782783 29.4951098,16.444972 29.4980391,17.134563 L29.4980391,30.0655834 L18.5843594,17.0821774 L17.7937344,16.1378062 C16.9238672,15.0623815 15.4739687,14.5640925 14.2348437,14.5640925 C12.5215234,14.5640925 11.2825549,15.6919028 11.2825549,17.0821774 L11.2825549,34.8918533 C11.2796492,35.5814132 11.5536421,36.2435748 12.0436685,36.7311885 C12.5336949,37.2188021 13.1991599,37.4914728 13.8921797,37.4886291 C14.5852306,37.4915206 15.250742,37.218871 15.7408073,36.7312522 C16.2308727,36.2436333 16.5048902,35.5814443 16.5019609,34.8918533 L16.5019609,21.9869363 L28.2062656,35.8886101 C29.0761328,36.9640348 30.5260312,37.4623238 31.7651562,37.4623238 C33.4784766,37.4623238 34.7174451,36.3345135 34.7174451,34.9444177 L34.7174451,17.134563 C34.7203508,16.4450031 34.4463579,15.7828415 33.9563315,15.2952278 C33.4663051,14.8076142 32.8008401,14.5349435 32.1078203,14.5377872 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,5 +1,5 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" height="1em" width="1em">
|
||||
<path opacity=".4" d="m21.66 10.44-.98 4.18c-.84 3.61-2.5 5.07-5.62 4.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2 1.17-2.42 3.16-3.07 6.5-2.28l1.67.39c4.19.98 5.47 3.05 4.49 7.23Z" fill="currentColor"/>
|
||||
<path d="M15.06 19.39c-.62.42-1.4.77-2.35 1.08l-1.58.52c-3.97 1.28-6.06.21-7.35-3.76L2.5 13.28c-1.28-3.97-.22-6.07 3.75-7.35l1.58-.52c.41-.13.8-.24 1.17-.31-.3.61-.54 1.35-.74 2.2l-.98 4.19c-.98 4.18.31 6.24 4.48 7.23l1.68.4c.58.14 1.12.23 1.62.27Zm2.43-8.88c-.06 0-.12-.01-.19-.02l-4.85-1.23a.75.75 0 0 1 .37-1.45l4.85 1.23a.748.748 0 0 1-.18 1.47Z" fill="currentColor" />
|
||||
<path d="M14.56 13.89c-.06 0-.12-.01-.19-.02l-2.91-.74a.75.75 0 0 1 .37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z" fill="currentColor" />
|
||||
<path d="m21.66 10.44-.98 4.18c-.84 3.61-2.5 5.07-5.62 4.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2 1.17-2.42 3.16-3.07 6.5-2.28l1.67.39c4.19.98 5.47 3.05 4.49 7.23Z" fill="#c9d1d9"/>
|
||||
<path d="M15.06 19.39c-.62.42-1.4.77-2.35 1.08l-1.58.52c-3.97 1.28-6.06.21-7.35-3.76L2.5 13.28c-1.28-3.97-.22-6.07 3.75-7.35l1.58-.52c.41-.13.8-.24 1.17-.31-.3.61-.54 1.35-.74 2.2l-.98 4.19c-.98 4.18.31 6.24 4.48 7.23l1.68.4c.58.14 1.12.23 1.62.27Zm2.43-8.88c-.06 0-.12-.01-.19-.02l-4.85-1.23a.75.75 0 0 1 .37-1.45l4.85 1.23a.748.748 0 0 1-.18 1.47Z" fill="#228e6c" />
|
||||
<path d="M14.56 13.89c-.06 0-.12-.01-.19-.02l-2.91-.74a.75.75 0 0 1 .37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z" fill="#228e6c" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 890 B After Width: | Height: | Size: 862 B |
3
scripts/assets/styled-components.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em">
|
||||
<path d="m16.214 6.762-.075.391c-.116.741-.074.953.244 1.228l.307.254-.318 1.418c-.19.846-.423 1.555-.571 1.788-.127.201-.275.497-.307.656-.053.19-.233.381-.508.55-.243.138-.72.508-1.058.805-.27.243-.456.392-.557.456l-.33.261a1.4 1.4 0 0 0-.189.411c-.023.107-.01.178.024.23.033.05.09.085.168.107a.954.954 0 0 0 .282.023 3 3 0 0 0 .632-.112c.07-.019.125-.037.173-.053.074-.091.245-.263.548-.562.804-.793 1.111-1.227.794-1.11-.117.042-.064-.064.137-.276.424-.413.667-1.037 1.175-2.994.402-1.545.402-1.567.698-1.567.139 0 .532.024.532.024V6.762h-.902zm3.839 3.165c-.064 0-.17.096-.233.202-.116.19.021.306 1.767 1.396 1.037.657 1.873 1.217 1.852 1.26-.021.031-.868.582-1.883 1.217-1.842 1.142-1.852 1.153-1.683 1.386.212.275 0 .37 2.391-1.122L24 13.155v-.836l-1.937-1.196c-1.047-.656-1.957-1.185-2.01-1.196zm-16.085.117c-.053 0-.963.54-2.01 1.185L0 12.425v.836l1.947 1.217c1.08.666 1.99 1.217 2.032 1.217.042 0 .127-.096.212-.212.127-.201.02-.286-1.768-1.418C.72 12.996.54 12.848.71 12.732c.106-.074.91-.572 1.778-1.111 1.979-1.217 1.873-1.133 1.714-1.387-.063-.105-.17-.2-.233-.19zm8.684.023c-.292-.002-.92.443-2.8 1.978-.081.193-.088.326-.051.412.024.059.068.1.129.13.06.03.138.048.224.055.171.015.373-.012.536-.044l.11-.025a.386.386 0 0 1 .144-.118c.116-.064.603-.508 1.09-.984.857-.868 1.058-1.26.709-1.387a.24.24 0 0 0-.09-.017zm2.196.603c-.257.007-.72.305-1.513.938-.398.323-.65.497-.785.533l-.524.414c-.197.36-.226.583-.174.706a.25.25 0 0 0 .138.134.644.644 0 0 0 .24.045 2.18 2.18 0 0 0 .58-.085 3.466 3.466 0 0 0 .291-.092l.029-.012.053-.028c.1-.129.33-.372.618-.652.91-.878 1.375-1.502 1.28-1.735-.043-.113-.117-.17-.233-.166zm-2.424 1.08c-.074.008-.24.136-.539.398-.432.382-.903.602-1.066.504a3.97 3.97 0 0 1-.114.024c-.166.033-.373.06-.558.045a.708.708 0 0 1-.252-.063.337.337 0 0 1-.168-.17c-.037-.09-.037-.202.005-.345l-.65.534-1.471 1.217v1.973l4.82-3.797a.41.41 0 0 1 .016-.123c.037-.134.035-.202-.023-.196zm2.074.639c-.073 0-.195.103-.39.31-.265.283-.682.557-.903.613l-.034.018a2.191 2.191 0 0 1-.11.042c-.06.02-.138.044-.228.068-.18.049-.404.094-.604.089a.732.732 0 0 1-.275-.054.344.344 0 0 1-.184-.18c-.058-.139-.035-.334.092-.611L7.61 16.033v1.205h1.868l3.962-3.112c.103-.114.258-.27.467-.465.56-.519.687-.698.687-.963 0-.206-.023-.31-.096-.31zm.943 1.95-.339.338c-.19.18-.529.402-.761.497l-.046.02-.003.005-.01.01c-.009.007-.013.008-.02.011a3.432 3.432 0 0 1-.282.093 3.058 3.058 0 0 1-.65.115 1.035 1.035 0 0 1-.31-.027.364.364 0 0 1-.218-.144c-.048-.074-.062-.173-.035-.295a1.11 1.11 0 0 1 .095-.25l-3.197 2.526h4.252l.508-.582c.698-.814 1.016-1.396 1.016-1.894z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
3
scripts/assets/sublime-text.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em">
|
||||
<path d="M20.953.004a.397.397 0 0 0-.18.017L3.225 5.585c-.175.055-.323.214-.402.398a.42.42 0 0 0-.06.22v5.726a.42.42 0 0 0 .06.22c.079.183.227.341.402.397l7.454 2.364-7.454 2.363c-.255.08-.463.374-.463.655v5.688c0 .282.208.444.463.363l17.55-5.565c.237-.075.426-.336.452-.6.003-.022.013-.04.013-.065V12.06c0-.281-.208-.575-.463-.656L13.4 9.065l7.375-2.339c.255-.08.462-.375.462-.656V.384c0-.211-.117-.355-.283-.38z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 532 B |
4
scripts/assets/vue2.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" height="1em" width="1em">
|
||||
<path d="m12 12.765 5.592-9.437h-3.276L12 7.33v.002L9.688 3.328h-3.28z"/>
|
||||
<path d="M18.461 3.332 12 14.235 5.539 3.332H1.992L12 20.672l10.008-17.34z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 269 B |
4
scripts/assets/xpath.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" height="1em" width="1em">
|
||||
<path fill="none" d="M0 0h24v24H0z"/>
|
||||
<path d="M10 2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H8v2h5V9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H8v6h5v-1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H7a1 1 0 0 1-1-1V8H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h6zm9 16h-4v2h4v-2zm0-8h-4v2h4v-2zM9 4H5v2h4V4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 449 B |
6
scripts/assets/yaml.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em" viewBox="0 0 512 470.647">
|
||||
<polygon points="235.793 0 143.978 137.674 143.978 224.949 87.702 224.949 87.702 137.674 0 0 63.25 0 119.018 88.646 175.243 0 235.793 0 235.793 0"/>
|
||||
<path d="M330.294,175.451h-101.861l-20.717,50.024h-45.106l95.38,-224.949h46.137l91.51,224.949h-48.2l-17.144,-50.024zm-16.92,-44.911l-31.226,-82.55l-34.837,82.55h66.063z"/>
|
||||
<polygon points="87.701 250.177 87.701 470.647 135.004 470.647 135.004 318.569 184.509 420.789 221.743 420.789 272.939 314.976 272.939 470.602 318.318 470.602 318.318 250.177 256.358 250.177 201.381 349.883 149.021 250.177 87.701 250.177 87.701 250.177"/>
|
||||
<polygon points="512 422.735 395.638 422.735 395.638 250.125 347.442 250.125 347.442 469.647 512 469.647 512 422.737 512 422.735"/>
|
||||
</svg>
|
After Width: | Height: | Size: 835 B |
@ -10,8 +10,10 @@ import { rehypeUrls } from './utils/rehypeUrls.mjs';
|
||||
import { tooltips } from './utils/tooltips.mjs';
|
||||
import { homeCardIcons } from './utils/homeCardIcons.mjs';
|
||||
import { getTocsTree } from './utils/getTocsTree.mjs';
|
||||
import { rehypeTitle } from './utils/rehypeTitle.mjs';
|
||||
import { anchorPoint } from './utils/anchorPoint.mjs';
|
||||
|
||||
const favicon = `data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20opacity%3D%22.4%22%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23777%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23999%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23999%22%20%2F%3E%20%3C%2Fsvg%3E`;
|
||||
const favicon = `data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23c9d1d9%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3C%2Fsvg%3E`;
|
||||
|
||||
export function create(str = '', options = {}) {
|
||||
let title = str.match(/[^===]+(?=[===])/g) || [];
|
||||
@ -39,6 +41,7 @@ export function create(str = '', options = {}) {
|
||||
}],
|
||||
],
|
||||
rewrite: (node, index, parent) => {
|
||||
rehypeTitle(node, options.filename);
|
||||
homeCardIcons(node, parent, options.isHome);
|
||||
tooltips(node, index, parent);
|
||||
htmlTagAddAttri(node, options);
|
||||
@ -47,6 +50,7 @@ export function create(str = '', options = {}) {
|
||||
node.children = getTocsTree([ ...node.children ]);
|
||||
node.children.unshift(header(options));
|
||||
node.children.push(footer());
|
||||
node.children.push(anchorPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
body {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
tab-size: 4;
|
||||
@ -117,10 +120,7 @@ body {
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: #e5e7eb;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre {
|
||||
@ -149,7 +149,7 @@ pur {
|
||||
}
|
||||
|
||||
.wrap-body em, .wrap-body sup, .wrap-body sub {
|
||||
color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);
|
||||
color: var(--color-fg-subtle);
|
||||
}
|
||||
|
||||
table {
|
||||
@ -203,8 +203,7 @@ table td:first-child>code {
|
||||
--text-opacity: 1;
|
||||
color: rgb(5 150 105/var(--text-opacity));
|
||||
}
|
||||
table td:first-child>del>code {
|
||||
text-decoration: inherit;
|
||||
table td > del, table td:first-child > del > code, .wrap-body p > del > code {
|
||||
color: var(--color-danger-fg);
|
||||
}
|
||||
|
||||
@ -212,6 +211,26 @@ table.show-header thead {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
table.style-list td + td, table.style-list-arrow td + td {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
table.style-list td, table.style-list-arrow td {
|
||||
display: block;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
table.style-list-arrow td:first-child::before, ul.style-arrow li:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 5px solid transparent;
|
||||
border-left: 6px solid #228e6c;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
tt, code {
|
||||
font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
|
||||
font-size: 1em;
|
||||
@ -282,6 +301,10 @@ body.home .h1wrap .wrap-body p {
|
||||
text-indent: 2rem;
|
||||
}
|
||||
|
||||
body:not(.home) .h2wrap > .wrap-body > ul {
|
||||
list-style: initial;
|
||||
margin-left: 1.2rem;
|
||||
}
|
||||
|
||||
body.home .h1wrap p {
|
||||
text-align: left;
|
||||
@ -293,21 +316,34 @@ body.home .h1wrap p {
|
||||
grid-template-columns: repeat(2,minmax(0,1fr));
|
||||
}
|
||||
|
||||
[data-color-mode*='light'] body .home-card a {
|
||||
--text-opacity: 0.75;
|
||||
color: rgb(15 19 24/var(--text-opacity));
|
||||
}
|
||||
[data-color-mode*='light'] body .home-card a:hover {
|
||||
--text-opacity: 0.85;
|
||||
color: rgb(241 245 249/var(--text-opacity)) !important;
|
||||
}
|
||||
.home-card a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem;
|
||||
padding: 0rem 1rem;
|
||||
height: 4rem;
|
||||
box-shadow: 0 0 #0000,0 0 #0000,0 1px 2px 0 rgba(0,0,0,0.05);
|
||||
color: var(--color-fg-default);
|
||||
--text-opacity: 0.75;
|
||||
color: rgb(241 245 249/var(--text-opacity));
|
||||
--bg-opacity: 0.5;
|
||||
background-color: rgb(62 69 72/var(--bg-opacity));
|
||||
transition: all .3s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.home-card a:hover {
|
||||
--bg-opacity: 1;
|
||||
--text-opacity: 0.75;
|
||||
}
|
||||
.home-card a svg {
|
||||
min-width: 1.6rem;
|
||||
@ -379,6 +415,7 @@ a.text-grey {
|
||||
padding-bottom: 0.5rem;
|
||||
border-radius: 9999px;
|
||||
transition: all .3s;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.header-nav .menu {
|
||||
@ -392,7 +429,6 @@ a.text-grey {
|
||||
font-size: 100%;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
-webkit-appearance: button;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
color: var(--color-fg-default);
|
||||
@ -420,6 +456,11 @@ a.text-grey {
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
margin-bottom: 3rem;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wrap-header.h1wrap > h1 > svg {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.h1wrap-body {
|
||||
@ -447,24 +488,32 @@ a.text-grey {
|
||||
color: rgb(148 163 184/1);
|
||||
}
|
||||
|
||||
body:not(.home) .h2wrap > h2 a::after {
|
||||
body:not(.home) .h2wrap > h2 a::after, body:not(.home) .h3wrap > h3 a::after {
|
||||
content: '#';
|
||||
padding-right: 0.5rem;
|
||||
color: rgb(16 185 129/1);
|
||||
}
|
||||
body:not(.home) .h3wrap > h3 a::after {
|
||||
position: absolute;
|
||||
left: -18px;
|
||||
font-size: 1rem;
|
||||
display: none;
|
||||
}
|
||||
body:not(.home) .h2wrap-body > .wrap:hover .h3wrap > h3 a::after {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.wrap-header.h3wrap {
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.wrap-header.h3wrap > h3 {
|
||||
position: sticky;
|
||||
float: right;
|
||||
margin-top: -24px;
|
||||
color: rgb(226 232 240/1);
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
z-index: 10;
|
||||
border-top-right-radius: 0.5rem;
|
||||
@ -576,6 +625,64 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.h2wrap-body ul.style-timeline {
|
||||
counter-reset: stepCount;
|
||||
}
|
||||
.h2wrap-body ul.style-timeline li:first-child:before {
|
||||
background-color: #228e6c;
|
||||
color: rgb(226 232 240/1);
|
||||
}
|
||||
.h2wrap-body ul.style-timeline li::before {
|
||||
color: #228e6c;
|
||||
background-color: #fff;
|
||||
counter-increment: stepCount;
|
||||
content: counter(stepCount);
|
||||
border-radius: initial;
|
||||
border-radius: 0.5rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
text-align: center;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.30rem;
|
||||
border: 2px solid #228e6c;
|
||||
top: -1px;
|
||||
left: -14px;
|
||||
}
|
||||
.h2wrap-body ul.style-timeline li:last-child {
|
||||
border-image: linear-gradient(to bottom,#228e6c,rgba(0,0,0,0)) 1 100%;
|
||||
}
|
||||
.h2wrap-body ul.style-timeline li {
|
||||
border-bottom: 0 !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 25px !important;
|
||||
border-left: 2px solid #228e6c;
|
||||
margin-left: 30px;
|
||||
}
|
||||
.h2wrap-body ul.style-timeline li > pre {
|
||||
padding: 0 !important;
|
||||
padding-top: 10px !important;
|
||||
height: initial !important;
|
||||
}
|
||||
|
||||
.h2wrap-body ul.style-round li::before {
|
||||
border-radius: 9999px;
|
||||
border-width: 2px;
|
||||
height: 0.5rem;
|
||||
width: 0.5rem;
|
||||
border-color: #228e6c;
|
||||
background: transparent;
|
||||
border-style: solid;
|
||||
top: 14px;
|
||||
}
|
||||
|
||||
.h2wrap-body ul.style-arrow li:before {
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
border-radius: initial;
|
||||
left: 16px;
|
||||
top: 13px;
|
||||
}
|
||||
|
||||
.wrap-body ul:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -584,7 +691,10 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.h3wrap hr {
|
||||
.h3wrap hr, .h3wrap-body hr {
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: #e5e7eb;
|
||||
border-bottom: 1px solid var(--color-border-default);
|
||||
}
|
||||
|
||||
@ -609,6 +719,11 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
border-radius: 0 0 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.h2wrap-body > .wrap.active {
|
||||
box-shadow: 0 0 0 1.6pt #10b981;
|
||||
transition: box-shadow 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.code-highlight {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
@ -629,6 +744,9 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
.cols-5 {
|
||||
grid-template-columns: repeat(5,minmax(0,1fr)) !important;
|
||||
}
|
||||
.cols-6 {
|
||||
grid-template-columns: repeat(6,minmax(0,1fr)) !important;
|
||||
}
|
||||
.col-span-2 {
|
||||
grid-column: span 2/span 2;
|
||||
}
|
||||
@ -638,6 +756,9 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
.col-span-4 {
|
||||
grid-column: span 4/span 4;
|
||||
}
|
||||
.col-span-5 {
|
||||
grid-column: span 5/span 5;
|
||||
}
|
||||
.row-span-2 {
|
||||
grid-row: span 2/span 2;
|
||||
}
|
||||
@ -647,6 +768,9 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
.row-span-4 {
|
||||
grid-row: span 4/span 4;
|
||||
}
|
||||
.row-span-5 {
|
||||
grid-row: span 5/span 5;
|
||||
}
|
||||
.wrap-text {
|
||||
white-space: pre-wrap !important;
|
||||
overflow-wrap: break-word !important;
|
||||
@ -795,19 +919,16 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-card {
|
||||
grid-template-columns: repeat(4,minmax(0,1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 375px) {
|
||||
@media only screen and (max-width: 375px) {
|
||||
.header-nav .title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.header-nav .max-container {
|
||||
padding-top: 0.85rem;
|
||||
}
|
||||
.header-nav .menu a, .header-nav .menu button {
|
||||
padding: 0.2rem 0.3rem;
|
||||
}
|
||||
.wrap-header.h1wrap > h1 {
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2rem;
|
||||
@ -816,15 +937,21 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
margin-top: 1.6rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.wrap-header.h2wrap > h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
.wrap-header.h3wrap > .wrap-body {
|
||||
overflow: auto;
|
||||
}
|
||||
.tooltip:hover .tooltiptext {
|
||||
display: none;
|
||||
}
|
||||
.h1wrap-body {
|
||||
gap: 2rem;
|
||||
}
|
||||
.home-card {
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrap-header.h2wrap > h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
a.home-button {
|
||||
padding-left: 1.1rem;
|
||||
padding-right: 1.1rem;
|
||||
@ -835,4 +962,23 @@ body:not(.home) .h2wrap > h2 a::after {
|
||||
.footer-wrap {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
table td, table th {
|
||||
display: block;
|
||||
text-align: left !important;
|
||||
}
|
||||
table td + td, table th + th {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-card {
|
||||
grid-template-columns: repeat(4,minmax(0,1fr));
|
||||
}
|
||||
.wrap-header.h3wrap > .wrap-body {
|
||||
overflow: initial;
|
||||
}
|
||||
.tooltip:hover .tooltiptext {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
30
scripts/utils/anchorPoint.mjs
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
const scripts = `
|
||||
if(('onhashchange' in window) && ((typeof document.documentMode==='undefined') || document.documentMode==8)) {
|
||||
window.onhashchange = function () {
|
||||
anchorPoint()
|
||||
};
|
||||
}
|
||||
function anchorPoint() {
|
||||
const hash = window.location.hash?.replace(/^#/, '') || '';
|
||||
const elm = document.getElementById(decodeURIComponent(hash));
|
||||
Array.from(document.querySelectorAll('.h2wrap-body .wrap')).forEach((elm) => elm.classList.remove('active'))
|
||||
if (elm?.tagName === 'H3') {
|
||||
elm?.parentElement?.parentElement?.classList.add('active');
|
||||
const box = elm?.parentElement?.parentElement;
|
||||
console.log('elm:2', box, document.querySelectorAll('.h2wrap-body .wrap'))
|
||||
}
|
||||
}
|
||||
anchorPoint();
|
||||
`;
|
||||
|
||||
export function anchorPoint() {
|
||||
return {
|
||||
type: 'element',
|
||||
tagName: 'script',
|
||||
children: [{
|
||||
type: 'text',
|
||||
value: scripts,
|
||||
}]
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { getSVGNode } from './getSVGNode.mjs';
|
||||
|
||||
const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets')
|
||||
export const ICONS_PATH = path.resolve(process.cwd(), 'scripts/assets')
|
||||
|
||||
export function homeCardIcons(node, parent, isHome) {
|
||||
if (isHome && node && node.type === 'element' && node.properties?.class?.includes('home-card')) {
|
||||
|
19
scripts/utils/rehypeTitle.mjs
Normal file
@ -0,0 +1,19 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { getSVGNode } from './getSVGNode.mjs';
|
||||
import { ICONS_PATH } from './homeCardIcons.mjs';
|
||||
|
||||
export function rehypeTitle(node, iconName) {
|
||||
if (node.type === 'element' && node.tagName === 'h1' && iconName !== 'index') {
|
||||
const iconPath = path.resolve(ICONS_PATH, `${iconName}.svg`);
|
||||
const iconDefaultPath = path.resolve(ICONS_PATH, `list.svg`);
|
||||
const iconExist = fs.existsSync(iconPath);
|
||||
if (iconExist) {
|
||||
const svgNode = getSVGNode(iconPath);
|
||||
node.children = [ ...svgNode, ...node.children ];
|
||||
} else {
|
||||
const svgNode = getSVGNode(iconDefaultPath);
|
||||
node.children = [ ...svgNode, ...node.children ];
|
||||
}
|
||||
}
|
||||
}
|