0到1搭建Vue3+Vite+Node自动化部署图床项目

这是我参与新手入门的第1篇文章


从0到1搭建一个Vue3+Vite+Node图床项目

前言

尤大的vue3都发布了那么久了,不会吧不会吧,你不会一点都没看吧 ? [手动滑稽]

Vue3Vite正式版已经出来很长时间了,生态圈也逐渐丰富。不过咋至今也没在项目上用过是不是太掉队伍了,所以咋今天就用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)输入项目名

image

(2)选择项目模板

image
image

你还可以通过附加的命令行选项直接指定项目名和模板,本项目要构建 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
复制代码

image

前端:修改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仓库

image

image

(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

项目代码页 -> 管理
image

添加WebHook
image

(2)WebHook基本配置

image

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服务器中)

  1. pm2 是开源的基于Nodejs的进程管理器,包括守护进程、监控、日志的一整套完整的功能
    2. pm2 基本是node应用程序不二的守护进程选择;
    3. 事实上,pm2并不仅仅可以启动node程序,对于一般的脚本程序同样可以胜任;
    4. pm2 带有负载均衡功能,可以保持node应用进程永远运行在后台
    5. pm2 还有个非常强大的deploy功能,可以从本地直接部署线上网站。

node与PM2:

  • 对于线上项目,如果直接通过 node
  • app来启动,如果报错了可能直接停止导致整个服务崩溃;
  • 一般监控 node 的几种进程管理方案:
    1. supervisor: 一般用作开发环境的使用forever:
    2. 管理多个站点,一般每个站点的访问量不大的情况,不需要监控
    3. PM2: 网站的访问量比较大,需要完整的监控页面。
  • pm2的特性:
    1. 内建负载均衡(使用 Node cluster 集群模块)
    2. 后台运行;
    3. 0 秒停机重载,维护升级时不需要停机;
    4. 具有 Ubuntu 和 CentOS 的启动脚本;
    5. 停止不稳定的进程(避免无限循环);
    6. 控制台检测;
    7. 提供 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
复制代码

image

重启应用

# 重启指定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
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享