From 41459c48197851a887bd574ee48cce34ce56941c Mon Sep 17 00:00:00 2001 From: haishan Date: Wed, 20 Oct 2021 12:01:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD(md):=20=E6=96=B0?= =?UTF-8?q?=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/bed/go/intro.md | 57 ++++++++ docs/db/mongodb/intro.md | 243 +++++++++++++++++++++++++++++++++++ docs/db/redis/install.md | 44 +++++++ docs/db/redis/intro.md | 128 ++++++++++++++++++ docs/fea/Q&A/index.md | 92 ++++++++++++- docs/fea/css/index.md | 7 +- docs/fea/{ => css}/sass.md | 8 +- docs/fea/norms.md | 6 +- docs/fea/{ => tools}/CI.md | 6 +- docs/fea/tools/lerna.md | 124 ++++++++++++++++++ docs/fea/{ => tools}/seo.md | 8 +- docs/fea/webgl/intro.md | 37 ++++++ docs/interview/html.md | 215 +++++++++++++++++++++++++++++++ docs/interview/javascript.md | 2 +- docs/tools/docker.md | 56 ++++++++ docs/tools/git.md | 1 + docs/tools/homebrew.md | 34 +++++ docs/tools/https.md | 97 ++++++++++++++ docs/tools/jenkins.md | 70 ++++++++++ docs/tools/npm.md | 52 ++++++++ docs/tools/pm2.md | 143 +++++++++++++++++++++ 21 files changed, 1412 insertions(+), 18 deletions(-) create mode 100644 docs/bed/go/intro.md create mode 100644 docs/db/mongodb/intro.md create mode 100644 docs/db/redis/install.md create mode 100644 docs/db/redis/intro.md rename docs/fea/{ => css}/sass.md (98%) rename docs/fea/{ => tools}/CI.md (98%) create mode 100644 docs/fea/tools/lerna.md rename docs/fea/{ => tools}/seo.md (98%) create mode 100644 docs/fea/webgl/intro.md create mode 100644 docs/interview/html.md create mode 100644 docs/tools/docker.md create mode 100644 docs/tools/homebrew.md create mode 100644 docs/tools/https.md create mode 100644 docs/tools/jenkins.md create mode 100644 docs/tools/npm.md create mode 100644 docs/tools/pm2.md diff --git a/docs/bed/go/intro.md b/docs/bed/go/intro.md new file mode 100644 index 0000000..eb15d13 --- /dev/null +++ b/docs/bed/go/intro.md @@ -0,0 +1,57 @@ +--- +nav: + title: 后端 + path: /bed +group: + title: Go + order: 1 +--- + +# 快速上手 + +## 配置 +### 1、目录结构 + + - ① pkg 打包后的路径 + - ② src 开发路径 + - ③ bin 应用程序 +### 2、两大配置路径 + + - gopath: $PATH + - goroot: $PATH +### 3、查看当前环境配置 + + - go env +### 4、设置环境变量 + + - vim ~/.profile 输入以下: + - export GOROOT=/usr/local/go + - export PATH=$PATH:GOROOT/bin +## 知识点 +### 常量定义 + + - 显式:const identifier type = value + - 隐式:const identifier = value(无类型常量) + - 特殊常量 iota + - 介绍 + - 每次碰到 const 会被重置为 0,如果没碰到每新增一个常量声明,就会自增 +1 + - 使用技巧 + - 跳值使用法:使用 _ , 每一个 _ 能使 iota 的值跳过 1 , 要跳多少就给多少个 _ + - 插队使用法:在变量声明中再插入一个赋值的变量不会对 iota 自增产生影响 + - 隐式使用法:如果不声明值,则默认使用最后一个表达式的赋值格式 +### 并发和并行 + + - 并发 + - 单核上,通过任务的来回切换达到类似同时进行 + - 并行 + - 两个任务同时执行 +### go 包源切换 + +```json +- vim ~/.bash_profile + - 输入: + - # 启用 Go Modules 功能 + - export GO111MODULE=on + - # 配置 GOPROXY 环境变量 + - export GOPROXY=[https://goproxy.io](https://goproxy.io) +``` diff --git a/docs/db/mongodb/intro.md b/docs/db/mongodb/intro.md new file mode 100644 index 0000000..e0dd1d7 --- /dev/null +++ b/docs/db/mongodb/intro.md @@ -0,0 +1,243 @@ +--- +nav: + title: 数据库 + path: /db +group: + title: 💊 mongoDB + order: 1 +--- + +# 💊 mongoDB + +## mac 安装 +### 1.1 到官网下载指定版本的安装包 +[https://www.mongodb.com/try/download/community?jmp=nav](https://www.mongodb.com/try/download/community?jmp=nav) + + +### 1.2 将安装包放到指定文件夹 +```javascript +open /usr/local +``` +### +### 1.3 配置数据库data目录 +```javascript +sudo mkdir -p /data/db +``` +## +### 1.4 配置环境变量 +```javascript +# 1. 打开 bash 文件 +open ~/.bash_profile + +# 2. 在 bash 中写入 +PATH=$PATH:/usr/local/mongoDB/bin + +# 3. 保存 bash,并触发生效 +source ~/.bash_profile +``` +## +### 1.5 启动 mongodb + + +```javascript +mongod --dbpath /usr/local/mongodb/db + +mongod --dbpath /usr/local/mongodb/db -f /etc/mongod.conf +``` +## centOS安装 +### 2.1 添加源 + + - sudo vi /etc/yum.repos.d/mongodb-org-4.0.repo +### 2.2 添加配置信息 + + - [mongodb-org-4.0] + - name=MongoDB Repository + - baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/ + - gpgcheck=1 + - enabled=1 + - gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc +### 2.3 安装 + + - sudo yum install -y mongodb-org +### 2.4 检验 + + - rpm -qa |grep mongodb + - rpm -ql mongodb-org-server +### 2.4 启动服务 + + - 建议加上 --auth 权限验证 + - service mongod start + - systemctl start mongod.service + + + +> 通过本地文件启动:mongod -f /usr/local/mongodb/mongodb.conf + +### 2.5 查看端口 + + - netstat -natp | grep 27017 +### 2.6 查看是否成功 + + - ps -aux | grep mongod # 查看数据库的进程是否存在 +### 2.7 开机自启 + + - chkconfig mongod on + - systemctl enable mongod.service +### 2.8 关闭 +```javascript +pkill mongod +``` +## 目录介绍 +### 配置文件: + + +/etc/mongod.conf +```json +port=27017 #端口 +dbpath=/usr/local/mongodb/db #数据库文件存放目录 +logpath=/usr/local/mongodb/logs/mongodb.log #日志文件存放路径 +logappend=true #使用追加的方式写日志 +fork=true #以守护进程的方式,创建服务器进程 +maxConns=100 #最大同时连接数 +journal=true #每次写入会记录一条操作日志 +bind_ip=0.0.0.0 #可外部访问 +auth=true #用户认证 +``` +### +### 数据库保存目录: + + - /usr/local/mongodb/db +### 日志目录: + + - /usr/local/mongodb/logs/mongodb.log +> 如果需要修改数据目录和日志目录,只需修改 /etc/mongod.conf 中的 storage.dbPath 和 systemLog.path 即可。 + +## +## 卸载 +### 4.1 关闭服务 +```json +service mongod stop + +or + +systemctl stop mongod.service + +``` +### 4.2 删除相关的包 +```json +yum erase $(rpm -qa | grep mongodb-org) +``` +### 4.3 删除目录和文件 +```json +rm -r /var/log/mongodbrm -r /var/lib/mongo +``` +### 4.4 彻底卸载 +```json +sudo yum erase $(rpm -qa | grep mongodb-org) # 卸载 +MongoDB sudo rm -r /var/log/mongodb # 删除日志文件 +sudo rm -r /var/lib/mongo # 删除数据文件 +``` + + +## 常见命令 +### 登录 +```javascript +• mongo '数据库名' -u '用户名' -p '密码' +``` +### 重启 +```javascript +sudo service mongod restart +``` +### 查看日志 +```javascript +/var/log/mongo/mongod.log +``` +### 命令行打开 +```javascript +• sudo mongod --port 27017 --dbpath /data/db --bind_ip 0.0.0.0 --auth -f /etc/mongod.conf +``` +### +### 用户权限 + + +#### 权限列表 + + +- .1. 数据库用户角色:read、readWrite; +- .2. 数据库管理角色:dbAdmin、dbOwner、userAdmin; +- .3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; +- .4. 备份恢复角色:backup、restore; +- .5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase +- .6. 超级用户角色:root +- // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase) +- .7. 内部角色:__system + + + +#### 新增用户 +```javascript +// 切换根数据库 +use admin +// 创建用户 +db.createUser({user:"h5creator",pwd:"123456mjw",roles:[{role:"dbAdmin",db:"test"}]}) +// 登录用户 +db.auth(${name}, ${pwd}) +``` +### +#### 修改用户权限 +```javascript +db.grantRolesToUser("h5creator",[{role:"readWrite", db:"test"}]) +``` + + +#### 更新字段 +```javascript +db.collection.update( + , + , + { + upsert: , // 如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。 + multi: , // 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新 + writeConcern: // 抛出异常的级别 + } +) + +// 删除一个 key 字段 +db.collection.update({},{"$unset":{"key":""}},{multi:true}) + +// 新增一个 type 字段 +db.getCollection('article').update({}, {$set: {type:NumberInt('1')}}, {multi: true}) +``` + + +### 开发对外端口 +#### 方案一 +```javascript +• systemctl status firewalld # 查看防火墙状态 +• firewall-cmd --zone=public --add-port=27017/tcp --permanent # mongodb默认端口号 +• firewall-cmd --reload # 重新加载防火墙 +• firewall-cmd --zone=public --query-port=27017/tcp # 查看端口号是否开放成功,输出yes开放成功,no则失败 +``` +#### 方案二 +```javascript +• iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 27017 -j ACCEPT +``` +## 偶遇问题 +### 1) Failed to unlink socket file /tmp/mongodb-27017.sock Operation not permitted + + - 解决方案:删除该文件 +### 2) Unable to lock file: /var/lib/mongo/mongod.lock + + - 解决方案:清空该文件内容 +### 3) 无法持续运行在后台 + + - 解决方案:mongod --fork --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/logs/mongodb2.log --logappend +4. 无法启动 mongodb +> 1. 进入 mongod 上一次启动的时候指定的 data 目录 --dbpath=/data/mongodb +> +删除掉该文件: +> rm /data/db/mongo.lock +> 2. 修复 +> +./mongod --repair + diff --git a/docs/db/redis/install.md b/docs/db/redis/install.md new file mode 100644 index 0000000..27bf4bf --- /dev/null +++ b/docs/db/redis/install.md @@ -0,0 +1,44 @@ +--- +nav: + title: 数据库 + path: /db +group: + title: 💊 redis + order: 2 +--- + +# 安装与配置 + +- redis-cli -h 101.132.156.228 -a  r-uf60a44b13666134:'123456Jzx' +## 在云服务器 ECS Linux 中安装 rinetd。 + + - wget [http://www.boutell.com/rinetd/http/rinetd.tar.gz&&tar](http://www.boutell.com/rinetd/http/rinetd.tar.gz&&tar) -xvf rinetd.tar.gz&&cd rinetd + - sed -i 's/65536/65535/g' rinetd.c (修改端口范围) + - mkdir /usr/man&&make&&make install + - > 注意:rinetd 安装包下载地址不确保下载可用性,您可以自行搜索安装包进行下载使用。 +## 2.打开配置文件 rinetd.conf。 + + - vi /etc/rinetd.conf +> 注意:配置文件可能为 /usr/local/etc/redis.conf + +## 3.在配置文件中输入如下内容: + + - 0.0.0.0 6379 Redis 的链接地址 6379 + - logfile /var/log/rinetd.log + - 说明:您可以使用 cat /etc/rinetd.conf命令来检验配置文件是否修改正确。 + - ![](https://cdn.nlark.com/yuque/0/2020/jpeg/195884/1597937067295-ee517e33-e17f-4d26-bfce-f262d66758bd.jpeg#height=47&id=nkYr8&originHeight=47&originWidth=647&originalType=binary&ratio=1&size=0&status=done&style=none&width=647) + - + +## 4.执行如下命令启动 rinetd。 + + - rinetd + - 注意 + - 您可以通过 echo rinetd >>/etc/rc.local 将 rinetd 设置为自启动。 + - 若遇到绑定报错,可以执行 pkill rinetd 结束进程,再执行 rinetd启动进程 rinetd。 + - rinetd 正常启动后, 执行netstat -anp | grep 6379 确认服务是否正常运行。 + - ![](https://cdn.nlark.com/yuque/0/2020/jpeg/195884/1597937067341-f158e903-fe66-4375-95ff-cfeda4b2a232.jpeg#height=61&id=jafrb&originHeight=61&originWidth=980&originalType=binary&ratio=1&size=0&status=done&style=none&width=980) +## 5.在本地进行验证测试。 + + - 您可以在本地通过 redis-cli 连接 ECS Linux 服务器后进行登录验证,比如安装了 rinetd 的服务器的 IP 是 1.1.1.1,即redis-cli -h 1.1.1.1 -a Redis的实例ID:Redis密码。或者通过 telent 连接 ECS Linux 服务器后进行操作验证。假设 ECS Linux 服务器的 IP 是 1.1.1.1,即 telnet 1.1.1.1 6379。 + - 连接上 ECS Linux 服务器后,输入连接 Redis 的密码:auth Redis的连接密码。 + - 进行数据写入及查询验证。 diff --git a/docs/db/redis/intro.md b/docs/db/redis/intro.md new file mode 100644 index 0000000..6b178e5 --- /dev/null +++ b/docs/db/redis/intro.md @@ -0,0 +1,128 @@ +--- +nav: + title: 数据库 + path: /db +group: + title: 💊 redis + order: 1 +--- + +# 环境搭建 + +## 下载 + + +[官方网站](https://redis.io/) + + +## 安装 + + +```javascript +解压 +tar zxvf redis-4.0.8.tar.gz +移动文件夹 +mv redis-4.0.8 /usr/local/ +打开该文件夹 +cd /usr/local/redis-4.0.8/ +编译测试 +sudo make test +编译安装 +sudo make install +``` + + +## 启动 + + +```javascript +redis-server +``` + + +## 配置 + +### 新建目录 +``` +sudo mkdir redis-4.0.8/bin +sudo mkdir redis-4.0.8/etc +sudo mkdir redis-4.0.8/db +``` + +### 拷贝文件 + +``` +cp src/mkreleasehdr.sh bin +cp src/redis-benchmark bin +cp src/redis-check-rdb bin +cp src/redis-cli bin +cp src/redis-server bin +``` + +## 修改redis.conf + + +```t +#修改为守护模式 +daemonize yes +#设置进程锁文件 +pidfile /usr/local/redis-3.2.8/redis.pid +#端口 +port 6379 +#客户端超时时间 +timeout 300 +#日志级别 +loglevel debug +#日志文件位置 +logfile /usr/local/redis-3.2.8/log-redis.log +#设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id +databases 16 +##指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 +#save +#Redis默认配置文件中提供了三个条件: +save 900 1 +save 300 10 +save 60 10000 +#指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间, +#可以关闭该#选项,但会导致数据库文件变的巨大 +rdbcompression yes +#指定本地数据库文件名 +dbfilename dump.rdb +#指定本地数据库路径 +dir /usr/local/redis-3.2.8/db/ +#指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能 +#会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有 +#的数据会在一段时间内只存在于内存中 +appendonly no +#指定更新日志条件,共有3个可选值: +#no:表示等操作系统进行数据缓存同步到磁盘(快) +#always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) +#everysec:表示每秒同步一次(折衷,默认值) +appendfsync everysec +``` + + +## 启动服务 + + +### 启动 +> ./bin/redis-server etc/redis.conf + +### 查看日志 +> tail -f log-redis.log + +### OK +> ./bin/redis-cli + +## 基本命令 + + +### 查看所有数据 +> keys * + +### 插入键值对 +> set a b + +### 查看数据 +> get a + diff --git a/docs/fea/Q&A/index.md b/docs/fea/Q&A/index.md index 74b02f3..b6ee712 100644 --- a/docs/fea/Q&A/index.md +++ b/docs/fea/Q&A/index.md @@ -7,4 +7,94 @@ group: order: 100 --- -## 问题合集 \ No newline at end of file +# 💊 Q&A + +## 通过浏览器打开https后,无法再次打开http链接? + + +请将下面这串代码删除,删干净一点: +```javascript + +``` + + +## 阿里云 oss 上传 + + +### 创建bucket + +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156371487-2e7a495b-c225-4ed4-82a3-ab28f7dfa4e2.png#height=363&id=r7ZCt&margin=%5Bobject%20Object%5D&name=image.png&originHeight=726&originWidth=473&originalType=binary&ratio=1&size=187718&status=done&style=none&width=236.5) +### 设置跨域规则 + +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156400297-4528de9b-e249-4f15-bdd1-9ae07bf8c2df.png#height=329&id=Kws6W&margin=%5Bobject%20Object%5D&name=image.png&originHeight=657&originWidth=629&originalType=binary&ratio=1&size=62533&status=done&style=none&width=314.5) +### 创建 RAM 用户 + + +> 这一步的作用是分担风险,不要直接用主账号去登录 + +并给该用户分配调用 STS 服务 AssumeRole 接口的权限,这样待会儿后端就能以该用户的身份给前端分配 STS 凭证了: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156480237-912d579e-2e46-4738-996c-991810b0121a.png#height=280&id=GWXB4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=560&originWidth=1456&originalType=binary&ratio=1&size=275868&status=done&style=none&width=728) +### 创建用户角色 +该角色即有权限在前端调用 aliyun-oss SDK 上传文件的用户角色,例如我们创建一个只有上传权限的角色,命名为 uploader +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156569197-374d1b4d-87ef-4b83-b888-43e585823b57.png#height=314&id=yH483&margin=%5Bobject%20Object%5D&name=image.png&originHeight=628&originWidth=1396&originalType=binary&ratio=1&size=365279&status=done&style=none&width=698) +接下来我们需要给该角色分配权限,可以通过创建一条权限策略并分配给角色,该权限策略里面只包含了上传文件、分片上传相关的权限: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156596778-1a1bd9f9-675d-4de8-ae9a-fe119187a138.png#height=370&id=M1KQd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=1382&originalType=binary&ratio=1&size=307620&status=done&style=none&width=691) +```javascript +// 策略内容 +{ + "Version": "1", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "oss:PutObject", + "oss:InitiateMultipartUpload", + "oss:UploadPart", + "oss:UploadPartCopy", + "oss:CompleteMultipartUpload", + "oss:AbortMultipartUpload", + "oss:ListMultipartUploads", + "oss:ListParts" + ], + "Resource": [ + "acs:oss:*:*:${bucket}", + "acs:oss:*:*:${bucket}/*" + ] + } + ] +} +``` +然后,把该策略赋予 uploader 角色 +![image.png](https://cdn.nlark.com/yuque/0/2021/png/195884/1614156673094-a4029f4e-63c9-4396-b3bc-d632f4056c7a.png#height=445&id=JrO2L&margin=%5Bobject%20Object%5D&name=image.png&originHeight=890&originWidth=1390&originalType=binary&ratio=1&size=295135&status=done&style=none&width=695) + + +### node 代码实现 +```javascript +const OSS = require('ali-oss'); +const STS = OSS.STS; + +const sts = new STS({ + accessKeyId: process.env.ALIYUN_OSS_RULE_ASSUMER_ACCESS_KEY, + accessKeySecret: process.env.ALIYUN_OSS_RULE_ASSUMER_ACCESS_KEY_SECRET +}); + +async function getCredential(req, res, next) { + try { + const { credentials } = await sts.assumeRole( + 'acs:ram::1582938330607257:role/uploader', // role arn + null, // policy + 15 * 60, // expiration + 'web-client' // session name + ); + req.result = credentials; + next(); + } catch (err) { + next(err); + } +} + +``` +### OSS报错大全 + +1. AccessDeniedError: You have no right to access this object because of bucket acl +> 看下配置的bucket 策略内容对不对 diff --git a/docs/fea/css/index.md b/docs/fea/css/index.md index f2f66ff..990c5bd 100644 --- a/docs/fea/css/index.md +++ b/docs/fea/css/index.md @@ -4,10 +4,11 @@ nav: path: /fea group: title: 💊 css - order: 3 + order: 2 + path: /css --- -## 💊 css +## 效果案例 ### 小球动画 @@ -47,4 +48,4 @@ group: ### 渐变文字 - \ No newline at end of file + diff --git a/docs/fea/sass.md b/docs/fea/css/sass.md similarity index 98% rename from docs/fea/sass.md rename to docs/fea/css/sass.md index 255d208..aa0b1b9 100644 --- a/docs/fea/sass.md +++ b/docs/fea/css/sass.md @@ -3,12 +3,12 @@ nav: title: 前端 path: /fea group: - title: 💊 SASS语法 - order: 8 - path: /sass + title: 💊 css + order: 2 + path: /css --- -## 💊 SASS语法 +## SASS语法 ### if 语句 diff --git a/docs/fea/norms.md b/docs/fea/norms.md index c72c4f8..db29e77 100644 --- a/docs/fea/norms.md +++ b/docs/fea/norms.md @@ -12,13 +12,15 @@ group: ### 使用语义化的命名 -```javascript +**Bad:** + +```js const yyyymmdstr = moment().format("YYYY/MM/DD"); ``` **Good:** -```javascript +```js const currentDate = moment().format("YYYY/MM/DD"); ``` diff --git a/docs/fea/CI.md b/docs/fea/tools/CI.md similarity index 98% rename from docs/fea/CI.md rename to docs/fea/tools/CI.md index d8628ad..72434c8 100644 --- a/docs/fea/CI.md +++ b/docs/fea/tools/CI.md @@ -3,12 +3,12 @@ nav: title: 前端 path: /fea group: - title: 💊 CI持续集成 + title: 💊 工具 order: 9 - path: /ci + path: /tools --- -# 💊 CI持续集成 +# CI持续集成 前后端分离的概念现在已经应用的比较广了,它使我们的工作更加的高效,也提升了后期代码的可维护性,减少人力成本。 diff --git a/docs/fea/tools/lerna.md b/docs/fea/tools/lerna.md new file mode 100644 index 0000000..c64548c --- /dev/null +++ b/docs/fea/tools/lerna.md @@ -0,0 +1,124 @@ +--- +nav: + title: 前端 + path: /fea +group: + title: 💊 工具 + order: 9 + path: /tools +--- + +# lerna + +## 介绍 +lerna 是一个包管理工具,方便在大型开源项目中不需要手动开启多个仓库 + +## 使用方法 + +### 安装 + +> npm i lerna -g + +### 创建子项目 +> lerna create {packageName} + +### 添加依赖 + +```javascript +// 此处用eslint作为案例 + +// 所有 package 都装 +lerna add eslint + +// 只有 package1 安装 +lerna add eslint --scope=package1 + +// 符合 prefix 的包都会安装 +lerna add esint packages/prefix-* +``` + + +> -dev:添加到 devDependencies +> --exact:只安装特定版本 + + + +### 执行 npm script 命令 +```javascript +// 执行所有子项中的 test +lerna run test + +// 执行 package1 中的 test +lerna run --scope package1 test + +// 只执行除了匹配package-*外项目中的 test +lerna run --ignore package-* test + +``` + + +### 查看哪些包需要发布 +```javascript +lerna updated +``` +> - 决定哪一个包需要被publish + + + + + +### 发布依赖包 +```javascript +learna publish +``` +> 建议使用 independent 模式,独立对每个依赖包做管理 +> `--npm-client=cnpm 指定源` + + + +## 常见命令 +| 命令 | 说明 | +| :---: | :---: | +| lerna bootstrap | 安装依赖 | +| lerna clean | 删除各个包下的node_modules | +| lerna init | 创建新的lerna库 | +| lerna list | 显示package列表 | +| lerna changed | 显示自上次relase tag以来有修改的包, 选项通 list | +| lerna diff | 显示自上次relase tag以来有修改的包的差异, 执行 git diff | +| lerna exec | 在每个包目录下执行任意命令 | +| lerna run | 执行每个包package.json中的脚本命令 | +| lerna add | 添加一个包的版本为各个包的依赖 | +| lerna import | 引入package | +| lerna link | 链接互相引用的库 | +| lerna create | 新建package | +| lerna publish | 发布 | + + +## 官方文档 +[http://www.febeacon.com/lerna-docs-zh-cn/](http://www.febeacon.com/lerna-docs-zh-cn/) + + +### Q&A +#### 1. 发布包提示lerna ERR! ENOREMOTEBRANCH Branch 'master' doesn't exist in remote 'origin'. +> git remote -v 查看是否是 origin 指向的分支,推送最新分支 +> lerna publish + + + +#### 2. lerna ERR! E402 You must sign up for private packages +在相应包的 package.json 添加 + +```js + { + ... + "publishConfig": { + "access": "public" + } + } +``` + +#### 使用father打包报错 + +如果是使用的 **yarn** 安装的包,改成 **cnpm** 安装,再试一次 + + diff --git a/docs/fea/seo.md b/docs/fea/tools/seo.md similarity index 98% rename from docs/fea/seo.md rename to docs/fea/tools/seo.md index bae64f1..7611e2d 100644 --- a/docs/fea/seo.md +++ b/docs/fea/tools/seo.md @@ -3,12 +3,12 @@ nav: title: 前端 path: /fea group: - title: 💊 SEO - order: 7 - path: /seo + title: 💊 工具 + order: 9 + path: /tools --- -# 💊 SEO +# SEO ## 介绍 diff --git a/docs/fea/webgl/intro.md b/docs/fea/webgl/intro.md new file mode 100644 index 0000000..7e0cb76 --- /dev/null +++ b/docs/fea/webgl/intro.md @@ -0,0 +1,37 @@ +--- +nav: + title: 前端 + path: /fea +group: + title: 💊 webGL + order: 9 + path: /webGL +--- + +## 介绍 + +### 基本对象 + +* 场景:scence +* 相机:camera +* 相机创建实例图(THREE.PerspectiveCamera(fovy, aspect, zNear, zFar)): +* 渲染器:renderer + + +### 绘制方法 + +* 网孔(Meshes,推荐) +* 多边形(Polygons) +* 顶点(Vertices) + +### 其它 + +* 材料(Materials) +* 纹理(Textures) +* 光照(Lights) +* 变换(Transforms) +* 矩阵(Matrices) +* 相机(Cameras) +* 视角(Perspective) +* 视窗(Viewports) +* 着色器(shader) diff --git a/docs/interview/html.md b/docs/interview/html.md new file mode 100644 index 0000000..fd3559a --- /dev/null +++ b/docs/interview/html.md @@ -0,0 +1,215 @@ +--- +nav: + title: 面试 + path: /interview +group: + title: 💊 面试题库 + order: 4 +--- + +# HTML + +## 开发能力模型 +- 基础开发 - 响应式开发 - 滑屏应用开发 - 动画效果开发 - 游戏开发 + +## 基础页面开发 +### 一、思考流程 + +1. 确定设计稿是否开发友好?还原成本? +2. 确定特殊元素是否有合理的边界处理(比如文案超出、输入框文案校验) +3. 确定页面框架结构:Layout +4. 确定整体网页可复用性组件:Site component +5. 确定当前页面可复用组件:Page component + + + +### 二、编写页面骨骼框架 +#### 盒模型 +margin、border、padding、content +区分元素宽度和盒子宽度(是否包括margin,在css3样式中可以使用:box-sizing:content-box、border-box) + + +#### 布局 + +1. 普通文档布局(display) +2. 浮动布局(float) +3. 绝对布局(position) +4. 弹性布局(display:flex) +5. 网格布局(grad) + + + +#### 语义化 +![屏幕快照 2020-08-23 上午11.54.26.png](https://cdn.nlark.com/yuque/0/2020/png/195884/1598154888954-152e1a38-b189-4bbf-8a5e-49720f81fb1b.png#height=1192&id=swYj7&margin=%5Bobject%20Object%5D&name=%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202020-08-23%20%E4%B8%8A%E5%8D%8811.54.26.png&originHeight=1192&originWidth=1312&originalType=binary&ratio=1&size=408275&status=done&style=none&width=1312) +### 三、填充网页血肉内容 + +切图可以使用 PS 的「生成 > 图像资源」 + +### 四、润色 + +使用bem方式命名 class(block、element、modify) + +### 兼容性测试 + +1. 页面在各浏览器,不同分辨率下是否能正常展示 +2. 网页的功能是否能在各个浏览器中使用 + + + +## 响应式页面 +### 一、添加 viewport meta 标签 +#### pageSpeed 准则 + +推荐在移动端头文件中,添加如下代码: +> + +### 二、使用 Media Queries +#### 六个参数 +| 参数名 | 描述 | +| --- | --- | +| min-width | 当视窗宽度大于或等于指定值时,@media 规则下的样式将被应用 | +| max-width | 当视窗宽度小于或等于指定值时,@media 规则下的样式将被应用 | +| min-height | 当视窗高度大于或等于指定值时,@media 规则下的样式将被应用 | +| max-height | 当视窗高度小于或等于指定值时,@media 规则下的样式将被应用 | +| orientation=portrait | 当视窗高度大于或等于宽度时,@media 规则下的样式将被应用 | +| orientation=landscape | 当视窗宽度大于高度时,@media 规则下的样式将被应用 | + +#### 2种用法 +方法一,使用link标签: + +```js + +``` + +方法二,直接在style中使用: + +```js +@media (max-width: 640px) { + /*当视窗宽度小于或等于 640px 时,这里的样式将生效*/ +} +``` + +### 三、使用viewport单位以及rem +#### 方法一:仅使用vw作为css长度单位 + +1. 利用sass函数将设计稿尺寸转换为vw + +```js +// iPhone 6尺寸作为设计稿基准 +$vw_base: 375; +@function vw($px) { + @return ($px / $vm_base) * 100vw; +} +``` + +2. 无论是文本字号大小还是布局高宽、间距、留白等都使用 vw 作为 CSS 单位 + +```js +.mod_nav { + background-color: #fff; + &_list { + display: flex; + padding: vw(15) vw(10) vw(10); // 内间距 + &_item { + flex: 1; + text-align: center; + font-size: vw(10); // 字体大小 + &_logo { + display: block; + margin: 0 auto; + width: vw(40); // 宽度 + height: vw(40); // 高度 + img { + display: block; + margin: 0 auto; + max-width: 100%; + } + } + &_name { + margin-top: vw(2); + } + } + } +} +``` + +3. 物理像素线(1px),采用transform属性scale实现 + +```js +.mod_grid { + position: relative; + &::after { + // 实现1物理像素的下边框线 + content: ''; + position: absolute; + z-index: 1; + pointer-events: none; + background-color: #ddd; + height: 1px; + left: 0; + right: 0; + top: 0; + @media only screen and (-webkit-min-device-pixel-ratio: 2) { + -webkit-transform: scaleY(0.5); + -webkit-transform-origin: 50% 0%; + } + } +} +``` + +4. 对于需要保持高宽比的图,使用padding-top实现: + +```js +.mod_banner { + position: relative; + // 使用padding-top 实现宽高比为 100:750 的图片区域 + padding-top: percentage(100/750); + height: 0; + overflow: hidden; + img { + width: 100%; + height: auto; + position: absolute; + left: 0; + top: 0; + } +} +``` + +#### 方法二:vw搭配rem,寻找最优解 + +1. 给更元素的字体大小设置随着视窗变化而变化的vw单位,这样就可以实现动态改变其大小 +2. 其它元素的文本字大小、布局高宽、间距、留白使用rem单位 +3. 限制根元素大小的最大最小值,配合 body 加上最大宽度和最小宽度,实现布局宽度的最大最小限制 + +核心代码如下: + +```js +// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推 +$vw_fontsize: 75; // iPhone 6尺寸的根元素大小基准值 +@function rem($px) { + @return ($px / $vw_fontsize ) * 1rem; +} +// 根元素大小使用 vw 单位 +$vw_design: 750; +html { + font-size: ($vw_fontsize / ($vw_design / 2)) * 100vw; + // 同时,通过Media Queries 限制根元素最大最小值 + @media screen and (max-width: 320px) { + font-size: 64px; + } + @media screen and (min-width: 540px) { + font-size: 108px; + } +} +// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小 +body { + max-width: 540px; + min-width: 320px; +} +``` + +## 滑屏应用开发 +### 善用利器 +熟练使用现有的滑动组件 swiper 或者其它 + diff --git a/docs/interview/javascript.md b/docs/interview/javascript.md index 61bb15f..c79eb73 100644 --- a/docs/interview/javascript.md +++ b/docs/interview/javascript.md @@ -4,7 +4,7 @@ nav: path: /interview group: title: 💊 面试题库 - order: 2 + order: 3 --- ## JavaScript diff --git a/docs/tools/docker.md b/docs/tools/docker.md new file mode 100644 index 0000000..56d9ef8 --- /dev/null +++ b/docs/tools/docker.md @@ -0,0 +1,56 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 docker + order: 4 + path: /docker +--- + +# 💊 docker + +## 通过 brew 下载 +> brew cask install docker + +## 设置国内镜像源 +> preference -> deamon(建议阿里云镜像源) + +## 测试 docker 是否可用 + +> docker run -d -p 80:80 --name webserver nginx + +## 用 nginx 镜像启动一个容器,命名为 webserver +停止 +``` +docker stop webserver +docker rm webserver +``` +进入上面命名后的 webserver 容器: +``` +docker exec -it webserver bash (进入容器) +echo 'Hello, Docker!' +/usr/share/nginx/html/index.html(修改容器内容) +exit(退出容器) +commit 复制镜像 +``` + +## 查看镜像近期的改动 +> docker diff + +## 提交信息 +``` +docker commit +--author "Tao Wang twang2218@gmail.com" +--message "修改了默认网页" +webserver +nginx:v2 +``` + +## 查看该镜像的提交记录 + +> docker history nginx:v2 + +## 运行该镜像在81端口 + +> docker run --name web2 -d -p 81:80 nginx:v2 diff --git a/docs/tools/git.md b/docs/tools/git.md index 025b35f..a20f2c7 100644 --- a/docs/tools/git.md +++ b/docs/tools/git.md @@ -5,6 +5,7 @@ nav: group: title: 💊 git order: 1 + path: /git --- # 💊 git diff --git a/docs/tools/homebrew.md b/docs/tools/homebrew.md new file mode 100644 index 0000000..f060ca9 --- /dev/null +++ b/docs/tools/homebrew.md @@ -0,0 +1,34 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 homebrew + order: 2 + path: /homebrew +--- + +# 💊 homebrew + +## 安装脚本 + +苹果电脑标准安装脚本:(推荐 优点全面 缺点慢一点) +``` +/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" +``` +苹果电脑极速安装脚本:(优点安装速度快 缺点update功能需要命令修复 ) +``` +/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" speed +``` +Linux 标准安装脚本: +``` +rm Homebrew.sh ; wget https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh ; bash Homebrew.sh +``` +苹果电脑卸载脚本: +``` +/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/HomebrewUninstall.sh)" +``` +Linux卸载脚本: +``` +rm HomebrewUninstall.sh ; wget https://gitee.com/cunkai/HomebrewCN/raw/master/HomebrewUninstall.sh ; bash HomebrewUninstall.sh +``` diff --git a/docs/tools/https.md b/docs/tools/https.md new file mode 100644 index 0000000..5d832d9 --- /dev/null +++ b/docs/tools/https.md @@ -0,0 +1,97 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 配置https + order: 2 + path: /https +--- + + +# 💊 配置https +[https://learnku.com/articles/33400](https://learnku.com/articles/33400) +​ + +本方法配置https用的是Let’s Encrypt ,系统为centOS +​ + +## 方案1 +​ + +* 一、安装nginx,需要安装ssl,安装过程省略 + +* 二、安装certbot + +> sudo yum install python2-certbot-nginx + +* 三、运行 +> sudo certbot --nginx +如果运行失败,出现包不存在,执行如下操作(以下是个巨坑) : +``` +pip uninstall requests +pip uninstall urllib3 +yum remove python-urllib3 +yum remove python-requests +yum install python-urllib3 +yum install python-requests +yum installcertbot +yum install docker-compose +``` +启动之后会让你输入邮箱、域名等一些信息,很简单,这里就不多说了。 +另外,nginx的server_name需要用你配置的域名,不然无法自动配置 + +* 四、错误处理(不报错请无视) +如果出现这个错误:The error was: NoInstallationError()那就是找不到nginx环境 解决: +``` +ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx +ln -s /usr/local/nginx/conf/ /etc/nginx +``` + +* 五、定时注册 +这里需要注意的是https的服务时间为3个月,需要定时注册,执行以下命令即可 +sudo certbot renew --dry-run +​ + +## 方案2 +## 配置证书 +我们在 etc/nginx/ 目录下新建 ssl 文件夹来存放证书。把 crt 证书文件和 key 私钥文件上传到这里。然后就可以配置 Nginx 配置文件了。 +我的配置文件放在 sites-enabled 文件夹里,我们删掉默认的文件新建一个,具体配置内容可以参考腾讯云的操作指导。 +下面是我的配置文件 +​ + +```javascript +# 配置 http 访问时通过 301 转发到 https 上。 +server{ + listen 80; + server_name example.com www.example.com; + return 301 https://www.example.com$request_uri; +} + +# 证书部分内容配置,注意证书路径写对,其他地方照抄就行了 +server { + listen 443 ssl default_server; + server_name www.example.com; + ssl on; + ssl_certificate /etc/nginx/ssl/1_www.example.com_bundle.crt; + ssl_certificate_key /etc/nginx/ssl/2_www.example.com.key; + ssl_session_timeout 5m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass http://127.0.0.1:8000; + } + +} + +# 这一步把 顶级域名转发到 www 二级域名上,有利于 SEO +server { + listen 443 ssl; + server_name example.com; + return 301 https://www.example.com$request_uri; + +} +``` +第一个server 配置的是把普通 80 端口访问的 http 协议转发到 https 访问。 第二个server 配置的就是证书路径和一些参数,这个照抄就行了,只要把证书路径写对 第三个server 配置的是把不带 www 的顶级域名转发到带 www 的二级域名,利于 SEO. 比如 example.com 会自动跳转到 www.example.com 。 diff --git a/docs/tools/jenkins.md b/docs/tools/jenkins.md new file mode 100644 index 0000000..32e039b --- /dev/null +++ b/docs/tools/jenkins.md @@ -0,0 +1,70 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 jenkins + order: 9 + path: /jenkins +--- + +# 💊 jenkins + +## 安装 java 环境 +### 查看 jdk 列表 + + - yum list java* +### 安装jdk + + - yum install java-1.8.0-openjdk-devel.x86_64 +### 检查是否成功 + + - java -version +## 安装 Jenkins 包 +### ① 下载依赖 + + - sudo wget -O /etc/yum.repos.d/jenkins.repo [https://pkg.jenkins.io/redhat-stable/jenkins.repo](https://pkg.jenkins.io/redhat-stable/jenkins.repo) +### ② 导入密钥 + + - sudo rpm --import [https://pkg.jenkins.io/redhat-stable/jenkins.io.key](https://pkg.jenkins.io/redhat-stable/jenkins.io.key) +### ③ 开始安装 + + - yum install jenkins #等待安装时间较长,约25min +### ④ 查看 Jenkins 安装路径 + + - rpm -ql jenkins +### ⑤ 配置 Jenkins + + - vim /etc/sysconfig/jenkins + - 修改为 JENKINS_PORT="6088" +### ⑥ 启动Jenkins + + - java -jar /usr/lib/jenkins/jenkins.war --httpPort=8080 + - nohup java -jar /usr/lib/jenkins/jenkins.war --httpPort=8088 & + - 若端口被占用则执行:java -jar /usr/lib/jenkins/jenkins.war --ajp13Port=-1 --httpPort=8899 +### ⑦ 查看端口 + + - netstat -ntlp + - netstat -tln | grep 8088 + - sudo lsof -i:8088 +### ⑧关闭端口 + + - sudo kill -9 8088 +### ⑨查看磁盘和分区情况 + + - df -h +## ** 问题解决 +### 1、No valid crumb was included in the request + + - 在jenkins 的Configure Global Security下 , 取消“防止跨站点请求伪造(Prevent Cross Site Request Forgery exploits)”的勾选。 +### 2、git 找不到 + + - yum install git + - whereis git 将路径放在 config tools git 配置里 +### 3、jenkins 打开项目构建很卡 + + - 凭证 - 配置全局凭证:id_rsa +### 4、无法使用 node 等工具 + + - ① source /etc/profile + - ② 安装全局工具插件 diff --git a/docs/tools/npm.md b/docs/tools/npm.md new file mode 100644 index 0000000..3ea0929 --- /dev/null +++ b/docs/tools/npm.md @@ -0,0 +1,52 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 npm 操作手册 + order: 2 + path: /npm +--- + +# 💊 npm 操作手册 + +## 发布npm 包 +### 一、初始化 + + - npm init +### 二、登录 + + - npm config set registry=http://registry.npmjs.org 切换回官方源 + - ([http://registry.npm.taobao.org/](http://registry.npm.taobao.org/)如果是淘宝源) +### 三、发布 + + - npm publish +> 发布@开头的包加上 --access public  + +### 四、删除包 +npm unpublish nicecode-tools --force  + + +### 错误大全 + + - *报错一: npm ERR! unscoped packages cannot be private : jzx-deom + - ·处理:npm publish --access public + - *报错二:"Jzx-deom" is invalid for new packages : Jzx-deom + - ·处理:发布包不允许大写字母 + - 报错三:You do not have permission to publish "deom". Are you logged in as the correct user? : deom + - ·处理:换个包名称,包已存在 +## 升级babel + +- npx babel-upgrade --write --install + + + +## 安装 npm-check + + - $ npm i npm-check -g + - 交互式选择所有 umi 相关依赖更新 + - $ npm-check -u + - # 指定 npm 客户端 +```javascript +NPM_CHECK_INSTALLER=cnpm npm-check -u +``` diff --git a/docs/tools/pm2.md b/docs/tools/pm2.md new file mode 100644 index 0000000..97d793a --- /dev/null +++ b/docs/tools/pm2.md @@ -0,0 +1,143 @@ +--- +nav: + title: 工具 + path: /tools +group: + title: 💊 pm2 + order: 1 + path: /pm2 +--- + +# 💊 pm2 + +## 配置文件说明 +```javascript +{ + "apps": [{ + "exec_mode": "cluster", // 应用启动模式,支持fork和cluster模式 + "instances": 4, // 应用启动实例个数,仅在cluster模式有效 默认为fork;或者 max + "script": "./bin/www", // 执行文件 + "name": "type-node", + "cwd": "./", // 根目录 + "args": "", // 传递给脚本的参数 + "interpreter": "node", // 指定的脚本解释器 + "interpreter_args": "", // 传递给解释器的参数 + "watch": true, // 是否监听文件变动然后重启 + "ignore_watch": [ // 不用监听的文件 + "node_modules", + "logs" + ], + "max_memory_restart": 8, // 最大内存限制数,超出自动重启 + "error_file": "./logs/app-err.log", // 错误日志文件 + "out_file": "./logs/app-out.log", // 正常日志文件 + "merge_logs": true, // 设置追加日志而不是新建日志 + "log_date_format": "YYYY-MM-DD HH:mm:ss", // 指定日志文件的时间格式 + "min_uptime": "60s", // 应用运行少于时间被认为是异常启动 + "max_restarts": 30, // 最大异常重启次数,即小于min_uptime运行时间重启次数; + "autorestart": true, // 默认为true, 发生异常的情况下自动重启 + "cron_restart": "", // crontab时间格式重启应用,目前只支持cluster模式; + "restart_delay": "60s" // 异常重启情况下,延时重启时间 + "env": { + "NODE_ENV": "production", // 环境参数,当前指定为生产环境 process.env.NODE_ENV + "REMOTE_ADDR": "爱上大声地" // process.env.REMOTE_ADDR + }, + "env_dev": { + "NODE_ENV": "development", // 环境参数,当前指定为开发环境 pm2 start app.js --env_dev + "REMOTE_ADDR": "" + }, + "env_test": { // 环境参数,当前指定为测试环境 pm2 start app.js --env_test + "NODE_ENV": "test", + "REMOTE_ADDR": "" + } + }] +} +``` + + +## 通过配置文件启动 +```javascript +pm2 start pm2.json --env production +``` +## ​ + +## 重启 +```javascript +pm2 restart app.js +``` +​ + +## 停止进程 +```javascript +pm2 stop app_name | app_id | all +``` +## 删除进程 +```javascript +pm2 delete app_name | app_id | all +``` +### +### 查看进程列表 +```javascript +pm2 list +``` + + +## 查看某个进程信息 +```javascript +pm2 descripe app_name | app_id +``` +## ​ + +## 查看进程详情 +```javascript +pm2 show {id, appname} +``` + + +## 性能监控 +```javascript +pm2 monit +``` +​ + +## 创建并关闭分组node进程 +```javascript +// 创建 +pm2 start api.js --namespace chihu +pm2 start ssr.js --namespace chihu +pm2 start db.js --namespace chihu +pm2 start monitor.js --namespace chihu + +// 关闭 +pm2 stop chihu +``` + + +## 运行 npm 命令 +pm2 start npm --name "webot" -- run build + +- --watch + - 监听应用目录的变化,一旦发生变化,自动重启。 +- -i + - 启用多少个实例,可用于负载均衡,如果 -i 0 或者 -i max,则根据当前机器核数确定实例数目。 +- --ignore-watch + - 排除监听的目录或文件,可以是特定的文件名,也可以是正则。 +- -n + - 应用的名称,查看应用信息的时候可以用到。 +- -o + - 标准输出日志文件的路径。 +- -e + - 错误输出日志文件的路径。 +- --max-memory-restart 100M + - 内存超过使用上限自动重启 + +​ + +## Q&A +### 1. Cannot find module ****ProcessContainerFork.js + + +``` +rm -rf ~/.pm2 +``` + +