# vue-admin-cn **Repository Path**: jsfront/vue-admin-cn ## Basic Information - **Project Name**: vue-admin-cn - **Description**: vue-admin.cn 是一个基于 Vue3, Nuxt3, ElementPlus, Scss, Bytemd的综合性应用,用最新的技术栈,展示最朴素的内容 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: http://vue-admin.cn - **GVP Project**: No ## Statistics - **Stars**: 140 - **Forks**: 15 - **Created**: 2022-11-09 - **Last Updated**: 2025-06-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 随着 [http://www.vue-admin.cn](http://www.vue-admin.cn) 的上线,今天总结一下这个项目的点点滴滴。这项目有几个模块组成,分别是 - Vitepress: 提供静态文档的支持,具体就是把`Markdown`格式转化为`html`并有组织的串联成一个网站 仓库地址 [https://gitee.com/jikey/vue-admin-cn](https://gitee.com/jikey/vue-admin-cn) 技术栈为:Vitepress, Element-Plus, VueUse, UnoCSS, - Nuxt:满足`SEO`前提下动态页面实现 仓库地址 [https://gitee.com/jikey/vue-admin-cn](https://gitee.com/jikey/vue-admin-cn) 技术栈为:Nuxt3, Element-Plus, VueUse, UnoCSS, - Vue3: 后台管理技术构成 仓库地址 [https://gitee.com/jsfront/vue3-tiger-admin](https://gitee.com/jsfront/vue3-tiger-admin) 技术栈为:Vue3, Arce, VueUse, UnoCSS, - Nestjs: 提供基础`API`数据源 仓库地址 [https://gitee.com/jsfront/nest-admin-api](https://gitee.com/jsfront/nest-admin-api) 技术栈为:Nestjs, Mysql, Typeorm, 先从全局角度总结一下: - 定位 最原始的出发点就是为`vue`开发者提供一个管理模板相关的资源整合类的平台,就是把能匹配管理模板这个关键字的内容整合到一起来,然后方便筛选,查找。 - 目标用户 与`Vue`相关的开发者、从业者 - 代码组织 代码组织采用的是Pnpm Monorepo, Monorepo 是把多个工程放到一个 `git` 仓库中进行管理,可以共享流程,复用代码等优点 开发时模块相互引用,发布时各个模块独立打包。这样代码能复用,发布又灵活,特别方便后续代码的扩展。比如要加个`Admin`平台,直接在apps中创建模块即可。 ### 1. Vitepress介绍 #### 1.1 基本介绍 Vitepress 虽然是alpha版本,初步评估还是满足简单`Markdown`转换为文档平台的需求。秉承了 Vite 一贯的速度和理念,开发配置也非常方便。页面风格上我个人更倾向于 Vuepress,所以做了一部分调整。`CSS`代码在:[vue-admin-cn/docs/.vitepress/theme/scss/override.scss](https://gitee.com/jsfront/vue-admin-cn/blob/master/apps/md/docs/.vitepress/theme/scss/override.scss) 供喜欢的朋友借鉴。 #### 1.2 如何发布上线 为何要把发布上线要讲这么前,这与一般先开发后上线习惯不同。其实这是踩过多次坑之后的一个经验。如果前期把各种基础配置都约定好,后续的开发遵循这个约定,在上线时很少踩这方面的大坑,就算踩个坑也完全能hold住,不会出现需要批量调整的场景。比如:`ApiUrl, BaseUrl`的配置,`Image`路径的配置等等。 项目中增加比较重的模块依赖建议走一遍`Build`发布流程,打包发布到测试环境进行测试验证。看看发布过程中是否有不可预知的问题需要提前处理掉,比如像`ElementPlus`,`Unocss`。这样风险前置,有效的保证任务按时完成。 ```javascript $ cd vue-admin-cn\apps\md $ pnpm build ``` 然后上传 `vue-admin-cn\apps\md\docs\.vitepress\dist`目录中的文件到`wwwroot/domain`目录即可。 ### 2. Nuxt3介绍 装Nuxt报错解决办法具体看这个链接:nuxt3项目初始化失败 [执行npx nuxi init nuxt-app报错](https://juejin.cn/post/7154586714416087076) #### 2.1 基本介绍 Nuxt3 终于发了正式版,从`rc13`切换过来还算流畅,在运行和打包上都没有遇到问题。`Nuxt`整体的思路还是对原有的`Vue`插件和资源进行了一部分整合,有的提供了插件,有的可以手工集成。比如这几个: - [@unocss/nuxt](https://github.com/unocss/unocss) unocss 的nuxt版本,然后增加配置文件,[https://gitee.com/jsfront/vue-admin-cn/blob/master/apps/ssr/unocss.config.ts](https://gitee.com/jsfront/vue-admin-cn/blob/master/apps/ssr/unocss.config.ts),就可以在开发中愉快用起来了。支持两种方式 ```css
``` 虽然第二种更方便,本着代码易懂的原则,我选择第一种方式。 然后大部分兼容tainwindcss的语法,所以这儿提供一个方便的在线查询 [tailwind-cheat-sheet](https://nerdcave.com/tailwind-cheat-sheet) - [@nuxtjs/color-mode](https://color-mode.nuxtjs.org/) 这是一款主题切换工具 ``` export default defineNuxtConfig({ modules: ['@nuxtjs/color-mode'] }) ``` - [nuxt-icon](https://github.com/nuxt-modules/icon) 安装后,在这个网站进行搜索:[https://icones.js.org/](https://icones.js.org/),然后用以后的方式引用: ```html // 支持Emoji ``` - [nuxt-lodash](https://www.npmjs.com/package/nuxt-lodash) 用法,对一些常有的方法进行了封装,但有些还是没有,没办法只能手动引入,总体下来这款加入后的收益并没那么好。 ```javascript const text = useToUpper("it works!"); ``` 其它的可以查看官网Modules模块:[https://nuxt.com/modules](https://nuxt.com/modules) 与vue其它不同的地方,有几个默认目录的资源是`Auto-Import`的,比如`components, composables`,也可以手动在`Nuxt.config.ts`中添加 `import`目录。 ```javascript export default defineNuxtConfig({ imports: { dirs: ['api'], }, }) ``` #### 2.2 其它插件安装 其它插件的代码在`vue-admin-cn\apps\ssr\plugins`文件下,然后在`Nuxt.config.ts`中引入, ```javascript export default defineNuxtConfig({ plugins: ['@/plugins/element-plus', '@/plugins/clipboard', { src: '~/plugins/vueInject.js', mode: 'client' }], }) ``` - [element-plus](https://element-plus.gitee.io/) 这段配置加上在`Nuxt3`中会报`zhLocale`不能设置的错误,所以删掉。 ``` // zhLocale.el.pagination = { // goto: '跳至', // pagesize: '条/页', // total: `共计 {total} 条`, // pageClassifier: '页', // } ``` ```javascript 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, }) }) ``` - [vue3-clipboard](https://github.com/soerenmartius/vue3-clipboard) 主要用在分享文章时复制地址 - [vue-dompurify-html](https://github.com/LeSuisse/vue-dompurify-html) 解决v-html提示不安全的问题,使用XSS插件他会把除了标签和内容之外的所有东西都给过滤掉,比如class,style这样过滤掉后富文本的样式就没有了,美观度一下就降低了。 #### 2.3 技术栈 技术 | 说明 | 官网 ----|----|---- Nuxt3 | 后端渲染框架 | [https://nuxt.com/](https://nuxt.com/) Vite | Vite下一代的前端工具链 | [https://cn.vitejs.dev/](https://cn.vitejs.dev/) Element-UI | 前端UI组件库 | [https://element-plus.gitee.io/](https://element-plus.gitee.io/) Sass | 强化CSS 的辅助工具 | [https://sass-lang.com/](https://sass-lang.com/) Nuxt-icon | 图标字体库 | [https://github.com/nuxt-modules/icon](https://github.com/nuxt-modules/icon) Nuxt-lodash | Lodash module for Nuxt | [https://github.com/cipami/nuxt-lodash](https://github.com/cipami/nuxt-lodash) @unocss/nuxt | UnoCSS Nuxt版本 | [https://github.com/unocss/unocss](https://github.com/unocss/unocss) Vue3-clipboard | 剪贴板 | [https://github.com/Daizhen1995/vue3-clipboard](https://github.com/Daizhen1995/vue3-clipboard) Qrcode | 生成二维码 | [https://github.com/soldair/node-qrcode](https://github.com/soldair/node-qrcode) Md-editor-v3 | Markdown编辑器 | [https://github.com/imzbf/md-editor-v3](https://github.com/imzbf/md-editor-v3) Juejin-markdown-themes | Juejin MD主题 | [https://github.com/xitu/juejin-markdown-themes](https://github.com/xitu/juejin-markdown-themes) Animate.css | CSS动画库 | [https://animate.style/](https://animate.style/) @vueuse/core | Vue工具库 | [https://vueuse.org/](https://vueuse.org/) #### 2.3 开发工具 系统 | 工具 | 官网 ----|----|---- Vscode | 开发工具 | [https://code.visualstudio.com/](https://code.visualstudio.com/) Navicat | 数据库管理工具 | [https://www.navicat.com.cn/](https://www.navicat.com.cn/) Atom | 源码阅读工具 | [https://atom.io/](https://atom.io/) Cmder | Cmd替代工具[windows] | [https://cmder.net/](https://cmder.net/) Notepad2 | 临时单文件编辑[windows] | [http://www.flos-freeware.ch/notepad2.html](http://www.flos-freeware.ch/notepad2.html) Chrome | 调试工具 | [https://www.google.com/intl/zh-CN/chrome/](https://www.google.com/intl/zh-CN/chrome/) #### 2.4 文件结构 ``` ├─.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 // 常用方法 ``` #### 2.5 如何在本地运行 根目录下运行 `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.0 nvm use 16.0.0 // 安装依赖 npm install // 启动项目 npm start // 清除 node_modules npm run clean // 全局安装 rimraf 之后方可使用 npm i rimraf -g // 清除 node_modules 重新安装依赖 // 等同于 npm run clean && npm install npm run reinstall ``` #### 2.6 如何上线发布 上线基于[宝塔](http://www.bt.cn)面板来介绍。 ##### 2.6.1 打包 ```javascript $ cd vue-admin-cn\apps\ssr $ pnpm build ``` 然后上传 `vue-admin-cn\apps\ssr\.output`目录中的文件。 **打包时需要停止正在运行的开发服务,如果出现没权限的提示,多试几次。** ##### 2.6.2 新建网站 其实就是新建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行 手工修改端口。 改完后的样子,没错每次发版都得修改 ```javascript const port = destr(process.env.NITRO_PORT || process.env.PORT) || 3300; ``` 另外一推荐的办法是,新建`ecosystem.config.js`文件,此文件是`PM2`配置文件,其它配置[可以看这个链接](https://juejin.cn/post/6926357629375610887),[英文文档出处链接](https://pm2.keymetrics.io/docs/usage/environment/)。 ```javascript 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 模式有效 默认为 fork autorestart: 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 production PORT: '3002', }, }, ], } ``` 然后用`pm2`运行此文件即可。 ##### 2.6.3 命令行终端调试 我们终究还是需要用pm2来进行服务的运行,但在pm2中查看日志又不非常,这时候就需要用到命令行调试。 在宝塔终端中cd到项目目录`/www/wwwroot/vue-admin-cn`,然后直接运行命令 ``` $ node .output/server/index.mjs ``` 遇到的报错: - 端口号不生效,是由于写错文件,必须写在`.env`中 见文件 `vue-admin-cn\apps\ssr\.env` - Element-plus中文配置不生效,删除 `vue-admin-cn\apps\ssr\plugins\element-plus.js` 中 ``` zhLocale.el.pagination = { goto: '跳至', pagesize: '条/页', total: `共计 {total} 条`, pageClassifier: '页', } ``` ##### 2.6.4 PM2绑定进程 - PM2配置如图所示: ![](https://s3.bmp.ovh/imgs/2022/11/25/48e9a38fecdf9aec.jpg) **每次部署,代码更新之后PM2需要重启一次** ---------- - 配置好之后如图所示: ![](https://s3.bmp.ovh/imgs/2022/11/25/f9f39d8dee8bdfda.jpg) - nextjs为next.js-v12版本应用, - [http://milu.blog](http://milu.blog) 为`Go`语言开发Blog, - [http://api.nest.vue-admin.cn](http://api.nest.vue-admin.cn) 为`Nest`开发Api服务 - [http://www.vue-admin.cn](http://www.vue-admin.cn) 为`Nuxt3`开发服务 就目前数据来看,没有经过任何优化前,内存消耗来说Go最少,然后Nest最多,跑一个Nest服务相当于能跑4个Go服务,跑一个Nuxt3相当于能跑不到3个Go服务。目前个人感觉Go的特点是,虽然开发略慢,但占用内存少,运行速度快,打包不拖泥带水等特点。 ### 3. Nest介绍 Nest在代码组织方式上借鉴了`ng`的方式,在底层上默认了`Express`的基础上可配置`Fastify`的这种灵活方式,满足多种选择。天生就以`Typescript`为类型约束,很适合中大型项目的开发。在配以管道、守卫、拦截器、装饰器等等理念使他与其它Node框架拉开了质的距离,所以这次我们采用他做为API的开发框架,整体开发下来的感觉还是比较符合预期,简单说是越开发越喜欢的感觉。 #### 3.1 基本介绍 - 这次的开发在原有的基础上增加了`webpack-hmr.config.js`文件,主要用来应付项目变大之后,热更新的场景。具体见这个配置文件:[https://gitee.com/jsfront/nest-admin-api/webpack-hmr.config.js](https://gitee.com/jsfront/nest-admin-api/blob/master/webpack-hmr.config.js),然后在main.ts中增加配置: ``` async function bootstrap() { // 热更新 if (module.hot) { module.hot.accept() module.hot.dispose(() => app.close()) } } ``` - 为防止恶意请求,增加了单一IP的单位时间内请求数的限制。 ``` // 设置访问频率 app.use( rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 1000, // 限制15分钟内最多只能访问1000次 }), ) ``` - 日常的文档开发由 [@nestjs/swagger](https://docs.nestjs.com/openapi/introduction) 这个包提供 配置生效之后,加入`@ApiModelProperty()`即可在预览的文档中生效。比如: ``` import { ApiModelProperty } from '@nestjs/swagger'; export class CreateCatDto { @ApiModelProperty() readonly name: string; @ApiModelProperty() readonly breed: string; } ``` - 由于比较懒,所以 `Entities` 的生成借助了这个工具:[typeorm-model-generator](https://github.com/Kononnable/typeorm-model-generator) #### 3.2 技术栈 技术 | 说明 | 官网 ----|----|---- Nest | 更优雅的node.js 框架 | [https://docs.nestjs.com/](https://docs.nestjs.com/) Mysql | 数据库服务 | [https://www.mysql.com/cn/](https://www.mysql.com/cn/) Typeorm | Orm | [https://typeorm.io/](https://typeorm.io/) @nestjs/jwt | JWT | [https://github.com/nestjs/jwt](https://github.com/nestjs/jwt) class-validator | 数据验证 | [https://github.com/typestack/class-validator](https://github.com/typestack/class-validator) #### 3.3 文件结构 ```javascript ├─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 ``` #### 3.4 如何在本地运行 根目录下运行 `npm install`,然后运行 `npm run dev`, ``` // 切换环境 nvm install 16.0.0 nvm use 16.0.0 // 安装依赖 npm install // 启动项目 npm start // 清除 node_modules npm run clean // 全局安装 rimraf 之后方可使用 npm i rimraf -g // 清除 node_modules 重新安装依赖 // 等同于 npm run clean && npm install npm run reinstall ``` #### 3.5 如何上线发布 ##### 3.5.1 打包 ```javascript $ cd nest-admin-api $ npm run build ``` 然后上传 `nest-admin-api\dist`目录中的文件,然后在服务器安装 `Node_modules` ##### 3.5.2 PM2绑定进程 PM2配置如图所示 ![](https://s3.bmp.ovh/imgs/2022/11/25/48e9a38fecdf9aec.jpg) ##### 3.5.3 配置Nginx ```shell location / { proxy_pass http://127.0.0.1:3000; } ``` #### 3.6 导入数据库 修改`conf`中的连接信息 至此发布成功。 为了方便找回此项目,可以点右上角 💖Star 💖 收藏 + 支持 还可以加Q群进行反馈交流: - Node交流群 422910907 - Vue交流群 364912432 - Javascript交流群 492107297