@jikeytang
2023-01-23T15:06:26.000000Z
字数 8629
阅读 1125
2022-blog
随着 http://www.vue-admin.cn 的上线,今天总结一下这个项目的点点滴滴。这项目有几个模块组成,分别是
Markdown格式转化为html并有组织的串联成一个网站 SEO前提下动态页面实现 API数据源 前端部分代码组织采用的是Pnpm Monorepo, 开发时模块上相互引用,打包发布时模块独立打包。
Vitepress 现在虽然是alpha版本,但整体用下来还是可以的。秉承了 Vite 一贯的速度和理念,只是页面风格上我个人更倾向于 Vuepress,所以做了一部分调整。CSS代码在:vue-admin-cn/docs/.vitepress/theme/scss/override.scss 供喜欢的朋友借鉴。
为何要把发布上线要讲这么前,这与一般的开发后上线理念不符。其实这是踩过多次坑之后得出的经验教训。如果前期把各种打包路径都配置好,后续的开发过程中遵循这个约定,在后期上线很少踩大坑,就算踩个坑也是小坑,完全能hold住,不会出现需要批量调整的体力活。比如:BaseUrl的配置,Image路径的配置等等。
项目中增加比较重的模块依赖建议走一遍Build发布流程,打包发布到测试环境进行整个流程的测试验证。看看发布过程中是否有不可预知的问题需要提前处理掉,比如像ElementPlus,Unocss。这样风险前置,有效的保证任务按时完成。
$ cd vue-admin-cn\apps\md$ pnpm build
然后上传 vue-admin-cn\apps\md\docs\.vitepress\dist目录中的文件到wwwroot/domain目录即可。
首先提一句,安装Nuxt模板问题,默认一直报错,需要采取一定的手段,nuxt3项目初始化失败 执行npx nuxi init nuxt-app报错
Nuxt3 终于从rc13,发了rc14之后发了正式版,从rc13切换过来还算流畅,在运行和打包上都没有遇到问题,整体感觉还是可以的,相对于Vite SSR,简单了许多,但首次启动项目编译时间还是相当的耗时。Nuxt整体的思路还是对原有的Vue插件和资源进行了一部分整合,有的提供了插件,有的可以手工集成,用起来也还可以。比如这几个:
<div class="mt-5"></div><div mt-5></div>
虽然第二种更方便,本着代码易懂的原则,我选择第一种方式。
然后大部分兼容tainwindcss的语法,所以这儿提供一个方便的在线查询 tailwind-cheat-sheet
export default defineNuxtConfig({modules: ['@nuxtjs/color-mode']})
<Icon name="uil:github" /><Icon name="🚀" /> // 支持Emoji
const text = useToUpper("it works!");
其它的可以查看官网Modules模块:https://nuxt.com/modules
与vue其它不同的地方,有几个默认目录的资源是Auto-Import的,比如components, composables,也可以手动在Nuxt.config.ts中添加 import目录。
export default defineNuxtConfig({imports: {dirs: ['api'],},})
其它插件的代码在vue-admin-cn\apps\ssr\plugins文件下,然后在Nuxt.config.ts中引入,
export default defineNuxtConfig({plugins: ['@/plugins/element-plus', '@/plugins/clipboard', { src: '~/plugins/vueInject.js', mode: 'client' }],})
Nuxt3中会报zhLocale不能设置的错误,所以删掉。
// zhLocale.el.pagination = {// goto: '跳至',// pagesize: '条/页',// total: `共计 {total} 条`,// pageClassifier: '页',// }
export default defineNuxtPlugin((nuxtApp) => {nuxtApp.vueApp.use(ElementPlus, { size: 'default', locale: zhLocale })nuxtApp.vueApp.provide(ID_INJECTION_KEY, {prefix: Math.floor(Math.random() * 10000),current: 0,})})
| 技术 | 说明 | 官网 |
|---|---|---|
| Nuxt3 | 后端渲染框架 | https://nuxt.com/ |
| Vite | Vite下一代的前端工具链 | https://cn.vitejs.dev/ |
| Element-UI | 前端UI组件库 | https://element-plus.gitee.io/ |
| Sass | 强化CSS 的辅助工具 | https://sass-lang.com/ |
| Nuxt-icon | 图标字体库 | https://github.com/nuxt-modules/icon |
| Nuxt-lodash | Lodash module for Nuxt | https://github.com/cipami/nuxt-lodash |
| @unocss/nuxt | UnoCSS Nuxt版本 | https://github.com/unocss/unocss |
| Vue3-clipboard | 剪贴板 | https://github.com/Daizhen1995/vue3-clipboard |
| Qrcode | 生成二维码 | https://github.com/soldair/node-qrcode |
| Md-editor-v3 | Markdown编辑器 | https://github.com/imzbf/md-editor-v3 |
| Juejin-markdown-themes | Juejin MD主题 | https://github.com/xitu/juejin-markdown-themes |
| Animate.css | CSS动画库 | https://animate.style/ |
| @vueuse/core | Vue工具库 | https://vueuse.org/ |
| 系统 | 工具 | 官网 |
|---|---|---|
| Vscode | 开发工具 | https://code.visualstudio.com/ |
| Navicat | 数据库管理工具 | https://www.navicat.com.cn/ |
| Atom | 源码阅读工具 | https://atom.io/ |
| Cmder | Cmd替代工具[windows] | https://cmder.net/ |
| Notepad2 | 临时单文件编辑[windows] | http://www.flos-freeware.ch/notepad2.html |
| Chrome | 调试工具 | https://www.google.com/intl/zh-CN/chrome/ |
├─.nuxt│ ├─dist│ │ ├─client│ │ │ └─_nuxt│ │ └─server│ │ └─_nuxt│ └─types├─.output // 发布目录│ ├─public│ │ └─_nuxt│ └─server├─api // 请求文件├─assets // 静态资源│ ├─css│ └─images├─components // 公共组件│ ├─AdminContribute│ ├─Banner│ ├─CardItem│ ├─Loading│ ├─MarkDownEditor│ ├─SearchBar│ ├─ShareBar│ └─Upload├─composables // hooks├─config // 配置文件├─layouts // 布局│ └─Default│ └─nav-bar├─pages // 页面│ ├─admin│ ├─help│ │ ├─about│ │ ├─contact│ │ └─update│ ├─hooks│ ├─post│ ├─ui│ └─vc├─plugins // 插件├─public // 静态资源目录└─utils // 常用方法
根目录下运行 pnpm install,然后运行 pnpm dev,这样的缺点是,两个apps输出的日志在同一窗口,显的比较混乱。如果想多窗口显示,那进入子目录下分别运行pnpm dev。比如:
$ cd vue-admin-cn\apps\md$ pnpm dev$ cd vue-admin-cn\apps\ssr$ pnpm dev
// 切换环境nvm install 16.0.0nvm use 16.0.0// 安装依赖npm install// 启动项目npm start// 清除 node_modulesnpm run clean// 全局安装 rimraf 之后方可使用npm i rimraf -g// 清除 node_modules 重新安装依赖// 等同于 npm run clean && npm installnpm run reinstall
这次选择的是宝塔控制面板来辅助部署,以下的经验也是基于宝塔来介绍。
$ cd vue-admin-cn\apps\ssr$ pnpm build
然后上传 vue-admin-cn\apps\ssr\.output目录中的文件。
打包时需要停止正在运行的开发服务。
其实就是新建nginx配置文件,比如新建网站 vue-admin.cn,然后在nginx中配置入口。假如Nuxt的端口为3300,则增加如下配置:
server{location / {proxy_pass http://127.0.0.1:3300;}}
Nuxt的默认端口为3000和Nestjs的端口冲突,需要进行修改。下面这个办法后来证实无效。
修改时,在 .env的环境文件中定义PORT或NITRO_PORT即可,在.env.prodcution中定义是无效的。
需要在 vue-admin.cn/ssr/server/chunks/node-server.js 899行 手工修改端口。
改完后的样子,没错每次发版都得修改
const port = destr(process.env.NITRO_PORT || process.env.PORT) || 3300;
另外一推荐的办法是,新建ecosystem.config.js文件,
module.exports = {apps: [{name: 'VueAdmin',script: 'server/index.mjs',args: '', // 传递给脚本的参数watch: false, // 开启监听文件变动重启ignore_watch: ['node_modules', 'public', 'logs'], // 不用监听的文件exec_mode: 'cluster_mode', // 自家主机window cluster_mode 模式下启动失败instances: '1', // max表示最大的 应用启动实例个数,仅在 cluster 模式有效 默认为 forkautorestart: true, // 默认为 true, 发生异常的情况下自动重启max_memory_restart: '200M',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, // 最大异常重启次数restart_delay: 60, // 异常重启情况下,延时重启时间env: {// 环境参数,当前指定为开发环境NODE_ENV: 'development',PORT: '3002',},env_production: {// 环境参数,当前指定为生产环境NODE_ENV: 'production', // 使用production模式 pm2 start ecosystem.config.js --env productionPORT: '3002',},},],}
然后用pm2运行此文件即可。
我们终究还是需要用pm2来进行服务的运行,但在pm2中查看日志又不非常,这时候就需要用到命令行调试。
在宝塔终端中cd到项目目录/www/wwwroot/vue-admin-cn,然后直接运行命令
$ node .output/server/index.mjs
遇到的报错:
.env中 vue-admin-cn\apps\ssr\.envvue-admin-cn\apps\ssr\plugins\element-plus.js 中
zhLocale.el.pagination = {goto: '跳至',pagesize: '条/页',total: `共计 {total} 条`,pageClassifier: '页',}
PM2配置如图所示:

每次部署,代码更新之后PM2需要重启一次
Go语言开发Blog,Nest开发Api服务Nuxt3开发服务 Nest在代码组织方式上借鉴了ng的方式,在底层上默认了Express的基础上可配置Fastify的这种灵活方式,满足多种选择。天生就以Typescript为类型约束,很适合中大型项目的开发。在配以管道、守卫、拦截器、装饰器等等理念使他与其它Node框架拉开了质的距离,所以这次我们采用他做为API的开发框架,整体开发下来的感觉还是比较符合预期,简单说是越开发越喜欢的感觉。
webpack-hmr.config.js文件,主要用来应付项目变大之后,热更新的场景。具体见这个配置文件:https://gitee.com/jsfront/nest-admin-api/webpack-hmr.config.js,然后在main.ts中增加配置:
async function bootstrap() {// 热更新if (module.hot) {module.hot.accept()module.hot.dispose(() => app.close())}}
// 设置访问频率app.use(rateLimit({windowMs: 15 * 60 * 1000, // 15分钟max: 1000, // 限制15分钟内最多只能访问1000次}),)
@ApiModelProperty()即可在预览的文档中生效。比如:
import { ApiModelProperty } from '@nestjs/swagger';export class CreateCatDto {@ApiModelProperty()readonly name: string;@ApiModelProperty()readonly breed: string;}
Entities 的生成借助了这个工具:typeorm-model-generator| 技术 | 说明 | 官网 |
|---|---|---|
| Nest | 更优雅的node.js 框架 | https://docs.nestjs.com/ |
| Mysql | 数据库服务 | https://www.mysql.com/cn/ |
| Typeorm | Orm | https://typeorm.io/ |
| @nestjs/jwt | JWT | https://github.com/nestjs/jwt |
| class-validator | 数据验证 | https://github.com/typestack/class-validator |
├─config // 配置文件├─dist // 打包文件├─entities // 生成实体文件├─public // 静态资源│ └─uploads // 上传文件├─src│ ├─common // 公共文件│ │ └─logger│ ├─config // 配置文件│ ├─interface // TS文件│ ├─modules // 业务文件│ │ ├─app│ │ ├─article│ │ ├─auth│ │ ├─category│ │ ├─common│ │ ├─file│ │ ├─menu│ │ ├─nav│ │ ├─role│ │ ├─tags│ │ └─user│ └─shared // 核心文件│ ├─constants│ ├─core│ │ ├─decorator│ │ ├─exception│ │ ├─filters│ │ └─interceptors│ ├─transformer│ └─utils└─test
根目录下运行 npm install,然后运行 npm run dev,
// 切换环境nvm install 16.0.0nvm use 16.0.0// 安装依赖npm install// 启动项目npm start// 清除 node_modulesnpm run clean// 全局安装 rimraf 之后方可使用npm i rimraf -g// 清除 node_modules 重新安装依赖// 等同于 npm run clean && npm installnpm run reinstall
$ cd nest-admin-api$ npm run build
然后上传 nest-admin-api\dist目录中的文件,然后在服务器安装 Node_modules
PM2配置如图所示

location / {proxy_pass http://127.0.0.1:3000;}
修改conf中的连接信息
至此发布成功。