背景
基于公司KPI自我学习进步,以及我本人是负责后台管理系统开发维护的大环境背景下,我决定研究并开发了,拖拽生成代码的工具,目前完成的功能有: 拖拽生成 Table 页面和拖拽自动生成 Form 表单。
-
- 拖拽生成 Table 页面
- 拖拽组件,从菜单栏到中间区域,或者同区域内更换位置,不同区域可以更换,只是目前,没有一个组件是会同时可以出现在 2 个区域的,所以此功能暂时无法看到;
- 单击编辑属性
- 右击删除
- 生成代码
- 可直接复制
- 可生成文件并下载 zip 包
-
- 拖拽自动生成 Form 表单
拖拽生成 form 表单,从左侧菜单栏中,将 form 元素拖到中间区域,可根据右上角的「N 列布局」输入你想要的 N 列布局,中间区域的各个 form 表单元素,可自由拖拽更换位置。可以点击这里来使用。此功能第一个版本可以看到的有:
- 可以生成是单列,双列或者 N([1,10]) 列
- 可以拖拽生成组件
- 添加普通校验:必填
- 单击编辑属性
- 右击删除
- 生成代码
- 可直接复制
- 可生成文件并下载 zip 包
- 解决拖拽过程中定位不准确的 bug
- 拖拽自动生成 Form 表单
简介
该项目前后端分离,前端是react写的,后端是node写的一个非常小的服务,用于生成目录文件,以及压缩zip包来下载生成的代码。写这个项目也主要是为了自己走一遍前端从开发到部署的所有流程。
本人主业是前端工程师,node是自己感兴趣想学的,所以写的只能说功能上还能用,代码质量渣的xx。
学习步骤
项目目录介绍
原始农业
刚开始,只为满足功能,能跑起来就OK。
纯手工部署。步骤如下:
前端部分
先登录服务器,将,代码git clone 下来,然后cd service
目录下执行npm install
。
# 在本地项目执行命令
# 正确来说,应该在服务器上执行这个命令,鉴于我的阿里云服务器内存很小,就在本地执行。但是基于工作经历来说,我们有的线上项目,大型后,在线上服务器进行build也会很慢,有时候还会卡死,所以在本地build也没什么薄饼。
npm run build
# 拷贝(在本地执行)
# 服务器上的路径,/srv/front,直接将文件夹重命名为front
# 注意:一定要在该项目目录下进行
scp -r build root@ssh [email protected].**.**:/srv
# 在服务器执行
# 登录服务器
ssh [email protected]
cd /srv/
# 删除旧的文件
rm -rf front/
# 重命名build为front
mv build front
后端部分
# 登录远程服务器
ssh [email protected]
# 更新代码
cd /srv/bms-code-auto-generate
git pull origin master
# 远程启动后端,如果已经启动着,需要先关闭再重新启动
nohup node index.js &
# 关闭后端服务
ps aux | grep node
kill -9 pid
近代农业
等完成部署后,就发现这样每次都很麻烦,因为不想每次更新了代码,再去手动重启一遍node,这时候想起来了pm2,它可以在监控到文件更新后,去自动重启服务,所以就想着应用上pm2。
PM2 是一个守护进程管理器,它将帮助您管理和保持您的应用程序 24/7 在线。
nodejs的高级生产流程管理器。
也有其他解释:
而pm2是基于nodejs开发的进程管理器,适用于后台常驻脚本管理,同时对node网络应用有自建负载均衡功能。官方的说法,pm2 是一个带有负载均衡功能的Node应用的进程管理器,个人认为,并不准确,因为pm2支持多种语言,只是对于除node之外的其他进程无负载均衡的能力。 - 知乎
第一版 简单使用pm2 去启动index.js文件
在服务器上。
# 启动后端服务,pm2版本,
## 全局安装pm2
npm install -g pm2
## 改用pm2来启动程序--watch表示,监控程序运行状态,一旦:服务异常:自动重启;服务发生变化:自动重启
pm2 start index.js --watch
这样启动的node进程,有个问题,就是我的下载文件xxx.zip文件是保存在tmp目录下,每当我一点下载的时候,node进程就会重启。
重启的时候有时候会导致下载链接失败。
这是在请教做node的同学时的聊天截图继续,所以moduleName一个是cvb,下载的zip文件名确是666600.zip,有点对不上,因为不是同一个时间段的,是后来写文的时候翻看的聊天记录。
后来发现,去掉--watch
不会重启,并且下载链接不会报错,但是,这时候,又出现了一个问题,就是,当代码有更新时,node服务并不会自动重新启动,这就又回到了“原始农业”时代,我觉得应该监控文件是可配置的,这时候发现,得去学习一下pm2啦,于是我去翻看了pm2的官方文档,找到了ignore_watch
和ecosystem.config.js
文件。
于是有了,在/service/目录下添加文件:ecosystem.config.js
。
将代码更新到服务上去后,可以使用命令
pm2 start ./service/ecosystem.config.js
进行启动,这样启动的就比较方便了。
备注
pm2起的项目路径这样的:
在其中是会包含current和source的。我们需要手动,在source下,添加git仓库的地址,项目源码是在这里面的。
current -- 当前服务运行的文件夹(是source的软链接)
share -- log pid 等共享数据 (我目前的项目中没有这个文件)
source -- clone 下来的源代码
-- 友
现代农业
虽然上面的后端部署方式有了很大的改进,但是还是有个弊端就是,需要每次登陆服务器并且去手动拉代码,这样很麻烦。
于是写了一个一键部署的命令。
后端 v1.0
在原有的文件:ecosystem.config.js
中进行扩展。
module.exports = {
apps: [
{
name: 'generate',
script: './index.js',
// instances: 1,
watch: true,
ignore_watch: ['[/\\]./', 'node_modules', 'tmp']
}
],
deploy: {
daily: {
user: 'root',
host: ['47.105.xx.xx'],
ref: 'origin/node',
repo: '[email protected]:springHyc/bms-code-auto-generate.git',
path: '/srv/hehe/bms-code-auto-generate3',
'post-deploy': 'git pull && cd service && npm install && npm run daily',
env: {
NODE_ENV: 'daily'
}
}
}
};
配合package.json
中添加命令:
"scripts": {
"daily": "NODE_ENV=daily pm2 startOrRestart ecosystem.config.js"
},
这样直接在本地运行:pm2 deploy ./service/ecosystem.config.js daily
,即可完成,自动拉取最新的代码,并且完成重启目的。
在第一次执行前,应该进入目录/srv/hehe/bms-code-auto-generate3
中,手动新建mkdir source
这个文件夹,不然后报错。
然后还要将/srv/hehe/bms-code-auto-generate3目录下clone项目git clone origin [email protected]:***c/bms-code-auto-generate.git
,再将项目名称更改为source
后端 v2.0
上面的方式,仍然不太好,因为在本地运行的时候,ecosystem.config.js
文件是放在./service/
目录下的,我们能不能将ecosystem.config.js
文件放在根目录下呢?继续研究试验...
在根目录下新建ecosystem.config.js
文件:
// 在v1.0版本和v2.0版本中,我们将命令的名字做了更改。
module.exports = {
apps: [
{
name: 'node-generate',
script: './index.js',
cwd: './service/',
watch: false,
log_date_format: 'YYYY-MM-DD HH:mm Z'
}
],
deploy: {
daily: {
user: 'root',
host: ['47.105.**.**'],
ref: 'origin/node',
repo: '[email protected]:springHyc/bms-code-auto-generate.git',
path: '/srv/hehe/bms-code-auto-generate3',
'post-deploy': 'git pull && cd service && npm install && cd ../ && npm run deploy-node',
env: {
NODE_ENV: 'daily'
}
}
}
};
配合package.json
中添加命令:
"deploy-node": "NODE_ENV=daily pm2 startOrRestart ecosystem.config.js",
"deploy-end": "pm2 deploy ecosystem.config.js daily",
这样在本机根目录下执行npm run deploy-end
即可完成,自动拉取最新的代码,并且完成重新部署的目的。
前端
至于前端代码,我们没有做build相关的优化,所以前端代码的打包很简单,只需要build,然后将build出来的build/
目录拷贝到服务器的某个位置,like: /srv/hehe/bms-code-auto-generate3/build
,然后配置好ngnix代理即可。
手动部署的命令是:
# 在本地项目执行命令
# 正确来说,应该在服务器上执行这个命令,鉴于我的阿里云服务器内存很小,就在本地执行。但是基于工作经历来说,我们有的线上项目,大型后,在线上服务器进行build也会很慢,有时候还会卡死,所以在本地build也没什么薄饼。
npm run build
# 拷贝(在本地执行)
# 服务器上的路径,/srv/front,直接将文件夹重命名为front
# 注意:一定要在该项目目录下进行
scp -r build root@ssh [email protected].**.**:/srv/hehe/bms-code-auto-generate3
那我们能不能写个命令让它自动执行呢?可以啊
就是这个,在package.json
中添加命令:
"deploy-front": "npm run build && scp -r build [email protected].**.**:/srv/hehe/bms-code-auto-generate3",
那现在我们执行npm run deploy-front
就可以部署前端啦。
那现在有想了,我们可不可以把前后端部署命令合并成一个命令呢?分开都麻烦啊☹️
于是就有了这个命令,在package.json
中添加命令:
"deploy": "npm run deploy-end && npm run deploy-front"
现在我们执行npm run deploy
就可以自动部署前后端啦。
前端部署还有一种方式,是直接在服务器上build的,由于我们有内部包的限制,外网无法访问通,所以上面我一直采用的是本地build的方式。
服务器上build方式为:
// ecosystem.config.js文件中添加
deploy: {
daily2: {
user: 'root',
host: ['47.105.**.**'],
ref: 'origin/node',
repo: '[email protected]:springHyc/bms-code-auto-generate.git',
path: '/srv/hehe/bms-code-auto-generate3',
'post-deploy': 'git pull && npm i --registry=http://shuqudata.registry.com && npm run build',
env: {
NODE_ENV: 'daily2'
}
}
}
// package.json中添加
"deploy-front-remote": "pm2 deploy ecosystem.config.js daily2",
然后执行npm run deploy-front-remote
即可。
这个地方注意,build后,build文件路径在/source/
根目录下,要进行nginx配置才可以访问。
备注
为什么我会把项目/srv/hehe/bms-code-auto-generate3
放在这个目录上呢,因为这是个从无到有的尝试过程,我原本在/srv/
是手动起着一套前后端的,我不想破坏正在启动着的应用。
- 服务上ngnix配置
# 路径:/etc/nginx/sites-enabled/
# 文件名:hehe-bms (其实是随便起的,只是为了试验)
server {
listen 8080;
server_name 47.105.**.**;
location /api {
proxy_pass http://localhost:3003; // 后端地址
}
location / {
root /srv/hehe/bms-code-auto-generate3/build/; // 前端路径
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
注意,nginx配置修改后,一定要重启nginx,不然不生效。重启命令nginx -s rolad
,想要学习有关nginx的命令请看我的总结。
- ecosystem.config.js
module.exports = {
apps: [
{
name: 'node-generate',
script: './index.js',
cwd: './service/',
watch: false,
log_date_format: 'YYYY-MM-DD HH:mm Z'
}
],
deploy: {
daily: {
user: 'root',
host: ['47.105.**.**'],
ref: 'origin/node',
repo: '[email protected]:springHyc/bms-code-auto-generate.git',
path: '/srv/hehe/bms-code-auto-generate3',
'post-deploy': 'git pull && cd service && npm install && cd ../ && npm run deploy-node',
env: {
NODE_ENV: 'daily'
}
}
}
};
- package.json
{
"name": "bms-code-auto-generate",
"version": "0.2.0-alpha0.1",
"private": true,
"scripts": {
"dev": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js",
"deploy-node": "NODE_ENV=daily pm2 startOrRestart ecosystem.config.js",
"deploy-end": "pm2 deploy ecosystem.config.js daily",
"deploy-front": "npm run build && scp -r build [email protected].**.**:/srv/hehe/bms-code-auto-generate3",
"deploy": "npm run deploy-end && npm run deploy-front"
},
...
}
- pm2 命令
命令 | 含义 |
---|---|
pm2 stop id/name | 暂停 |
ps aux | grep node | 查看node进程 |
pm2 list | 查看pm2启动列表 |
pm2 start index2.js --watch | 启动项目 |
pm2 logs | 查看日志 |
pm2 restart app_name | 杀死并重新启动进程。restart = stop+start |
pm2 reload app_name | reload实现了0秒的停机时间重新加载.reload = 重新读取配置文件 |
pm2 stop app_name | |
pm2 delete app_name | |
pm2 flush | pm2 flush |
清空 PM2 管理的当前应用程序日志 |
pm2 monit | 监控CPU/内存 |