前端工程化:云构建

背景

通常个人在开发项目的时,都是在本地编写构建脚本对项目进行构建,这个脚本可能是 Gulp,可能是 Grunt, 可能是 webpack,也可能是其他的一些脚本,每次代码发布之前,都要对代码进行构建,代码仓库里面包含构建脚本和构建之后的代码。对于个人开发,这样做是没有问题的,但是涉及到多人开发或者团队开发就会有一定的问题。说是问题也不是问题只不过是会导致开发效率降低,构建错误的情况越来越多。

在本地对项目进行构建,通过脚手架工具来分发构建脚本对于团队开发来说有很多问题:

  • 构建脚本的开发维护者很难去持续优化,更新构建脚本
  • 构建脚本使用者对构建脚本的修改,改良不可复用
  • 每次发布之前都需要对项目进行构建,如果忘记构建将会导致发布失败
  • 同一个项目的开发者可能会有不同的构建脚本,极有可能会导致构建出错

我们把构建脚本从应用里面提炼出来,包装成单独 npm 模块,这样构建脚本(下文统称为构建器)就有了模块的一些特性:

  • 可分享: 任何人可以很方便发布一个构建脚本模块给任何人使用
  • 可修改: 如果你有更好的主意,可以 fork,加上自己想要的功能,并发布到 npm 平台上
  • 易维护: 模块可以由专人维护与更新

使用云构建后,本地不需要安装任何构建环境,这个对于一些新技术的推广是有好处的, 比如大家都知道,在 Windows 下, 安装 compass 不是一件轻松的事。而且对于构建脚本的更新也是很友好的,只需要更新云构建平台上的构建脚本即可。

使用云构建后仓库里面就不需要保存构建后的代码,这样有助于保持代码整洁,同时,在多人开发的时候,再也不会出现构建脚本冲突的情况。把云构建接入发布流程,每次提交发布时执行构建,这样就再也不会在发布之前忘了构建。而且服务器的性能更强大,对于比较大的项目能够更快执行构建,节省构建的时间。一线开发人员不需要去关心构建的问题,能够把更多的时间放到业务上,提高工作效率并。

历史和现状

Grunt;Glup 等前端构建的概念是近几年才火起来的,其实淘宝前端团队早在 2011 左右就开始大规模对前端代码进行构建了(Git 也是在这个时候引入到团队内作为版本管理工具)。最初使用的构建引擎是 ant,基于 XML 描述构建规则,后来将 ant 的 build 任务放到了服务器端执行,再后来由于 ant 的扩展性和维护性太低直接改成了 shell 脚本(那个时候压缩代码还是用 YUICompress 和 Google Closure Compiler)。

再后来 Node.js 开始流行,基于 Node.js 的前端生产力工具开始如雨后春笋般涌现。团队内部开始使用 Grunt 构建前端代码(后续慢慢被 Glup 和 webpack 替代),但依旧是在本机电脑执行构建,然后将构建后代码提交到仓库进行发布上线。14 年底开始构思并上线了第一版云端构建平台,开始逐步将前端代码的共建工作再次迁移到云端执行。

经过一年多时间的完善,云构建平台已经完全支撑起了团队内部乃至整个集团的前端代码构建任务,日构建任务量已达 1000+。并且构建服务还集成到了代码发布流程中和本地开发工具中,使前端开发前所未有的高效和轻松。

系统架构

云构建系统由五部分组成:

  • 客户端(client

    • client 负责向云构建发起一个构建请求并获取构建后内容。
    • client 官方提供了一个已经封装好逻辑的 npm 模块,如果是基于 Node.js 的系统,可以直接使用。
    • client 支持将需要构建的代码直接上传给构架服务器或者仅提供一个 URL,由构建服务器自己从 URL 下载代码,官方更推荐后者。
  • 构建器(builder
    • builder 是构建任务的最终执行者,包含详细的构建业务逻辑
    • builder 是一个标准的 npm 模块
  • 构建服务器(workers
    • workers 是一组高性能服务器,每台服务器可以并发运 32 个构建任务。
    • workers 可以动态扩容;上线和下线
  • 构建路由(router
    • router 负责分发构建任务给 worker。
    • router 集成了 worker 负载监控功能,可以保证所有 worker 平均负载。
  • 数据展示和管理平台(web
    • web 展示所有构建过程中产生的数据
    • web 管理构建器和构建服务器

架构图:

运行一次构建任务的大概过程如下:

  1. app(需要调用云构建的各种系统)集成 client,并使用 client 提供的接口发起构建请求
  2. client 从 router 获取一个 worker 地址
  3. client 与 worker 建立 socket 连接,并向这个 worker 发起构建任务
  4. worker 实时输出构建日志信息给 client
  5. worker 完成构建后将构建结果返回给 client
  6. client 将构建结果返回给 app

为了减轻构建服务器的负载,整个构建过程中涉及到的文件上传下载服务都是通过文件中转服务来完成的。

abc.json

除了上面的五个部分,还有一个配置文件也是必不可少的:abc.json(a build config)。这个文件一般跟需要构建的内容放在一起发送给 worker。是一个标准的 JSON 文件,指定需要调用的 builder 和一些配置信息。

构建器(builder)

abc.json 和 builder 是整个云构建平台唯一可定制部分。

builder 是一个标准的 npm 模块,入口文件可以是一个 Grunfile.js 或者 glupfile.js,当然也可以是你自己的 xx.js。如果是 Gulp 或者 Grunt 脚本,worker 会帮你运行这个脚本,如果是普通的 npm 包,wroker 会运行由 package.json 文件中指定的入口文件。

构建器编写注意事项

1,项目本身需要依赖一些外部的模块,例如 lodash,需要构建开始前需要自己安装相应的依赖,可以通过一个 Gulp 的 task 去执行,没有依赖则忽略。

3,针对特定项目的配置信息,可以在项目的配置文件(abc.json)中添加,然后在构建时通过读取配置文件获取。

4,云构建和本地构建有一定的区别。本地构建时,源码目录和构建好的代码的存放目录构建者都是明确的。而云端构建,构建脚本是由云构建平台来控制的,云构建也需要收集构建好的文件返回给客户端,因此待构建源码的目录(src)和构建好的代码的存放目录(dist)都是需要有云构建平台来指定,worker 在执行 builder 的时候会传递相关参数。

5,如果构建器本身需要安装依赖,package.json 的依赖需要是 dependencies,不能是 devDependencies。

构建器测试

构建器编写本身也需要一定的成本,而且在本地无法测试,如果构建器编写出错,而且已经发布,将会造成很大的问题,因此需要一个构建器的测试平台。

通过删除构建系统的大部分特性,而只保留最核心的功能,同时去除原系统的一些限制使构建器能够在上面正常运行。同时编写相应的测试命令行工具,形成整个构建器测试平台。

线上构建系统对构建器做了严格的限制,构建器必须要审核通过才能够发布上线。测试平台没有这些限制,方便构建器开发者更新测试。

遇到的问题和解决方法

1,HTTP 连接

最开始的时候 client 与 worker 都是通过 HTTP 进行通信,这样实现起来的确是很简单,系统也能正常运行。而且对于绝大多数构建任务来说是没有问题的。但是遇到一些比较大的项目,构建时间比较长的项目,问题就暴露出来了。由于构建时间比较长 HTTP 连接经常可能会被重置,既有可能因为 nginx 代理的问题导致,也有可能因为网络问题导致。

随着云构建系统越来越复杂,服务器的返回值,需要经过多层嵌套才能够返回给客户端,这对于系统的调试和错误处理带来了很多的不变,而且大大降低了代码的可读性。错误处理变得很复杂,可能会存在没有发现的 bug。

为了彻底解决这个问题,我们使用了 socket 来代替 HTTP,使用了 socket 的特性,构建时间即使再久也不会发生构建过程中通信中断的问题。而且只要构建发生错误,通过 socket 的事件机制立马就能够通知客户端。

2,文件上传

在最初的系统中,项目文件的上传是通过 client 直接把项目文件压缩打包上传到 worker,项目文件很大打包压缩上传的时间需要很久,而且文件过大,nginx 会返回 413 错误。当并发任务数量过多的时候,worker 负载过大,经常会因为上传下载占用过多的资源影响构建服务的正常进行。

通过把文件上传服务独立出来,建立单独文件中转服务,worker 只需要关注构建相关的问题,不再接收处理上传的文件,client 传递给 worker 的只是一个 URL 地址。构建完成后,worker 把构建好的代码打包压缩上传到文件中转服务,然后返回相应的地址给 client,client 通过地址拿到构建好的内容。所有文件处理都通过第三方去处理,文件部分的处理和构建过程完全独立。减少了系统的耦合程度。

3,负载均衡

随着云构建系统被使用的越来越多,构建任务经常需要等待,为了避免构建等待,加快构建速度,我们增加了构建服务器的数量。

多台构建服务器就需要有相应的任务分发机制,对任务进行分发保证构建任务不需要等待。因此增加了云构建路由服务(router)。云构建路由对任务进行分发,构建服务器有多台,在分发的时候要根据构建服务器上面正在运行任务的数量进行分发,确保任务能够以最快的速度运行。

同时还需要设定心跳机制,定时去检测构建服务器的情况,如果构建服务器出现异常能够及时报警,同时自动下线相应的构建服务器。最大程度的保证构建能够正常的运行,不会因为一台构建服务器出现故障而影响整个构建系统的正常运行。

展望

1,为了提高测试平台的稳定性和安全性,我们设想为每个构建器提供单独的沙盒运行环境,使用 docker 技术把构建器的运行环境和构建系统本身隔离开来,保证构建器运行过程的问题不会影响构建系统本身,使两者独立起来。这样做对于系统的安全性也会有很大的提高,限制了构建器本身的运行环境,即使构建器中存在一些危害构建系统的行为也不会影响到构建系统,这样极大的提高了安全性和稳定性。

2,目前云构建还只是拥有对代码进行构建的能力,完全可以把云构建平台进行通用化,成为一个通用 Node.js 任务运行平台,目前我们正在做这方面的尝试。

转载自:淘宝前端团队

作者:阿大,慎里

时间: 2024-09-20 04:13:00

前端工程化:云构建的相关文章

京东资深前端架构师分享前端工程化在电商首页中的实践

大家好,我是京东用户体验设计部前端架构团队的刘威,网上ID是putaoshu,非常高兴 "ITA1024团队"的邀请,有这样的一个机会与大家分享下我们团队关于2015年京东PC新首页的一些前端开发实践,希望通过今天的讲解能为大家以后在大型前端项目开发和改版时提供一个思路和参考.   今天我的讲解主要分为两部分,具体如下: 京东首页前端架构设计与实现 面临挑战 前端页面静态化 前端页面整体架构 前端页面加载策略 前端基础架构 前端工具和系统 前端灾备策略 前端性能优化 前端工程化在电商首

DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证

本文讲的是DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证[编者的话]随着公司业务不断发展以及逐渐向微服务的转变,我们借助于Kubernetes容器化解决方案来标准化和简化应用发布的整个流程,使原来需要大量人工维护和干预的工作变为自动化.本次内容主要是FreeWheel现阶段基于Kubernetes容器化经验和实践的总结,目标是提供一个持续.稳定.高效的容器云平台. 服务健康检查与自我恢复 对线上业务来说,保证服务的正常稳定是重

别再羡慕“别人家的孩子” ,私有云构建让您也可以拥有自己的好孩子

话说,近几年随着企业数字化转型的需求,以及云计算.大数据.物联网等技术的推动,企业对于业务上云的需求愈加明显和具体.但是,同样是云,也有不少企业产生了"别人家的孩子"的感叹. 松下集团的私有云就属于典型的"别人家的孩子".松下用38个可插拔数据库整合了16个集团公司的销售管理系统,形成集团数据库私有云,又通过数据库集成和增强的服务级别协议管理,将运营工作量减少15倍并提高了部署效率,从5个DBA管理8个系统到7个DBA管理170个系统. 不仅如此,建成后的数据库私有

煤炭企业级电力云构建及电网规划应用实现

煤炭企业级电力云构建及电网规划应用实现 敖培,牟龙华 将"云计算"和SOA 软件构架引入煤炭企业级电力系统,构建煤炭企业级电力云计算平台,最大限度地整合当前系统的数据资源和处理器资源,极大提高煤矿电网数据的处理和交互能力,进而为煤炭企业智能电网建设提供有效的技术支持.在该平台的基础上,以煤矿电网规划应用服务为例,阐述了整个服务的实现过程,为"云计算"应用服务落地提供了新的解决思路. 关键词:煤炭企业级电力系统;电网规划;云计算;SOA temp_1209141013

云加数商业地产转型——基于阿里云构建云+中台

在2017云栖大会-上海峰会上,正佳金控集团CIO宋亦皇做了题为<云加数商业地产转型--基于阿里云构建云+中台>的分享.未来在大数据技术和云计算的推动下,商业地产中将出现原生金融.融合体验.对于企业来说,商业决策也会变得更加智慧,体制也会被不断创新.云在未来的商业活动中将凸显其核心地位.

? 阿里云前端工程化工具 Dawn 正式开源!

Dawn Dawn 取「黎明.破晓」之意,原为「阿里云·业务运营团队」内部的前端构建和工程化工具,现已完全开源.它通过 pipeline 和 middleware 将开发过程抽象为相对固定的阶段和有限的操作,简化并统一了开发人员的日常构建与开发相关的工作. 项目地址:https://github.com/alibaba/dawn (感兴趣请赏个 Star) 特点 采用中间件技术,封装常用功能,易于扩展,方便重用 支持 pipeline 让多个 task 协同完成构建任务 简单.一致的命令行接口,

阿里云前端工程化工具 - Dawn

一.Dawn 简介 Dawn(后续将简称为 DN)是阿里云前端团队,新一代的前端构建工具,简化并统一了针对开发人员的「命令行接口」,将开发过程抽象为有序的 6 个阶段 + 1 个常用操作.不会因为工具本身的扩展,而扩展新的用法,统一.一致,免于记忆,通过 DN 创建的工程还将会结合 GitLab CI 进行持续集成. DN 相较于同类工具的特点是什么? 简单.统一.一致,无论扩展还是使用它. 无关框架.甚至可以无关语言.轻中心化(并非完全去中心化,而是「轻」) 松散且易于整合,注重重用,易于扩展

阿里云无线&amp;前端团队是如何基于webpack实现前端工程化的

背景 前端经历了初期的野蛮生长(切图,写简单的特效)--为了兼容浏览器兼容性而出现的各种类库(JQUERY,YUI等--mv*(饱暖思淫欲,代码多了,也就想到怎样组织代码结构,backbone,angularjs等)--工程化(利用grunt,gulp,yeoman做项目脚手架以及打包部署),然而这些东西配置起来需要一定的门槛,并且需要跟业务耦合.全端化.全栈化以及工程化的大环境下,我们希望有这样一套工具可以尽量多的支持业务场景,尽量少的配置,尽量简单的使用命令.而DBL就是这样一个前端自动化工

【技术干货】阿里云构建千万级别架构演变之路

本文作者:乔锐杰,现担任上海驻云信息科技有限公司运维总监/架构师.曾任职过黑客讲师.java软件工程师/网站架构师.高级运维.阿里云架构师等职位.维护过上千台服务器,主导过众安保险.新华社等千万级上云架构.在云端运维.分布式集群架构等方面有着丰富的经验. 前言     一个好的架构是靠演变而来,而不是单纯的靠设计.刚开始做架构设计,我们不可能全方位的考虑到架构的高性能.高扩展性.高安全等各方面的因素.随着业务需求越来越多.业务访问压力越来越大,架构不断的演变及进化,因而造就了一个成熟稳定的大型架