旧的 admin 项目结构梳理
项目梳理
admin
团队由于业务需要或者职能的转变, 项目经历过几次更迭
old admin
成立以来一直到现在的古老 admin
系统
new admin
新的 admin
系统
mspa
更加独立的 admin
系统
low code
提供高复用方案
old admin 目录结构及运行流程梳理
old admin
技术栈老旧且庞大混杂, 包含了node
层(koa
) / handlebars
/ jquery
/ element-ui 1.x
/ bootstrap
/ gulp
混杂 webpack
这里不会写出所有的细节, 类似于 koa-compress / koa-proxy / koa-router 等不会列举出来, 只写出最主要的流程
代码处理
- 使用
gulp
+ webpack
开始编译代码
1 2
| gulp dev # for dev hmr gulp build # for prod
|
dev
/ build
命令在 gulpfile.js
文件中定义的, 其中 gulp
会启动 webpack
处理文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| gulp.task( 'dev', [ 'conf_gen', 'js:locales', 'css', ], function () { gulp.start('webpack:js:dev'); } );
|
- 主要的
webpack
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
module.exports = { entry: { index: {}, storage: { storage_add: ['pages/storage/storage_add.js'], }, setting: {}, act: {}, credit_mgt: { credit_mgt: ['pages/credit-mgt/main.js'], }, }, output: { chunkFilename: 'js/[name].[chunkhash].js', filename: 'js/[name].bundle.js', publicPath: get_public_path_desktop(), path: __dirname + '/s/dist/desktop/', }, module: {}, resolve: { alias: { src: 'web/s/src', desktop: 'src/desktop', }, }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', ADMIN_API: 'admin_api', }), ], optimization: { vendors: { name: 'vendors', filename: 'js/vendors.bundle.js', }, iview: { name: 'iview', filename: 'js/iview.bundle.js', }, commons: { name: 'commons', filename: 'js/commons.bundle.js', chunks: 'initial', minChunks: 10, }, }, };
|
运行
dev
时以 app.js
为入口启动 node
服务
1
| node app.js --port=1122 # --harmony flag 可以让旧版本的 node 支持 es6
|
app.js
中的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var compress = require('koa-compress'); var logger = require('koa-logger'); var koa = require('koa'); var proxy = require('koa-proxy'); var web_all_init = require('./handlers/web_all.js').init;
var app = (module.exports = koa());
web_all_init(app);
var port = argv.p || argv.port || 1122; app.listen(port);
|
web_all.js
中的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var nav_config = require("./nav_config.js").nav_config; var koa_hbs = require("koa-hbs");
function init(app, opt) { opt.static_root = opt.static_root || path.join(webroot, "s/dist"); app.use(create_web_all(mobile_handler, desktop_handler)); this._render = function(tpl, locales) { _session: {}, _permission: {}, this.render(tpl, locals); }
}
|
desktop.js
中间件中的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| router.get( ['/api/partner_new_version', '/api/new_partner'], web_comm.auth_klk, web_comm.auth_klk_roles( `${role_map['API']['API-PARTNER-BROWSE']}` ), function* () { yield this._render('pages/api/index', { title: 'api', }); } );
|
- 在返回的
html
中, 会用 hbs
手动写入引入的 js
文件, 以 3
中的 pages/api/index
为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| {{!< layout }}
{{#contentFor "title"}} <title>{{title}}</title> {{/contentFor}}
{{#contentFor 'main-content'}} {{{{raw-helper}}}} <div id="app"> {{#if (eq extra_info [])}} <div></div> {{#else}} <div></div> <div> {{/contentFor}}
{{#contentFor "script_self"}} <script src="{{s '/s/dist/desktop/js/api_index.bundle.js'}}"></script> {{/contentFor}} </div> </div>
|
- 如果是新的 vue spa 流程, 会以 “pages/admin_spa” 为统一入口
1 2 3 4
| <div id="app" /> {{#contentFor "script_self"}} <script src="{{s '/s/dist/desktop/js/admin_spa.bundle.js'}}"></script> {{/contentFor}}
|
- 其中
bundle
: /s/dist/desktop/js/admin_spa.bundle.js
的打包入口在 webpack
的 entry
中指定, 为 admin_spa.js (main.js)
1 2 3 4 5 6
| new Vue({ store, router, el: '#app', });
|
- 每个模块, 如库存/商户/活动/财务, 都将是独立的 spa
部署
1 2 3
| # deploy.sh gulp build pm2 start app.js
|
new admin 目录结构
这个工程没什么好说, 基于 vue-admin-template
- 目录结构, 其他业务线, 只要在
modules
下新增自己的模块就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| - build —— 项目构建文件目录 - index.js —— 入口文件 - conf —— 项目配置目录 - dist —— 项目打包输出目录 - docs —— 文档目录 - mock —— mock 服务目录 - node_modules —— npm 包目录 - public —— 公共文件目录 - src —— 开发源文件目录
- modules —— 业务模块
- demo —— demo 模块,展示所有如 业务模版、全局组件 等的效果**_(optional)_** - layouts - list - list_1.vue - list\_[num].vue - [business_name] - components - [component_name] - index.vue - [module_name] (Top-level) —— 一级业务模块
- **\_**************\*\*\*****************\_\*\* - **_⬇️⬇️⬇️ 开发人员关注 ⬇️⬇️⬇️_**
- modules **_(optional)_** - [module_name] (Second-level) —— 二级业务模块 - modules - [module_name] (More-level) —— 更多级业务模块 - (其余同 Top-level 目录)…… - routes —— 路由 - index.js —— 入口文件 - components —— 组件(处于一级模块目录下时,对于一级模块目录下所有子模块来说,是全局组件目录;处于其它层级模块目录下时,为其所在模块的局部组件目录。)**_(optional)_** - [component_name] —— 任一组件目录 - index.vue —— 任一组件入口文件 - index.css/scss/...... —— 任一组件样式文件 - templates —— 模板**_(optional)_** - index.html - pages —— 业务页面 - [page_name].vue - styles —— 样式**_(optional)_** - [page_name].css/scss/...... —— vue 对应样式文件 - images —— 图片**_(optional)_** - [image_name].jpg/jpeg/png/...... - store —— 状态管理(vuex)**_(optional)_** - index.js —— 入口文件 - getters.js —— getter 定义文件 - mutation-consts.js —— mutation 方法常量文件 - api —— 接口实例**_(optional)_** - index.js —— 入口文件 - api_url.js —— 接口路径文件 - utils —— 工具函数**_(optional)_** - index.js —— 入口文件 - conf —— 模块配置**_(optional)_** - index.js —— 入口文件 - .eslintignore —— eslint 忽略文件(局部)**_(optional)_** - .eslintrc.js —— eslint 配置文件(局部)**_(optional)_**
- **_⬆️⬆️⬆️ 开发人员关注 ⬆️⬆️⬆️_** - **\_**************\*\*\*****************\_\*\*
- assets —— 全局资源 - styles —— 样式 - [style_name].css/scss/...... - images —— 图片 - [image_name].jpg/jpeg/png/...... - fonts —— 字体 - [font_name].eot/ttf/woff/woff2/svg/...... - components —— 全局组件 - [component_name] —— 任一全局组件目录 - index.vue —— 任一全局组件入口文件 - index.css/scss/...... —— 任一全局组件样式文件 - index.js 入口文件 - conf —— 开发相关配置 - index.js —— 入口文件 - const.js —— 全局常量定义文件 - …… - icons —— 图标文件目录(svg) - layouts —— 业务模版 - components —— 组件目录 - [business_name] —— 任一业务模版目录 - index.vue —— 入口文件 - pages —— 默认提供页面 - 404.vue - root.vue - router —— 全局路由 - index.js —— 入口文件 - services —— 服务 - api —— 接口服务 - index.js —— 入口文件 - axios.js —— axios 实例封装文件(interceptors 开发等) - lang —— 多语言 - index.js —— 入口文件 - [lang].js —— 多语言文案文件 - store —— 全局状态管理(vuex) - modules —— 模块目录 - index.js —— 入口文件 - getters.js —— getter 定义文件 - mutation-consts.js —— mutation 方法常量文件 - styles —— 全局样式目录 - utils —— 工具函数目录 - index.js —— 入口文件 - [util_module_name].js —— 任一工具函数模块入口文件 - App.vue —— 应用入口 vue 文件 - main.js —— 应用入口 js 文件 - permission.js —— 权限控制文件
- static —— 静态文件目录 **_(optional)_** - tests —— 项目测试目录 - ********\*\********* 我是分割线 ********\*\********* - .commitlintrc.js —— commitlint 配置文件 - .editorconfig —— IDE 代码风格配置文件 - .env.development —— 环境脚本文件 - .env.production —— 环境脚本文件 - .env.staging —— 环境脚本文件 - .eslintignore —— eslint 忽略文件(全局) - .eslintrc.js —— eslint 配置文件(全局) - .gitignore —— git 忽略文件 - .jsdoc.json —— jsdoc 配置文件 - .travis.yml —— Travis CI 文件 - babel.config.js —— babel 配置文件 - jest.config.js —— jest 单元测试配置文件 - package.json - postcss.config.js —— postcss 配置文件 - README.md - tsconfig.json —— typescript 配置文件 - vue.config.js —— vue-cli 配置文件 - ……
|
- 部署, 产线运行目录下的
deploy.sh
即可, deploy.sh
包含 checkout/install/build
命令 (该项目依赖于 old admin
提供的 node
服务)
mspa (multi single page)
由于 new admin
也集成了各个业务线的代码, 越来越难于维护
并且 admin
团队后续将偏向于成为提供基础能力的团队, 业务开发将分散到各个vertical
团队 (各个垂直业务团队, 如租车, hotel, airport transfer, ttd 等等)
于是提供 mspa
的开发模式.
admin
团队提供以下能力:
1 2 3 4 5 6 7 8 9
| admin-cli # vue 项目脚手架 - 类 @vue/cli admin-cli-service # 项目脚手架工具 - 类 @vue/cli-service admin-ui # ui 组件库 admin-utils # 常用工具函数库 admin-login # 提供 google 登录功能 admin-permission # 提供 admin 权限验证 admin-layout # 提供统一的布局 .... ....
|
- 各个业务团队使用
admin-cli
以及相关的库自行搭建项目
- 使用
node
编写接口, 在部署时, 上传每个 app
的 router
, 集成展示
- 由于大家都是独立工程, 有需要可以自行部署至单独域名
- 统一托管到
aws
的cdn
上
low code
由于 admin
开发, 会出现大量的重复工作, 例如表单+表格的页面模式, 在 admin
占比非常大
于是使用业界方案 sula
或者 baidu/amis
, 提供 low code
方案
该方案仅限于普通的通过配置生成界面, 希望做到更高的可拓展性和可拔插性
持续中
-
版权声明: 本博客所有文章除特别声明外,均采用
CC BY 4.0 CN协议
许可协议。转载请注明出处!
Жизнь, как качели - то вверх, то вниз.