作者:居玉皓,去哪儿网移动架构组(YMFE)前端工程师。是 Avalon 开源组件库 OniUI 的主要代码贡献者和维护者。目前主要从事平台技术服务设施的搭建,是用户行为收集分析平台QReport 和移动开发框架 Qunar React Native 的主要开发者。现阶段负责去哪儿网前端构建统一解决方案 Ykit。
为了让大家更深入地了解Ykit背后的研发故事,CSDN“前端开发创新实践”线上峰会已邀请到居玉皓做深入分享。他将结合Ykit的研发过程,分享如何管理项目构建,以及在保证构建稳定性方面的探索和经验。
Webpack 是现在最流行的前端构建工具之一。它具备高可配置性的特点,你可以用它来构建 React、Angular、Vue 等等各种类型的 Javascript 应用。它的构建过程十分灵活,支持使用各种模块加载器和插件进行个性化定制。
然而从另一方面来讲,Webpack 的高灵活性也带来了配置过于复杂,对初学者不友好等问题。在公司内部我们希望开发同学能更加专注于研发本身,摆脱掉繁冗的配置文件并且避免一些实际使用中的陷阱 。在本文中会介绍基于 Webpack 实现的构建工具 Ykit,它在 Webpack 基础上进行了哪些优化,以及它在去哪儿网的应用现状。
背景——各自为战的混乱
最开始的时候公司里的开发同学使用过 Gulp、Grunt、Webpack 等各种构建工具,大家各玩各的,看上去也都能满足需求,然而从这些独立构建的工程中我们发现了几个共同的问题:
- 几乎每个工程都要通过配置或脚本完成一些特定的工作。比如指定资源输入输出路径、生成资源版本号、配置 HMR 、搭建 mock 服务等等,这些类似的工作经常被重头到尾实现一遍。而如果这些工作可以由统一的工具来实现则可以节省很多开发成本。
- 缺少构建层面的优化。不管是从打包出来的资源体积以及编译速度上,不少工程都有很大的提升空间。我们曾试着将其中一个工程的公用库用 CommonChunks 的方式提取出来,将整体资源体积减小了多一半。这主要是因为很多时候开发同学只是想短平快地完成一些业务,并不会过多关注流程上的优化。
- 沟通和学习成本高。大家各玩一套的结果是跨团队和跨工程时会由于构建工具和流程不一样而带来额外的成本。当面对一个缺少文档的新的工程时,一个刚接触的同学可能会很懵,要先花时间搭建环境才能把它运行起来。而工程之间构建工具的不一致也会导致切换环境时要花费更多的精力。
构建方式不同造成沟通不畅
由这些现象我们在想,能不能提供一个统一的工具出来,将共性的工作交由工具来完成。这样既可以保持开发体验的一致性,也使得开发同学在构建时效率更高并且少踩一些坑。
Ykit——定制与灵活的统一
Ykit 是基于 Webapck 的,熟悉 Webpack 的同学可能知道它的配置非常多样和灵活,可以满足各种个性化需求,但是从零开始搭建起一个完整的开发和生产环境比较费时,对于新手来说不够友好。Ykit 希望实现的是兼具定制性与灵活性,让开发同学既可以通过定制化方案快速地搭建环境,也允许在其基础上实现个性化的配置。
一键生成开发环境
Ykit 与 Webpack 最大的不同就是 Ykit 自身的插件机制,这个插件可以包含 Webpack 配置、必要的 npm 模块、特定的构建流程任务等。可以用一个插件封装一整套特定类型的解决方案,而开发者唯一要做的就是使用一行命令去安装它。
举例来说当我们要做一个 React 应用,那么只要安装上相应的 React 插件,插件里面包含了 React 相关的模块以及 Babel 来处理 ES6。而当你想使用 Ant Design ,也是一样的,安装相应的插件,然后就可以在代码中引用其组件了。目前公司内外有十几个不同的插件来满足多样化的需求。
在插件中也可以去完成各种构建任务。在去哪儿内部的前端构建流程中有很多固定的工作,比如打包结果的拷贝和上传,生成一个单独文件用来存放资源版本号等等。这些类似的工作都被纳入了一个专门的插件中,每个工程将其引入之后即不必担心这些构建流程中的问题。
总的来说 Ykit 本身只是一个壳,真正的多样化构建依赖于插件。每个插件都是一个 npm 模块,它们将构建过程中的配置和功能进行封装,使得 Ykit 能满足多种多样的需求而又不会互相冲突,同时保持了开发体验的相对一致性。
高度*的配置
Ykit 不是一个黑盒,它允许开发者侵入开发和构建中的各个环节来实现定制化的需求。
三层配置
构建依赖于 Webpack 的配置,Ykit 将它分为三级。最底层的是 Ykit 内在的核心配置,它里面只有一些最基本的东西,比如公共的配置项和必备的 Webpack 插件等。在 Ykit 核心之上是插件中的配置,这里是实现功能的主要部分。插件包含了特定场景的配置以及用来处理各种类型文件的 loader。最上层的是业务中的配置文件,它的优先级最高,可以获取到任何底层的配置项并进行修改。也就是说在一个应用中,构建配置最终是取决于应用自身。
在本地开发服务中,Ykit 支持了自定义中间件来处理请求。也就是说,当浏览器向一个本地 Server 发起请求时,你可以在自己的中间件里操作请求和响应对象。比如利用它来实现 mock 或者代理,以及处理特定类型的文件编译等等。另外,Ykit 在构建过程中提供了钩子帮助开发同学完成一些自定义的构建任务。这些钩子支持同步和异步,并且提供了构建流程中的信息。比如在 afterPack 这个钩子中可以获取到当前打包后的资源信息,方便对打包资源结果进行更进一步的操作。
构建速度的全面优化
Webpack 一直容易被人诟病的就是它的构建速度慢。官方虽然也给出了许多优化策略,但是一些优化只对特定类型的应用有效果,对于其他应用则效果有限。对于开发同学来说并不是总有充足的时间去一个个尝试到自己的工程中,而这些工作由 Ykit 来做却是非常合适的。
很多使用过 Webpack 的同学应该不难发现 Webpack 总是第一次构建很慢。启动工程时要等好久才能把页面打开,这是因为 Webpack 会把所有的资源都打包一遍。如果工程中有 10 个 JavaScript,而第一次打开的页面只请求了其中的一个,那么也要等所有资源作为一个整体打包完成之后返回那一个。
本地服务资源过滤
Ykit 在这里进行了一次入口过滤。当本地服务接收到页面的请求时,会带着所请求的资源去资源列表中找,生成一个只含有所请求的资源入口的 Webpack 实例,打包完成后立即返回结果。其实实际情况还要比这个更复杂一些,比如所请求的资源有可能只是打包的副产品而不在配置入口中,Ykit 对这些情况都进行了处理。最后达到的效果是页面请求哪个资源才会打包哪个资源,即便是对于很大型的工程来说第一次打开的速度也会相对来说可以接受。
本地服务优化
这里对三个工程进行测试,它们分别使用了 React、jQuery、Vue,资源数也各不相同。我们分别计算了采用入口过滤优化前后工程第一次构建的速度,发现它对于多页应用等资源数量比较多的工程较为有效。另外优化效果也和代码的组织方式有关,如果公用代码已经都被提取了出来,优化效果也将相对不那么明显。
压缩优化
另一个在 Webpack 中很耗时的操作就是压缩资源,当我们的工程发布 beta 或者线上时,构建的速度一定要快,否则的话就会浪费开发和测试同学的时间,等很久才能去验证结果。与 Webpack 不同,Ykit 并没有采用它内置的 UglifyJS 插件,而是创建了一个进程集群(cluster),一个进程只负责压缩一个资源,从而更有效地利用了系统的计算能力和内存。从上面图中可以看到使用了压缩优化之后构建耗时有了比较显著的下降。
与此同时多进程压缩也解决了较大型应用在使用 Webpack 压缩资源时内存溢出的问题。V8 虚拟机的内存限制在 64 位系统上为 1.4GB,在 32 位系统则为 0.7GB。当工程规模庞大之后,构建过程有可能超过这个限制而导致奔溃。在 Ykit 中一个进程只负责一个资源的压缩,所以完全不必有这种担心。
Hy2 优化
除上面提到的优化之外,在 Ykit 插件中还进行了更加个性化和深入的优化。 因为一般来讲对于不同类型应用优化的策略也不一样,比如使用 Babel 来编译 ES6 代码的时候可以采用 Happypack 替代原有的 Loader 进行打包,像是这类的配置就适合放在插件中。在去哪儿有一套移动端的开发框架 Hy2,它内部的依赖库很多,构建速度也较慢。我们在它的插件中使用了 Happypack、 DLLPlugin 等优化策略,将首次打包的时间从 10s 左右减少到了 5s 左右,而 rebuild 的时间也减少到了之前的 1/3,总体效果是比较可观的。针对使用场景的不同,每个 Ykit 插件都可以对自身进行深度优化,将对应情景的最佳实践封装起来提供给开发者。
在去哪儿的使用现状
目前公司内部大部分业务线都已经开始在使用 Ykit 进行构建和发布,截止到目前上线的工程有 90 个左右。在 Ykit 不断迭代的过程中,我们发现通过插件机制确实解决了之前遇到的问题,将重复性的构建工作都交给 Ykit 来做,业务同学仍然可以去玩各种各样的技术方案,而开发体验是相对统一的。
另外值得一提的是,除了 Web 工程的构建以外,目前去哪儿的小程序目前也是使用 Ykit 进行构建的。我们打造了专门为小程序开发而定制的插件,它内置了初始化脚手架,编译小程序特定语法,支持引入 npm 包等等功能。这表明了对于 Ykit 来说即便是截然不同的开发环境也可以实现开发体验的相对统一,开发同学也不必在电脑中安装一大堆开发工具了。
未来展望
在以后我们还会着眼更多的场景,就像现在为小程序提供的脚手架和开发工具一样,将来可能会有更多这样的模式,使得搭建各种各样的开发环境都变得更加简单,让开发同学花更少的精力在构建上面而更加专注于研发本身。
现在 Ykit 已经开源(YMFE-Ykit),欢迎一起为它添砖加瓦:)
2017年7月8日(星期六),「“前端开发创新实践”线上峰会」将在 CSDN 学院召开。本次峰会集结来自Smashing Magazine、美国Hulu、美团、广发证券、去哪儿网、百度的多位国内外知名前端开发专家、资深架构师,主题涵盖响应式布局、Redux、Mobx、状态管理、构建方案、代码复用、个性化图表定制度等前端开发重难点技术话题。技术解析加项目实战,帮你开拓解决问题的思路,增强技术探索实践能力。目前火热报名中,5折票价最后三天,现在购买立省200元,欲购从速,详情点击注册参会!