这是我参与新手入门的第1篇文章
从0到1搭建一个Vue3+Vite+Node图床项目
前言
尤大的vue3都发布了那么久了,不会吧不会吧,你不会一点都没看吧 ? [手动滑稽]
Vue3 和 Vite正式版已经出来很长时间了,生态圈也逐渐丰富。不过咋至今也没在项目上用过是不是太掉队伍了,所以咋今天就用Vue3 + Vite + TypeScript + Node脚本来弄一个自动化部署图床。 说真,Vite体验感贼好,大佬诚不欺我
强烈推荐巨佬文章(本文的参照物):从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境
本文篇幅有点长,从以下几个方面展开:
- 架构搭建
- 版本管理
- 自动化部署
技术栈
- 编程语言: TypeScript4.x + JavaScript
- 后端框架: Expresss
- 后端自动化开发工具: Nodemon
- 日志管理工具: Log4js
- 七牛云上传库: qiniu-js
- 前端框架: Vue3.x
- 构建工具: Vite 2.x
- 路由工具: Vue Router
- 状态管理工具: Vuex 4.x
- UI框架: Element Plus
- HTTP工具: Axios
- 自动化部署:Gitee WebHook
- 服务器进程守护: Pm2
架构搭建
后端:配置后端开发环境 node + TypeScript
node安装,参考:
window 下 node 安装
项目使用Vite构建工具构建,需求 Node.js 版本 >= 12.0.0
查看node版本
$ node -v
复制代码
node升级
// 建议将 Node.js 升级到最新的稳定版本
$ npm install -g n
复制代码
node初始化
$ npm init -y
复制代码
根目录下创建【index.ts】作为程序入口
├── /
|——index.ts
复制代码
修改基本package.json
// package.json
{
"name": "img-bed",
"version": "1.0.0",
"description": "图床",
"main": "./build/index.js", // 根据tsconfig.json打包目录修改
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
复制代码
TypeScript安装
// 全局安装
$ npm i typescript -g
复制代码
打印TypeScript配置文件
命令执行后根目录中会出现tsconfig.js配置文件
$ tsc --init
复制代码
tsconfig.js配置文件修改
// tsconfig.js
{
"compilerOptions": {
"target": "ES2017", // es05 修改成 ES2017
"outDir": "./build", // 输出目录
}
}
复制代码
编译tsc
编译完成后,根目录出现【./build/index.js】
$ tsc
复制代码
声明node中使用typescript
$ npm i @types/node // node中使用typescript
复制代码
后端:快速集成Nodemon
每次文件发生修改改都需要手动重启服务
node ./build/index.js
复制代码
所以我们需要【nodemon】来帮我们执行这一项重复的工作
安装
npm i nodemon -D
// or
npm i nodemon -g
复制代码
配置启动脚本script – package.json
// package.json
{
"scripts": {
"start-sever": "tsc && node ./build/main.js",
"start": "nodemon -e ts -w ./src -x npm run start-sever"
}
}
// -e 监听的文件类型
// -w 监听的文件目录
// -x 发生改变后执行
// 每次监听发生修改都将执行 npm run start-sever
复制代码
启动
npm run start
复制代码
后端:Express快速搭建服务器
安装
npm i express
复制代码
ts声明
npm i @types/express
复制代码
入口 index.ts
// index.ts
import express from 'express'
import {Request, Response, ErrorRequestHandler, NextFunction} from 'express'
import path from "path"
import bodyParser from 'body-parser'
import compression from "compression"
const app = express();
// 开启gzip
app.use(compression());
// 处理post参数
app.use(bodyParser.json());
// 设置静态文件访问路径
app.use(express.static(path.resolve(__dirname, 'static')));
// 设置默认路由
app.get('/', (req: Request, res: Response) => {
// 返回静态文件
// res.sendFile(__dirname + "/static/" + "index.html");
// 设置状态码,返回文本信息
res.status(200).send('首页')
});
// 获取七牛云上传 token
app.post('/getToken', (req: Request, res: Response) => {
const {ma} = req.body;
const md5Str = getMd5();
if (ma != md5Str) {
throw {
message: '参数错误',
code: 500
};
} else {
res.status(200).send(getToken())
}
})
// 启动服务
app.listen(8899, () => {
logger.info('端口正在运行:8899')
})
// 自定义化错误处理
app.use((error: any, req: Request, res: Response, next: NextFunction) => {
// 这里写上自己的错误处理
res.send(JSON.stringify(error));
})
复制代码
body-parser
模块body-parser,它用于解析客户端请求的body中的内容,内部使用JSON编码处理,url编码处理以及对于文件的上传处理
引入body-parser插件格式化post参数
$ npm i body-parser
$ npm i @types/body-parser
// 使用
import bodyParser from 'body-parser'
const app = express();
// 处理post参数
app.use(bodyParser.json());
app.post('/test', (req: Request, res: Response) => {
// 解构获取参数
const {name, age} = req.body;
// 设置状态码,返回文本信息
res.status(200).send('post请求')
});
复制代码
后端:Gzip压缩
开启服务器gzip压缩,压缩率可达70%,但是会消耗服务器性能
安装使用
$ npm i compression
$ npm i @tpyes/compression
// 使用
import compression from "compression"
// 开启gzip
app.use(compression());
复制代码
后端:Log4js 日志管理
保存程序运行日志,以便更好的排错纠因
安装
$ npm i log4js
$ npm i @tpyes/logjs
复制代码
基本使用
import log4 from 'log4js'
// 加载配置文件
log4.configure('log4js.json');
// 指定自己的二次分区 - 相对于等级更加灵活 - 指定当前文件夹更方便知道该日志出自哪个文件
const logger = log4.getLogger(__filename);
logger.fatal('fatal-test');
logger.debug("debug-test")
logger.info("info-test")
logger.error("error-test")
logger.warn('warn-test')
logger.trace('trace-test')
logger.mark('mark-test')
// [2021-07-03T08:50:10.924] [FATAL] E:\desktop\test\build\index.js - fatal-test
// [2021-07-03T08:50:10.929] [DEBUG] E:\desktop\test\build\index.js - debug-test
// [2021-07-03T08:50:10.930] [INFO] E:\desktop\test\build\index.js - info-test
// [2021-07-03T08:50:10.930] [ERROR] E:\desktop\test\build\index.js - error-test
// [2021-07-03T08:50:10.931] [WARN] E:\desktop\test\build\index.js - warn-test
// [2021-07-03T08:50:10.932] [TRACE] E:\desktop\test\build\index.js - trace-test
// [2021-07-03T08:50:10.932] [MARK] E:\desktop\test\build\index.js - mark-test
复制代码
固定日志文件【log/file.log】 将会写入以下内容 – 累加
// log/file.log
[2021-07-03T08:50:10.924] [FATAL] E:\desktop\test\build\index.js - fatal-test
[2021-07-03T08:50:10.929] [DEBUG] E:\desktop\test\build\index.js - debug-test
[2021-07-03T08:50:10.930] [INFO] E:\desktop\test\build\index.js - info-test
[2021-07-03T08:50:10.930] [ERROR] E:\desktop\test\build\index.js - error-test
[2021-07-03T08:50:10.931] [WARN] E:\desktop\test\build\index.js - warn-test
[2021-07-03T08:50:10.932] [TRACE] E:\desktop\test\build\index.js - trace-test
[2021-07-03T08:50:10.932] [MARK] E:\desktop\test\build\index.js - mark-test
复制代码
日期日志文件 【log/dataFile.log】根据设定的时间规则更新
[2021-07-03T08:50:10.924] [FATAL] E:\desktop\test\build\index.js - fatal-test
[2021-07-03T08:50:10.929] [DEBUG] E:\desktop\test\build\index.js - debug-test
[2021-07-03T08:50:10.930] [INFO] E:\desktop\test\build\index.js - info-test
[2021-07-03T08:50:10.930] [ERROR] E:\desktop\test\build\index.js - error-test
[2021-07-03T08:50:10.931] [WARN] E:\desktop\test\build\index.js - warn-test
[2021-07-03T08:50:10.932] [TRACE] E:\desktop\test\build\index.js - trace-test
[2021-07-03T08:50:10.932] [MARK] E:\desktop\test\build\index.js - mark-test
复制代码
自动生成压缩备份.gz
// log/ 新增
log/datefile.log.2021-07-03-09-17.gz
复制代码
配置文件log4js.config.json
// log4js.config.json
{
"appenders": {
"file": {
"type": "fileSync",// 类型
"filename": "log/file.log",// 将日志写入的文件名
"maxLogSize": 10485760,// 最大日志存储
"numBackups": 5,// 线程数
"compress": true,// 是否在日期滚动期间,生成压缩备份文件 扩展名为.gz
"encoding": "utf-8",// 编码格式
"mode": "0o0640", // 文件模式 - 0o0640 = nodd文件模式
"layout": { // 布局
"type": "pattern",
"pattern": "[%d] [%p] [%c] | %m"
}
},
"dateFile": { // 根据时间更新的日志文件类型
"type": "dateFile",
"filename": "./log/datefile.log",
"pattern": "yyyy-MM-dd-hh-mm-ss",// 精确到每秒更新一次
"compress": true // 是否在日期滚动期间,生成压缩备份文件 扩展名为.gz
},
"console": {
"type": "console"
}
},
"categories": {
"file": {
"appenders": [
"file"
],
"level": "error"
},
"default": {
"appenders": [
"file",
"dateFile",
"console"
],
"level": "trace"
}
}
}
复制代码
后端:集成 qiniu 七牛云node版js库
更多应用可以查看qiniu官网文档:qiniu官网node文档
安装
$ npm i qiniu
$ npm i @types/qiniu
复制代码
使用
// qiniu.ts
import {auth, rs} from 'qiniu';
// 最简单的上传凭证只需要AccessKey,SecretKey和Bucket就可以。Bucket - 空间名
let accessKey: string = "七牛云accessKey";
let secretKey: string = "七牛云secretKey";
let bucket: string = '存储空间名';
//自定义凭证有效期(示例2小时,expires单位为秒,为上传凭证的有效时间
let options = {
scope: bucket,
expires: 7200
};
// 获取token
function getToken(): string {
let mac: Mac = new auth.digest.Mac(accessKey, secretKey);
let putPolicy: PutPolicy = new rs.PutPolicy(tokenOption);
return putPolicy.uploadToken(mac);
}
export {
getToken
}
// index.ts
import {getToken} from './qiniu
复制代码
前端:vite快速创建vue3.x项目
安装
$ npm init @vitejs/app
// or
$ yarn add @vitejs/app
复制代码
(1)输入项目名

(2)选择项目模板


你还可以通过附加的命令行选项直接指定项目名和模板,本项目要构建 Vite + Vue3 + TypeScript 项目,则运行:
# npm 6.x
$ npm init @vitejs/app vite-vue3-starter --template vue-ts
# npm 7+(需要额外的双横线)
$ npm init @vitejs/app vite-vue3-starter -- --template vue-ts
# yarn
$ yarn create @vitejs/app vite-vue3-starter --template vue-ts
复制代码
(3)安装依赖
$ npm i
// or
$ yarn init
复制代码
(4)启动项目
// 具体查看package.json
$ npm run dev
// or
$ yarn run dev
复制代码

前端:修改vite配置文件
Vite 配置文件 vite.config.ts 位于根目录下,项目启动时会自动读取。
本项目先做一些简单配置,例如:设置 @ 指向 src 目录、 服务启动端口、打包路径、代理等。
关于 Vite 更多配置项及用法,请查看 Vite 官网 vitejs.dev/config/ 。
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
}
},
base: './', // 设置打包路径
build: { // 打包输出路径
outDir: './static'
}
server: {
port: 4000, // 设置服务启动端口号
open: true, // 设置服务启动时是否自动打开浏览器
cors: true // 允许跨域
// 设置代理,根据我们项目实际情况配置
// proxy: {
// '/api': {
// target: 'http://xxx.xxx.xxx.xxx:8000',
// changeOrigin: true,
// secure: false,
// rewrite: (path) => path.replace('/api/', '/')
// }
// }
}
})
复制代码
前端:规范目录结构
├── publish/
└── src/
├── assets/ // 静态资源目录
├── common/ // 通用类库目录
├── components/ // 公共组件目录
├── router/ // 路由配置目录
├── store/ // 状态管理目录
├── style/ // 通用 CSS 目录
├── utils/ // 工具函数目录
├── views/ // 页面组件目录
├── App.vue
├── main.ts
├── shims-vue.d.ts
├── tests/ // 单元测试目录
├── index.html
├── tsconfig.json // TypeScript 配置文件
├── vite.config.ts // Vite 配置文件
└── package.json
复制代码
前端:集成Vue Router
(1) 安装支持 Vue3 的路由工具 vue-router@4
npm i vue-router@4
复制代码
(2)创建 src/router/index.ts 文件
在 src 下创建 router 目录,然后在 router 目录里新建 index.ts 文件:
└── src/
├── router/
├── index.ts // 路由配置文件
复制代码
// src/router/index.ts
import {
createRouter,
createWebHashHistory,
RouteRecordRaw
} from 'vue-router'
import Home from '@/views/home.vue'
import Vuex from '@/views/vuex.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/vuex',
name: 'Vuex',
component: Vuex
},
{
path: '/axios',
name: 'Axios',
component: () => import('@/views/axios.vue') // 懒加载组件
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
复制代码
(3)在 main.ts 文件中挂载路由配置
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
createApp(App).use(store).mount('#app')
复制代码
前端:集成状态管理工具Vuex
1. 安装支持 Vue3 的状态管理工具 vuex@next
npm i vuex@next
复制代码
2. 创建 src/store/index.ts 文件
在 src 下创建 store 目录,然后在 store 目录里新建 index.ts 文件:
└── src/
├── store/
├── index.ts // store 配置文件
复制代码
import { createStore } from 'vuex'
const defaultState = {
count: 0
}
// Create a new store instance.
export default createStore({
state() {
return defaultState
},
mutations: {
increment(state: typeof defaultState) {
state.count++
}
},
actions: {
increment(context) {
context.commit('increment')
}
},
getters: {
double(state: typeof defaultState) {
return 2 * state.count
}
}
})
复制代码
3. 在 main.ts 文件中挂载 Vuex 配置
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
createApp(App).use(store).mount('#app')
复制代码
前端:集成 UI 框架 Element Plus
可前往官网查看文档: element plus 官网文档
(1)安装
$ npm i element-plus
复制代码
(2)在 main.ts 文件中挂载 Element Plus
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
createApp(App).use(ElementPlus).mount('#app')
复制代码
前端:集成HTTP工具
(1)安装 Axios(Axios 跟 Vue 版本没有直接关系,安装最新即可)
$ npm i axios
// or
$ yarn add axios
复制代码
(2)安装qs格式化post请求参数
$ npm i qs
// op
$ yarn add qs
复制代码
(3)配置 Axios
为了使项目的目录结构合理且规范,我们在 src 下创建 utils 目录来存储我们常用的工具函数。
Axios 作为 HTTP 工具,我们在 utils 目录下创建 axios.ts 作为 Axios 配置文件:
└── src/
├── utils/
├── axios.ts // Axios 配置文件
复制代码
// axios.ts
import Axios, {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'
import {ElMessage} from 'element-plus'
import qs from 'qs'
const baseURL: string = '域名';
const axios: AxiosInstance = Axios.create({
baseURL,
timeout: 20 * 1000
})
// 前置拦截器(发起请求之前的拦截)
axios.interceptors.request.use(
(response: AxiosRequestConfig) => {
/**
* 根据你的项目实际情况来对 config 做处理
* 这里对 config 不做任何处理,直接返回
*/
console.log(response, '请求前');
// 在请求前格式化post参数
if (response.method == 'post') {
response.data = qs.stringify(response.data);
}
return response
},
(error: AxiosError) => {
return Promise.reject(error)
}
);
// 后置拦截器(获取到响应时的拦截)
axios.interceptors.response.use(
(response: AxiosResponse) => {
/**
* 根据你的项目实际情况来对 response 和 error 做处理
* 这里对 response 和 error 不做任何处理,直接返回
*/
return response
},
(error: AxiosError) => {
if (error.response && error.response.data) {
const code = error.response.status
const msg = error.response.data.message
ElMessage.error(`Code: ${code}, Message: ${msg}`)
console.error(`[Axios Error]`, error.response)
} else {
ElMessage.error(`${error}`)
}
return Promise.reject(error)
}
)
export default axios
复制代码
前端:集成七牛云qiniu-js
七牛云官网文档: qiniu-js 文档
**(1)安装qiniu-js **
$ npm install qiniu-js
// or
$ yarn add qiniu-js
复制代码
(2)使用
import * as qiniu from 'qiniu-js'
// 七牛云上传
const onUploadQiniu = (file: File, token: string) => {
// 基本配置
let config = {
useCdnDomain: true, //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
region: qiniu.region.z2 // 根据具体提示修改上传地区,当为 null 或 undefined 时,自动分析上传域名区域
};
// 额外配置
let putExtra: any = {
params: {}, //用来放置自定义变量
mimeType: null//用来限制上传文件类型,为 null 时表示不对文件类型限制;限制类型放到数组里: ["image/png", "image/jpeg", "image/gif"]
};
// 实例上传对象 params: (文件流, 文件名, token(后端获取的上传凭证), 额外配置, 基本配置)
let observable = qiniu.upload(file, qiniu.key, token, putExtra, config);
// 开始上传
observable.subscribe({
next: (result: any) => {
// 主要用来展示进度
console.log(result);
},
error: (errResult: any) => {
// 失败报错信息
console.log(errResult);
},
complete: (result: any) => {
// 接收成功后返回的信息
console.log(result)
}
});
}
复制代码
版本管理
Gitee托管
代码托管平台使用的Gitee,因为里面几乎都是中文,对英文不好的比较友好
官网文档:Gitee Doc
(1)创建Gitee仓库


(2)项目中的git配置
进入项目中,打开cmd或者右键 Git Bash Here
Git全局配置
$ git config --global user.name "自己的Gitee用户名"
$ git config --global user.email "自己的Gitee邮箱"
复制代码
初始化项目git仓库
# 初始化git仓库
$ git init
# 添加文件追踪
$ git add *
# 保存修改
git commit -m "first commit"
# 设置项目源
git remote add origin <项目的地址>
# 上传数据
git push -u origin master
复制代码
此时回到Gitee代码库,就能看到自己提交的代码
自动化部署
Gitee WebHook
因为项目是基于Gitee托管,所以使用WebHook
使用node实现自动执行.sh脚本程序
Gitee WebHook 官网文档: Gitee WebHook Doc
(1)添加WebHook
项目代码页 -> 管理

添加WebHook

(2)WebHook基本配置

Node自动化运行脚本
(1)新建node项目
$ npm init -y
$ npm i
复制代码
(2)根目录下新建【index.js】入口文件,【script】脚本文件夹
└── /
├── index.js // 程序入口
├── script // 脚本文件夹
复制代码
// index.js 自动化脚本
const fs = require('fs')
const http = require('http')
//node.js最有意思的child_process
const spawn = require('child_process').spawn
// 启动服务
http.createServer(function (req, res) {
createServerHandle(req, res)
}).listen(9103, () => {
console.log('服务运行成功:端口9103')
});
// 执行脚本方法
function rumCommand(cmd, args, callback) {
var child = spawn(cmd, args)
child.stdout.on('data', function (data) {
callback('stdout:' + data)
})
child.stdout.on('end', function (data) {
callback('end结束指令' + data)
})
child.on('close', code => {
callback('close,code' + code)
})
}
// 服务请求处理方法
function createServerHandle(req, res) {
// 获取token
const token = req.headers['x-gitee-token'];
// 脚本文件放在根目录下的script文件夹
fs.readdir(__dirname + '/script', (error, fileList) => {
// 我的命名方式是 <WebHook密码>-<版本>.sh , item.split('-')[0]
// 例如: imgBedNode-1.sh
const list = fileList.map(item => item.split('-')[0]);
// 脚本匹配
const index = list.indexOf(token);
if (index !== -1) {
const autoFile = __dirname + '/script' + fileList[index];
rumCommand('sh', [autoFile], (text) => {
console.log(text)
})
res.statusCode = 200;
res.end('success:匹配脚本,正在执行');
} else {
res.statusCode = 200;
res.end('error:未找到自动脚本');
}
});
}
复制代码
(3)编写shell(.sh)脚本
脚本统一放入script文件夹中
脚本示例:
# imgBedNode-1.sh
# cd到自己的前端目录
cd /xx/xxx/xx
# 每次都强制覆盖本地
# 仅拉取最新代码
git fetch --all
# 重置工作区
git reset --hard origin/master
# 拉取覆盖
git pull
# 我用的是yarn,如果项目中使用npm 则 npm run build
# 项目打包
yarn run build
# 复制打包文件到指定目录dist - 打包的文件 ,/var/www/html/ 目标位置
cp -r -f dist /var/www/html/
复制代码
Pm2进程守护(linux服务器中)
- pm2 是开源的基于Nodejs的进程管理器,包括守护进程、监控、日志的一整套完整的功能
2. pm2 基本是node应用程序不二的守护进程选择;
3. 事实上,pm2并不仅仅可以启动node程序,对于一般的脚本程序同样可以胜任;
4. pm2 带有负载均衡功能,可以保持node应用进程永远运行在后台
5. pm2 还有个非常强大的deploy功能,可以从本地直接部署线上网站。
node与PM2:
- 对于线上项目,如果直接通过 node
- app来启动,如果报错了可能直接停止导致整个服务崩溃;
- 一般监控 node 的几种进程管理方案:
- supervisor: 一般用作开发环境的使用forever:
- 管理多个站点,一般每个站点的访问量不大的情况,不需要监控
- PM2: 网站的访问量比较大,需要完整的监控页面。
- pm2的特性:
- 内建负载均衡(使用 Node cluster 集群模块)
- 后台运行;
- 0 秒停机重载,维护升级时不需要停机;
- 具有 Ubuntu 和 CentOS 的启动脚本;
- 停止不稳定的进程(避免无限循环);
- 控制台检测;
- 提供 HTTP API;
更详细应用可查看官网: pm2.keymetrics.io/
安装
$ npm install pm2 -g
复制代码
设置软连接(linux中需要全局使用,需建立软连接)
// /usr/local/node-v14.17.1-linux-x64/bin/bm2 pm2安装目录
// /usr/local/bin/pm2 linux上给用户存放可执行程序的目录
ln -s /usr/local/node-v14.17.1-linux-x64/bin/bm2 /usr/local/bin/pm2
复制代码
更新
pm2 update
复制代码
运行程序
上边我们写的node自动化运行程序,在这里就用上了
# 假如我们的node自动脚本所在目录为:/pro/autoScript/index.js
# 进入脚本根目录
cd /pro/autoScript/
# 简单启动
pm2 start index.js
# 启动并命名 - 命名为(--name=) autoScript
pm2 start index.js --name=autoScript
# 启动 and 命名 and 监听文件变化 (--watch)
pm2 start index.js --name=autoscript --watch
复制代码
以配置文件启动
假如我们的node自动脚本所在目录为:/pro/autoScript/index.js
进入脚本根目录
cd /pro/autoScript/
复制代码
打印配置文件 – 此命令会在当前目录下生成 ecosystem.config.js 文件
pm2 init
复制代码
// ecosystem.config.js 更多配置可查看官网
module.exports = {
apps : [{
"name": "autoScript", // 项目名
"script": "./index.js", // 执行文件
"cwd": "./", // 根目录
"args": "", // 传递给脚本的参数
"interpreter": "", // 指定的脚本解释器
"interpreter_args": "", // 传递给解释器的参数
"watch": true, // 是否监听文件变动然后重启
"ignore_watch": [ // 不用监听的文件
"node_modules",
"logs"
],
"exec_mode": "cluster_mode", // 应用启动模式,支持fork和cluster模式
"instances": 4, // 应用启动实例个数,仅在cluster模式有效 默认为fork;或者 max
"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": ""
}
}],
deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};
复制代码
运行配置文件 ecosystem.config.js
pm2 start ecosystem.config.js
复制代码
查看运行状态
看看我们的程序是否运行正常
pm2 status
复制代码

重启应用
# 重启指定pid 或者 name 应用
pm2 restart <pid | name>
# 重启所有应用
pm2 restart all
复制代码
停止应用
# 停止指定 pid 或者 name 应用
pm2 stop <pid | name>
# 停止所有应用
pm2 stop all
复制代码
杀掉应用
# 杀掉指定 pid 或者 name 应用
pm2 delete <pid | name>
# 杀掉所有应用
pm2 delete all
复制代码
查看日志
# 查看指定应用日志
pm2 logs <pid | name>
# 查看所有应用日志
pm2 logs
复制代码
清除日志
pm2 flush
复制代码























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)