表单提交系统开发总结

表单提交系统开发总结

前几天帮安大西门电信写了一个表单提交系统。由于项目紧迫需要及时上线,于是采用了一种新的开发模式:在开发完系统的基本功能后直接上线,等到本地完成一些新的功能后再部署到生产环境进行增量更新。之后,实际产生的效果很好,大大超过预期。

这几天,我开始了对这种开发模式更深层次的思考。以前我写的项目都比较小,涉及的后端服务也比较简单,需要实现的功能也可以一次全部写完,也就不存在增量更新的问题。但是这次的项目还是稍微有点复杂的,首先需要实现一个用于表单提交的前端页面,还需要一个对这些信息进行管理的后台系统,再就是一个与数据库交互的完整后端服务。

如果换做之前,项目比较简单。基本的开发工作流大概是先本地开发前端页面,接着直接在线上写后端服务的代码,最后等前端页面写完后部署到生产环境,测试是否相关接口能否正常调用。这样做缺点很明显:一方面是前后端的接口调试不够及时,其次是在开发新 feature 时系统不能正常为其它用户提供服务。

针对上述开发痛点,我尝试了将开发环境与生产环境分离,实际体验很好,对效率提升很大,并且很好地解决了上述问题。

分离开发环境与生产环境

要分离开发环境与生产环境,包括后端服务的开发环境和生产环境也需要分离。这样做有下面一些优点:

  • 不会影响既有系统的正常运行。如果你的项目已经上线了,持续的新开发不会影响现有系统正常的对外服务,这一点当然重要。
  • 支持增量更新。一旦将开发环境和生产环境进行分离,本地开发的新功能一旦测试好没问题,就可以迅速上线替换掉现有的线上系统,完成增量更新。由于本地数据库与线上数据库不同,因此本地开发也不会影响到数据库。
  • 部署成本小。从本地开发好的前后端代码可以直接替换线上现有代码,无需做任何改动。

使用本地代理

由于后端服务是基于 NodeJS 的,所以无论生产环境还是开发环境都需要反向代理,才能很好地实现前后端接口的联调。在之前的文章《利用代理解决跨域请求问题》 中,我详细介绍了在生产环境中如何使用通过配置 nginx 实现反向代理,但对本地开发环境中具体如何使用反向代理说得并不是很清楚。

由于前端工程化进程不断加快,现在的前端开发者基本都是使用 Vue、React 之类的框架进行 Web 应用的开发,再不济也会初始化个 Webpack 骨架,然后在这个基础上开发。对于前端框架,我暂时只接触过 Vue,而 Vue 底层也是调用的 Webpack,所以配置反向代理的方式也和普通 Webpack 项目的方法类似。

普通 Webpack 项目

对于比较简单的小项目,我使用的是自己之前撸的一个 Webpack 骨架 webpack-scaffold-lolimay(欢迎 star、watch 和 fork 素质三连),然后在这个骨架的基础上进行二次开发。在这次 commit 后,我已经将反向代理集成进了我的 scaffold 中,因此你只需要简单地将 build/webpack.config.js 中第 10 行的端口改成你本地后端服务监听的端口就可以直接使用。代理的 url 对应关系是 /api/test => http://localhost:[port]/test

用法示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Frontend
...
axios.get('/api/test').then( res => {
console.log(res.data)
})
...
// Backend
...
http.createServer( (req, res) => {
const route = url.parse(req.url).pathname

console.log(route) // Output: /test
})
...

Vue 项目

Vue CLI 3 已经彻底将 Webpack 的底层处理模块封装起来。如果需要配置反向代理,我们需要在项目根目录新建个 vue.config.js 文件,添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
devServer: {
open: true,
host: '0.0.0.0',
port: 8080,
https: false,
hotOnly: false,
proxy: {
'/api': {
target: 'http://localhost:[port]/', //! 请将 [port] 修改成你实际后端服务监听的端口
pathRewrite: {'^/api' : ''},
changeOrigin: true,
secure: false,
}
}
}

接着把 target 的值改成你需要代理的地址即可以实现本地代理。