导读

58金融前端脚手架的设计与实现

17年初,前端项目开始逐步大规模转向react技术栈。在完整经过第一个react项目的搭建、开发、上线后,积累了react项目运行必要的配置、使用方式、最佳实践等,这些为后续项目的迁移提供了参考。

 

背景

起初团队内新的react项目的搭建都是通过手动拷贝其他项目完成的,例如需要拷贝webpack配置、代码基本结构、组织方式、package.json等。这样虽然可以创建新的项目,但容易出现以下问题:

  • 人工操作,在拷贝的过程中容易出现遗漏或者是误修改;
  • 开发人员既需要进行业务开发,也需要关注项目的配置,增加了开发成本;
  • 不同项目有自己定制的部分,团队人员之间接手项目也需要熟悉一遍配置流程,无法迅速的进入业务开发;
  • 项目基础包不同,开发人员需要频繁切换环境,增加了迁移成本。

为了解决以上痛点,迫切需要推出两个工具:

一个自动化创建项目的工具,一键生成需要的项目模版,免去开发人员在项目之间来回拷贝;

一个通用打包脚本,将项目配置这种与业务无关的逻辑提取出一个通用npm包,使用时安装即可,开发同学可以无需关注配置细节、打包细节即可快速运行项目。

 

前期准备

为了开发出更贴合团队需求的工具,需要从以下几个方面考虑:

1、根据团队现有的项目类型,划分不同的项目模版,为开发项目脚手架作准备,提升开发效率、质量

  • 确定项目类型

开发脚手架的第一步就是要明确需要支持哪些项目,因为我们做的是多个不同的项目集合,需要充分了解团队内的项目结构,合理划分。如m端项目、pc项目,这两个方向的项目可以分别划分为两个模版,因为不同平台的页面需要的基础库不同、开发结构也不同;

  • 项目模版的可扩展性。需要考虑后续可能会增加多种项目模版,方便模版的扩展;
  • 技术栈基础库版本统一,如react、react-router。合理约束基础库的版本,降低项目迁移时的人员学习成本。

2、提取项目通用配置,高度抽象不同项目间的配置差异,为开发打包脚本做准备,提升开发体验

  • 统一项目打包基础库,如webpack、babel
  • 提供个性化配置入口以满足不同业务需求
  • 方便接入,项目运行零配置
  • 与部署平台低耦合,可以快速对接集团以及金融内部的部署平台。

 

及实现

脚手架

提到脚手架,我们自然想到了yeoman生态系统。Yeoman是一个帮助开发者快速创建新项目的工具,通过开发yeoman的插件,即可在终端上使用 yo + 插件名 命令为用户生产文件。

 

可以实现如下功能:

  • 根据用户的输入选择对应的模版文件
  • 拷贝模版文件到目标目录
  • 安装依赖

因此,分离项目中的业务代码,最终提供可以运行起来的项目模版便成了首要开发目标。

该脚手架创建至今,已由最初的几个react项目模版增加了多个项目,如 node项目、项目等。不仅仅是项目模版,除此之外每个项目内都包含了基础开发的最佳实践,以供开发同学参考。

其中,react相关的项目和组件都分别内置了我们的earth-scripts和earth-components-scripts打包脚本(后面会详细介绍),为项目提供统一的开发、打包配置。

 

 

脚手架生成项目流程

实现过程

开发者可以继承yeoman-generator,通过实现提供的生命周期钩子函数,来实现自己的插件。

 

接下来会详细介绍react项目打包脚本(earth-scripts)的实现方式。(earth-components-scripts与项目打包脚本类似,这里不再赘述)

react项目打包脚本

由于团队内使用react项目开发、打包的配置大同小异,在第一个react项目成功上线后,将其配置抽取出npm包。在充分了解团队内多个项目之间的差异及配置需求后,封装通用逻辑,并开放部分配置以满足项目定制化需求。

初版的配置功能主要如下:

  • 统一分包逻辑:runtime.js 项目启动文件、vendor.js 基础库包、入口文件chunk、异步加载chunk;
  • 仅支持单页应用;
  • webpack基础配置:dev环境下的hotReload;es6、s等编译;build压缩等基本功能。

但在实际使用中发现,仅仅是完成项目中的webpack配置已经远远不够,为了丰富脚本内容,提升开发体验,因此在社区内寻找优秀的。恰好当时react官方发布了create-react-这个一键生成react项目的工具,通过查看create-react-app eject后的项目配置( 0.3.x 版本),发现其已经提供非常丰富的功能,正好弥补我们开发的不足,如:

  • 开发环境下自动启动浏览器运行页面、端口号检测
  • react-dev-utils 提供多种插件和工具方法来提升开发体验:,比如:

开发环境下代码出错时提供友好的提示信息;

可视化展示build后的资源大小以及与上次build后资源大小的对比;

格式化webpack输出的资源信息;

清空终端console信息;

接口代理配置和webpack-dev-server的结合;

  • 通过使用env配置来实现不同环境下的差异化配置
  • 单元测试Jest的基础配置及运行
  • ......

最终我们考虑将现有配置和react官方提供的脚本融合,提取出一套适用于金融前端团队使用的react打包脚本。除包含以上基本功能外,提供了如下能力(主要):

  • 提供自定义config,开放部分webpack配置,如plugin、alias
  • 支持typescirpt
  • 支持多页
  • 分包优化
  • 开发环境下browserRouter支持
  • 外链资源自动插入到中,并与externals配置结合
  • jest配置
  • 内置mock server

更多内容详见 https://www.npmjs.com/package/earth-scripts

由于积极跟进社区变化并及时更新,不断调整配置、使用体验、丰富功能,目前,该脚本已进行了3个重要大版本更新100+次历史小版本迭代,已满足目前团队内所有项目的打包需求。

 

实现过程

1、支持多页应用

项目的应用场景是多个或一个单页应用,为此,规定了项目src下的文件结构,兼容多页和原有的单页模式打包。

 

打包时读取src下的文件结构,如果无pages,则使用单页模式,如果有pages,并且和html的模版文件一致,则使用多页模式打包。将对应文件夹下的index作为入口文件,多页面即多个入口,动态配置webpack入口文件,同时使用html-webpack-plugin创建多个插件实例生成对应的html

2、分包优化

在升级至webpack4后,webpack本身提供了默认分包策略,同时我们也自定义了splitChunks的配置,并配置了分包优先级,最大化利用缓存。

提供分包配置入口,业务可自行决定将某些module在打包时打到vendor工具包中。

不建议将所有的node_modules下的包都打到一个文件里,因为除基础库外也有我们的组件包,组件是有一定的更新频率的,当组件更新了,这个工具包又会重新打包,生成新的chunkhash,这样就失去了缓存的意义。

因此,拆分出common和vendor两个包,业务代码和基础工具包分离:

 

3、开发环境下browserRouter支持

为了在开发环境也可以使用html5的browserRouter,在webpack-dev-server中对页面路径做了重定向。

在检测到一级路由是项目中pages文件夹下对应的路径,如/pages/user,当访问http://localhost:3000/user.html或者http://localhost:3000/user/xx时则直接返回对应的html,例如,在本例子中为user.html。

 

4、外链资源自动插入到html中,并与externals配置结合

在开发中,我们发现,一些高频基础库单独引用cdn的配置,既提升了打包速度,又可以合理利用cdn的资源。

 

扩展webpack配置使用方式

通过开发webpack插件,将配置中的entry动态插入html中

a) 将自定义配置项与webpack配置结合;

b) 读取配置中的entry,files字段,在插件中将entry中的资源配置到对应的files上。

 

5、不同类型资源使用不同的cdn路径

由于webpack的publicPath配置后,所有静态资源的路径都为当前配置的publicPath。为了满足不同资源有不同的cdn配置,所以通过插件修改:

a)通过html-webpack-plugin的暴露出的hooks事件(beforeAssetTagGeneration),对assets.js,assets.css的路径重写;

b) 由于在webpack打包后,js文件的加载路径是通过__webpack_require__.p拼接的 ,因此修改其值为js cdn的路径。

 

6、扩展的功能插件

目前团队内扩展了多个插件,用于对项目功能的扩展:

  • service worker插件,提供PWA能力;
  • 错误捕获babel插件,为项目代码添加try-catch,并配合金融日志系统进行错误上报。

 

总结

脚手架及打包脚本已推广至金融前端部门所有项目使用,目前使用的项目有260+,组件55+。

提升了前端团队开发效率,带来以下好处:

  • 技术栈一致、基础类库一致;
  • 项目交接方便;
  • 高扩展性;
  • 快速创建项目,零配置运行,专注于业务开发。

后续仍会持续关注业内其他优秀的解决方案,不断优化,使开发更高效、提升开发质量。

 

参考文献:

https://www.npmjs.com/package/react-scripts/v/0.2.2

https://github.com/webpack/webpack/releases/tag/v4.42.1

 

作者简介:

坑红艳,金融前端技术部开发工程师,负责金融支付和基础平台前端开发。

胜象大百科