前几天花了3天时间,搭建、开发了一个包含客户端、cms、server端的项目,也因着之前有php的开发经验,以及sql的设计和应用能力,倒也没遇到什么阻碍。至于项目结构搭建(架构),也是共通的,以模块化、便于协做、扩展为前提。而构建工具的搭建,也只是nodejs的server端稍陌生,掌握了思路,也就简单了。php
vue全家桶 + element-ui + axios + sass + webpack + ES6/ES7 + nodejs(express) + mongodb(mongoose) + sentrycss
element-ui:用来搭建CMS UI。前端
axios:服务端数据请求使用axios,而非vue-resource(已中止维护)。根据restful api的定义,使用其get/post/put/delete/(patch未使用)方法。在进行post和update(put、patch即update)时,须要将 content-type 由 ‘application/json’ 转换成 ‘application/x-www-form-urlencoded’;转换方法有多种:vue
tips:服务端如何获取数据呢?若是服务端为nodejs,可以使用body-parse中间件。可经过其extened属性来设置,将post/update的数据转换成对象;在取req数据时,需使用req.body.paramsName而非get方法中的req.query.paramsName。node
ES6/7: 因babel的存在,能够更好的使用ES6/7的特性;如结构解析、rest、promise、模块管理、async/await、symbol、set等。同时因为nodejs为事件循环机制,经过使用async/await,来获取返回结果,其虽为同步语法,但并不是真正的同步,不会影响并发(nodejs的优点)。可经过try{}catch{}来捕获await失败的error(async/await的实质为promise的封装,遇到reject的状况,可以使用catch来捕获),代码以下:webpack
try { let admin = await adminModel.findOne({username}) // 依次验证是否存在管理员和密码,而后将admin_id存入session中(登陆机制) if (!admin) { rst.error = error.adminNotExist } else if (encryption(password).toString() != admin.password.toString()) { rst.error = error.passwordError } else { req.session.admin_id = admin['_id']; rst.success = true } } catch(err) { rst.error = error.default Raven.captureException(err); }
Express:是由路由和中间件构成一个的 web 开发框架,从本质上来讲,一个 Express 应用就是在调用各类中间件。其中间件为函数:function (req, res, next) {... // next(); 执行下一个中间件},如:ios
// 当访问cms的api,获取列表信息时,须要先验证是否已登录,如此才能获取信息,不然访问失败 router.get('/api/cms/album', adminCtrl.checkLoginState, albumCtrl.findAlbum) checkLoginState: async (req, res, next) => { ... // 若是验证成功则跳入下一个中间件,不然返回 if (rst.success) { next() } else { resCallback(res, rst) } }
mongodb:一种文档型数据库,相对稳定的关系型数据库来讲,在一致性等可能保证不足,不适合金融业务。mongoose的两个关键方法:Schema:定义属性的类型和默认值等;model:至关于schema的实例,我将其视为为一个文档,对应关系型数据库中的表。web
结构图sql
分别为client、cms在dev、production环境下的webpack配置。其中dev环境下的几个重要的中间件介绍以下:mongodb
分别为客户端、CMS 的源码,其子目录如图所示,相应的文件夹内容为:
各生产环境下的webpack区别化配置信息及本地开发路由代理配置信息。
cms:为CMS 在production环境下的编译生成,当nodejs server端捕获到/cms/*的路径时(cms页面刷新时产生),导向该文件夹;
main:为client 在production环境下的编译生成,当nodejs server端捕获到/pages/*的路径时(client页面刷新时产生),导向该文件夹;
经过nodejs的express框架搭建的服务端,对client\cms 的api及页面访问提供数据和文件等资源服务。
// index.js require('babel-core/register')({ babelrc: 'false', presets: ['stage-3', 'env'], plugins: [ 'transform-runtime', "transform-async-to-generator", "transform-es2015-modules-commonjs" ] }); require('./app.js');
为文件、图片上传后的存放位置,使用express的静态服务器方法进行处理,可经过http进行访问。