如何设计完善的构建系统,为日常开发提速一倍

在搭建开发环境的构建系统时,我们关注二点:

  • 提高效率,对于大部分事务的自动化,如自动编译代码、自动重启服务。
  • 代码质量,编码完成时,我们则转而关注于代码的质量。

下面,让我们来详细了解下这两点的内容吧。

提高效率

依赖管理

我们在第一章 基础知识时提到了包管理的一些基础知识,对于一个成熟的编程语言来说,其也搭配有对应的包管理工具。只是在这里的,包管理工具不仅仅具有包管理的功能,它还会负责对包所依赖的子依赖进行管理。如我们在安装 Vim 软件的时候,会依赖于 vim-runtime,这里包管理工具所自带的依赖管理功能将会为我们自动安装这个依赖包。

对应的也会有相应的版本管理机制,如在上一章里,我们使用 pip install Django==1.10.2来指定我们安装的Django包的版本,这些配置也会也在相应的配置文件里。在一些语言里,其包管理工具可以指定包依赖的子依赖的版本,如我们可以限定 vim-runtine的版本为xx,如 Ruby 语言里的 Gemfile.lock,又或者是 Nodejs 里的 shirinkwrap。

除了在我们的依赖管理配置里写上所需要使用的库的版本,还可以在这个文件里指定包的中心。在中大型的软件公司里,由于安全性及便利性的原因,他们都会建立自己的包中心,又或者称为仓库中心。在这些仓库中心里,将会同步不同语言的仓库中心中的包。并且,也会将自己开发的软件包上传到这个中心,以方便组织里的其他开发者使用。

自动重载

在早期的 Web 开发中,当我们修改完后台代码时,需要手动重启后台服务;当我们修改完前端代码时,需要手动刷新前端界面。而这些步骤事实上都可以交由自动化工具来完成的,在后台开发时,这部分需要依赖于框架来实现,又或者是构建工具。而在前端开发时,我们则可以手动创建这样的服务。当检测到本地文件里的代码修改,自动编译代码、再重新加载前端页面。

当我们开发前端项目时,可能会用到 TypeScript 或者 ES6 来开发语言。为了在浏览器上运行,我们需要将其转换为 JavaScript,因此每当我们修改代码时,我们就需要做一次转换。又或者是我们使用 SASS 或者 LESS 作为样式开发语言时,就需要在运行时将其转换为 CSS。而转换 JavaScript 和 转换为 CSS 这两点都是在自动重载时所需要做的。

代码质量

lint检测编程风格

当 C 还是一门新型的编程语言时,还存在一些未被原始编译器捕获的常见错误,所以程序员们开发了一个被称作 lint 的配套项目用来扫描源文件,查找问题。对应于不同的语言都会有不同的 lint 工具,在 Python 语言中有 Pylint,在 JavaScript 中就有 JSLint,在Java里有lint4j等等。我们使用这类工具,来帮助我们从基本的语法上提高代码质量,比如:

  • 变量定义规范。在不同的语言里存在不同的变量使用方法。如在Python里,我们不使用诸如GetCurrentPage类似的驼峰命名方式,转而使用类似于getcurrentpage的下划线方式。当我们使用驼峰来取变量时,我们所使用的Lint工具就会提示我们这个错误。
  • 代码格式规范。不同的人、团队、语言对于编程风格有偏好,而在团队合作时,我们需要保持这些风格的一致性。诸如左括号后换不换行,右括号后换不换行,单个if语句是否需要括号等等,我们都需要对之有合理的规范,一种比较理想的方法是参考语言官方推荐的编码风格。
  • 限制语言特性。由于历史原因或者语言本身的语法糖,语言本身会有一些怪异的特性,可以用来实现一些特殊的功能,诸如JavaScript中的eval——它可以对字符串进行求值,而这些特性有可能是危险,又或者是难以掌控的。因此我们需要对这类特性进行限制,仅在不得已的情况下才考虑使用它。
  • 代码行数限制。这是一种简单、粗暴的降低代码复杂度的方式:我们可以将单个函数的代码行数限制在30行以内,超过时我们就不得提取出一个新的函数。当提取出新的函数时,也就意味着我们看不到长长的函数。
  • 多重嵌套限制。随着我们的业务的扩展或者对异常的处理,我们很有可能在一个if里嵌入一个if语句,然后又嵌入一个if语句,直至代码变得越来越难以阅读。因此,对于这种代码的多重嵌套我们可以限制其为3层。当超过3层时,我们就需要对其进行重构。

除了这些还有一些值得考虑的限制,诸如

  • 未用到的代码
  • 代码拥有注释
  • 函数里没有相应的文档

值得注意的是,这样做的主要原因是保持团队的代码风格一致。即使我们已经做出了一套规范,如果没有对应的代码检视机制,那么我们还是需要依靠工具来帮助我们提高。

运行测试

在我们准备提交代码到服务器的时候,我们就需要运行测试来保证不破坏系统原来的功能。当然,我们也需要在这时候添加对现有代码的测试。在这时候我们需要运行单元测试、功能测试、集成测试等等。

对于单元测试和功能测试而言,我们可以使用测试框架自带的测试命令来运行——只需要调用测试框架的接口即可。

对于集成测试来说则稍微复杂一些,我们需要运行起一个真实的服务器,使用基于Selenium或者类似的自动化测试工具来在浏览器上对页面进行操作。又或者是在前后端分离的项目里,运行在一起一个仿造服务器,再运行起前端项目,最后用对页面进行测试。

为了方便与第六章上线使用的技术栈结合,我们将使用使用 Fabric 来构建我们的构建系统。

~~~此处离结束,还有十万八千字~~~

节选自:《全栈应用开发:精益实践》

原文发布于微信公众号 - phodal(phodal-weixin)

原文发表时间:2017-07-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏架构师之路

为什么说要搞定微服务架构,先搞定RPC框架?

第一章聊了【“为什么要进行服务化,服务化究竟解决什么问题”】 第二章聊了【“微服务的服务粒度选型”】 今天开始聊一些微服务的实践,第一块,RPC框架的原理及实践...

42180
来自专栏性能与架构

Redis的消息机制 - 发布订阅

发布订阅(pub/sub)是一种消息通信模式,主要目的是解除消息发布者、消息订阅者之间的耦合 pub/sub的特点 (1)时间非耦合 发布者和订阅者不必同时在线...

530120
来自专栏企鹅号快讯

Python学习笔记之一

一、Python简介 Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于19...

226100
来自专栏数据之美

玩转 SHELL 脚本之:Shell 命令 Buffer 知多少?

1、问题: 下午有同学问了这么一个问题: tail -n +$(tail -n1 /root/tmp/n) -F /root/tmp/ip.txt 2>...

47060
来自专栏Golang语言社区

Golang的GC信息

使用方法,如果程序为myserver。正常的启动方法为./myserver,如果需要收集GC信息启动方式如下GODEBUG=gctrace=1 ./myser...

14120
来自专栏逆向与安全

漏洞分析入门一

0x00: 什么是漏洞及漏洞分类 1. 漏洞是指信息系统在生命周期的各个阶段(设计、实现、运维等过程)中产生的某类问题,这些问题会对系统的安全(机密性、完整性、...

24420
来自专栏逻辑熊猫带你玩Python

Python | “Python太火,我都不敢不把这些告诉你”

之前说过,小编现在使用的环境是ubuntu server 16.04 LTS。默认安装的应用面没有python2.x,由于越来越多的平台弃用python2,所以...

14240
来自专栏JackieZheng

十分钟带你了解服务化框架

在此之前 在此之前,你需要知道中间件的概念,可能在过往的从业生涯这个名词无数次的从你的眼前、耳畔都留下了足记,但是它的样子依然很模糊。 今天要说的服务化框架其...

20580
来自专栏Python中文社区

Python开源项目介绍:网站日志分析工具

日志分析在web系统中故障排查、性能分析方面有着非常重要的作用。该工具的侧重点不是通常的PV,UV等展示,而是在指定时间段内提供细粒度(最小分钟级别,即一分钟内...

20630
来自专栏Java面试笔试题

你使用过的应用服务器优化技术有哪些?

① 分布式缓存:缓存的本质就是内存中的哈希表,如果设计一个优质的哈希函数,那么理论上哈希表读写的渐近时间复杂度为O(1)。缓存主要用来存放那些读写比很高、变化很...

15930

扫码关注云+社区

领取腾讯云代金券