导读
背景
前期准备
架构及实现
提到脚手架,我们自然想到了yeoman生态系统。Yeoman是一个帮助开发者快速创建新项目的工具,通过开发yeoman的插件,即可在终端上使用 yo + 插件名 命令为用户生产文件。
可以实现如下功能:
根据用户的输入选择对应的模版文件
拷贝模版文件到目标目录
安装依赖
因此,分离项目中的业务代码,最终提供可以运行起来的项目模版便成了首要开发目标。
该脚手架创建至今,已由最初的几个react项目模版增加了多个项目,如 node项目、小程序项目等。不仅仅是项目模版,除此之外每个项目内都包含了基础开发的最佳实践,以供开发同学参考。其中,react相关的项目和组件都分别内置了我们的earth-scripts和earth-components-scripts打包脚本(后面会详细介绍),为项目提供统一的开发、打包配置。
脚手架生成项目流程
开发者可以继承yeoman-generator,通过实现提供的生命周期钩子函数,来实现自己的插件。
接下来会详细介绍react项目打包脚本(earth-scripts)的实现方式。(earth-components-scripts与项目打包脚本类似,这里不再赘述)
由于团队内使用react项目开发、打包的配置大同小异,在第一个react项目成功上线后,将其配置抽取出npm包。在充分了解团队内多个项目之间的差异及配置需求后,封装通用逻辑,并开放部分配置以满足项目定制化需求。
初版的配置功能主要如下:
统一分包逻辑:runtime.js 项目启动文件、vendor.js 基础库包、入口文件chunk、异步加载chunk;
仅支持单页应用;
webpack基础配置:dev环境下的hotReload;es6、scss等编译;build压缩等基本功能。
但在实际使用中发现,仅仅是完成项目中的webpack配置已经远远不够,为了丰富脚本内容,提升开发体验,因此在社区内寻找优秀的框架。恰好当时react官方发布了create-react-app这个一键生成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支持
外链资源自动插入到html中,并与externals配置结合
jest配置
内置mock server
更多内容详见 https://www.npmjs.com/package/earth-scripts
由于积极跟进社区变化并及时更新,不断调整配置、使用体验、丰富功能,目前,该脚本已进行了3个重要大版本更新,100+次历史小版本迭代,已满足目前团队内所有项目的打包需求。
项目的应用场景是多个或一个单页应用,为此,规定了项目src下的文件结构,兼容多页和原有的单页模式打包。
打包时读取src下的文件结构,如果无pages,则使用单页模式,如果有pages,并且和html的模版文件一致,则使用多页模式打包。将对应文件夹下的index作为入口文件,多页面即多个入口,动态配置webpack入口文件,同时使用html-webpack-plugin创建多个插件实例生成对应的html
在升级至webpack4后,webpack本身提供了默认分包策略,同时我们也自定义了splitChunks的配置,并配置了分包优先级,最大化利用缓存。
提供分包配置入口,业务可自行决定将某些module在打包时打到vendor工具包中。
不建议将所有的node_modules下的包都打到一个文件里,因为除基础库外也有我们的组件包,组件是有一定的更新频率的,当组件更新了,这个工具包又会重新打包,生成新的chunkhash,这样就失去了缓存的意义。
因此,拆分出common和vendor两个包,业务代码和基础工具包分离:
为了在开发环境也可以使用html5的browserRouter,在webpack-dev-server中对页面路径做了重定向。
在检测到一级路由是项目中pages文件夹下对应的路径,如/pages/user,当访问http://localhost:3000/user.html或者http://localhost:3000/user/xx时则直接返回对应的html,例如,在本例子中为user.html。
在开发中,我们发现,一些高频基础库单独引用cdn的配置,既提升了打包速度,又可以合理利用cdn的资源。
扩展webpack配置使用方式
通过开发webpack插件,将配置中的entry动态插入html中
a) 将自定义配置项与webpack配置结合;
b) 读取配置中的entry,files字段,在插件中将entry中的资源配置到对应的files上。
由于webpack的publicPath配置后,所有静态资源的路径都为当前配置的publicPath。为了满足不同资源有不同的cdn配置,所以通过插件修改:
a)通过html-webpack-plugin的暴露出的hooks事件(beforeAssetTagGeneration),对assets.js,assets.css的路径重写;
b) 由于在webpack打包后,js文件的加载路径是通过__webpack_require__.p拼接的 ,因此修改其值为js cdn的路径。
目前团队内扩展了多个插件,用于对项目功能的扩展:
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
#58技术1024活动开奖#
恭喜微信ID为风儿、莫名的青春、北巷的三位同学,获得100元京东E卡和58技术专属代码台历一本。
恭喜微信ID为宁夏、happy@one、唐、我有一头下毛驴呀,我从来也不骑、🎈、田优秀、意犹未尽的七位同学,获得58技术专属代码台历一本。
请以上获奖的同学,添加58技术小助手(jishu-58)领取奖品。
感谢大家的参与和支持,后续会有更多的活动推出,欢迎持续关注~