San CLI 4.0 升级指南
San CLI 历经多个版本迭代,目前已经进入 4.0 版本,增加 webpack5 支持、优化配置机制等,本文会对升级经验做出总结,期望给读者带来一些启发。
前言
San CLI 更新到 3.0 版本时,已从最初的简单脚手架功能逐步增加了构建命令、插件化、图形化的能力,其功能已经可以满足大部分的业务需求。但在一些特殊场景,其表现仍有待提升,例如配置的修改:San CLI 默认对 CSR 的工程支持较好,但在业务中遇到 SSR 架构的工程时,则需要在 San CLI 默认配置的基础上增加较多配置,3.0 提供的配置修改能力需要对默认规则逐一进行覆盖,对于业务来说还是比较繁琐且不够灵活的。在实际的使用过程中,我们也发现对于一些内置的命令,如 command、 plugin 等命令,使用频率较低,无法达到按需安装,同时新增命令时,使用方式略显复杂。随着社区工具的升级,San CLI 内部也需要不断的更新升级,基于此我们在 4.0 版本对 San CLI 进行了整体功能架构的调整,主要的目标就是提升工具的灵活性及构建性能。
关于 San CLI 的功能介绍可以参考以往公众号文章
San CLI 4.0 升级
San CLI 4.0 的主要升级包括两部分,第一个就是提升灵活性,为此对整体架构进行调整,以实现命令的按需安装,更灵活的配置,提升整体的扩展性;第二个则是针对构建性能的优化,提升用户的使用体验。接下来将详细介绍这两点。
1 架构变化
San CLI 的构建能力主要基于对 webpack 的封装,我们知道,大型项目的 webpack 的配置通常是比较复杂的,集齐一些优化方案也比较耗费时间,而 San CLI 内置了 webpack 常用的配置及优化方案,可以大大简化用户的使用,并在此基础上提供了 init(项目创建)、build(生产环境构建)、 serve(本地调试)三个核心命令,除此之外,内置的 command 、plugin 、inspect 命令可以提供自由扩展命令、插件及查看配置能力,用户可以定制属于自己的前端开发的工具集,San CLI 3.0 的架构如下图所示:
San CLI 4.0 升级后的架构,如下图所示:
为提升工具的灵活性,架构的调整主要包括以下几点:
- 精简命令,按需安装 所有功能及插件都以独立 npm 包存在;内置命令及扩展命令都是按照统一命名规范加载,并从 之前的san-cli-service 包解耦,可以实现独立安装升级,内置命令由之前的 7 个精简为 3 个主要命令,其余命令可通过安装扩展。
- 配置解耦,独立升级 内置的构建配置由 san-cli-config-webpack生成,统一通过插件生成和扩展,外部可以通过加载插件或配置包的形式扩展配置,并且将 webpack 启动包基于事件机制进行重构,提升复用性。
- 统一扩展方式 San CLI 配置都是通过插件进行修改,内外逻辑统一;规定三种类型的扩展:san-cli-xxx自定义命令,san-cli-plugin-xxx 用于修改 San CLI 自身配置, san-cli-ui-xx 增加 San CL UI 可视化界面插件
1.1 命令 / 插件扩展
San CLI 有三种插件扩展的方式:
- 第一种是命令的扩展。新增的自定义命令,只需符合包及 yargs 的命令规范,即可集成到 SanCLI,安装即可使用,无需采用之前的命令式安装。自定义命令包导出的变量格式如下所示:
- 第二种是可修改 webapck 配置的 service 插件。同样需要符合包命名规范,并导出统一字段:插件 id 和实际执行函数,通过webpack-chain 的语法修改默认配置。在 4.0 中增加了插件的配置映射 pickConfig, 将插件的配置项与 SanCLI 配置文件中的配置项隔离,使得插件的使用更纯粹。插件包导出的变量格式如下所示:
- 第三种则是用于 San CLI UI 可视化界面的插件,在符合包命名规范的基础上可根据提供的 api 创建不同类型的可视化部件.
1.2 配置机制
San CLI 3.0 内默认支持 CSR 工程的打包,webpack 相关的 loader 及 rules 等均在 san-cli-service 包内置,在执行 san serve/build 命令构建时,统一通过 service 生成,整个流程对用户是透明的,用户可以快速开启一个 San 的工程,但整个配置的生成是在 Service 内部流转,对开发者来说只能通过 提供的 webpack-chain 覆盖修改,如果遇到需要对构建流程有较大改动时,配置较多且繁琐,因此需要更加灵活的控制内置配置的生成,下图是配置升级前模块调用关系图:
如上图所示,配置升级前所有的 loader、 rules 等 webpack 配置都在 service 内部调用,开发者可以通过增加 San CLI 的 plugin 进行修改,或者在配置文件中通过函数对最终生成的 webpack 配置的 JSON 对象进行修改。内置的 san-cli-config-webpack 的配置是完全执行完毕,即使自定义的构建配置可能并不需要,甚至在最后需要手动覆盖。整个配置的生成流程:
- getWebpackConfig 调用 getWebpackChainConfig 生成 chainConfig ,同时得到san-cli-config-webapck 内置的配置
- getWebpackChainConfig 内依赖san-cli-config-webapck 内的函数 createChainConfig 创建 chainConfig ,加载san-cli-config-webapck 内置的配置
- 执行 webpackChainFns 内的所有函数,应用 plugin的插件扩展修改配置
- 回到 getWebpackConfig 继续执行 webpackRawConfigFns 内一些对 config直接修改的方法
- 调用 san-cli-config-webapck 内的函数 createDevServerConfig,合并传入的devServer 配置和默认配置
在配置升级后,所有的内置的 webpack 相关配置都是以 plugin 方式存在,统一了内外部配置的修改方式;并且插件以资源类型进行拆分,加载配置时提供了每个插件的开关,用户可以通过传入插件的配置来关闭对应的插件;与此同时为提升同一类型配置的复用性,在 San CLI 的配置文件内增加了 extends 关键字,可以批量增加配置包或者配置插件,更多细节可查看 san-cli-config-webpack 配置包,升级后的模块调用关系如下如所示:
配置拆分后,移除了对 san-cli-config-webapck 创建 webpackChain 的依赖,san-cli-config-webapck 仅作为配置包加载,不参与 service 流程的执行。调用 api.getWebpackConfig 生成 webpack 配置流程:
- getWebpackConfig 调用 getWebpackChainConfig 生成 chainConfig
- 在getWebpackChainConfig 内通过 new Config 生成 webapckChain 的实例。
- 执行webpackChainFns 内的所有函数,应用 plugin 的插件扩展修改
- 回到 getWebpackConfig 继续执行 webpackRawConfigFns 内一些对 config 直接修改的方法
- 取得 san-cli-config-webapck内的函数 devServerOptions,在 service 内部做合并
2 性能提升
San CLI 4.0 升级的第二个部分就是对构建性能的优化,将内置的 webpack 版本由 4 升级到 5。Webpack5 甩掉了一些历史包袱,并做了一些优化,进一步提升了 San CLI 的构建体验。关于 webpack5 升级的文章有很多,这里我们仅介绍升级后为 San CLI 增加的一些新特性。
2.1 新特性与效果
Webpack5 升级官方有一些关于构建性能的指导,比如 loader 设置 exclude 去掉不包含的模块,精简 loader/plugin 的数量、应用缓存等,升级的过程就是不断的修改、调试、运行的过程,不再详述,我们简要总结下在 San CLI 内部经验证保留的功能:
首先是 San CLI 4.0 内默认开启的能力(以下效果数据均基于 San CLI 创建的默认 demo 测试产生):
- Pollyfill 按需加载:Webpack5 移除了 node 相关的依赖,结合我们实现的 pollyfill 按需加载方案,其vendor 的体积减少 5.3%(19.62kb)
- Cache:Webpack5 的构建缓存能力,在生产环境关闭,开发环境开启且默认使用memory 缓存,在 San CLI 中指定了缓存到文件系统(filesystem),开发环境非首次启动可以减少78.14%,增量构建减少 7.66%
- Asset module:Webpack5 的资源处理模块,可以替换 url-loader、file-loader,以减少 loader 的数量,demo 对比来看没有明显的提升(demo 工程较小),但loader 的数据量的减少对一些大型工程打包的速度会有一定的影响
以上都是在 San CLI 内默认开启的功能,接下来介绍下选择开启的功能:
- Esbuild-loader:开启后,在开发环境替换 babel-loader,首次减少 22.25%;增量构建减少31.17%;生产环境替换 terser 对 js 进行压缩 ,构建速度有所提升(减少 34%),但是会导致包大小略有增加
- Thread-loader:多进程打包,只应用在生产环境,开启也消耗时间(600ms)因此推荐只在大型项目时开启,默认关闭
- RuntimeChunk:Webpack5 支持拆分运行时 chunk,推荐多入口情况下选择开启,开启后体积略有降低,配合splitChunks 进一步可以降低入口 bundle 的大小
- Dlls 分包预编译:引入后对构建流程有所改造,通过 demo的测试,仅在开发环境增量构建速度有所降低,相较于对产出的影响,在 San CLI 内部默认不应用
- optimization.moduleIds:Webapck5 新增的文件生成的优化,San CLI 内默认设置为deterministic 以减少文件的 hash 修改频次,有利于缓存
2.2 升级问题总结
在升级的过程中,我们遇到的问题主要有以下两类:
- 构建性能:尽管 webpack5 官方升级说明中指出构建性能有所优化和提升,但是在实际升级过程中,将所有的相关 loader、plugin 升级到合适版本后发现,构建速度并没有明显提升,甚至在生产环境下构建速度有所下降,为此我们尝试了一些方法,总结为以下几点:
持久化缓存
webpack5 可指定缓存到文件系统,这在本地开发环境下,可以极大提升构建速度。
{
cache: {
type: ‘filesystem’
}
}
精简 plugin
webpack5 提供了一些配置和功能,可以替代一些 loader/plugin 的使用,我们知道 loader/plugin 的数量在一定程度上会影响构建的速度,例如:使用 Asset module 替换 url-loader、file-loader;使用 lint 工具替换 CaseSensitivePathsPlugin 插件;使用 output.clean 的配置项替换 CleanWebpackPlugin 插件等。
按需关闭配置项
webpack5 内部新增了一些默认开启的计算策略,但在构建时也会影响到构建的速度,可在使用时按需关闭,例如:可通过指定 module.unsafeCache = true 来关闭 webpack5 的安全缓存策略,可减少约 800ms 左右的时间;生产环境下指定 output.pathinfo=false 禁用模块的注释信息,仅在开发环境下启用;注意简化 stats 状态信息,stats.toJSON 转换全部信息也需要耗费一定的时间,因此在使用时推荐传入配置 {all: false},仅提取需要的部分。写法上注意检查避免 export * 的写法。
- 工具更新和兼容
关于 esModule 的支持:webpack5 已全面拥抱 ES Module,相关的插件如:html-loader、san-loader、css-loader 等均支持 esModule 配置项,以便开启 ES Module 的语法支持。为此,在 San CLI 内部新增了 esModule 配置项,用于一键开启内置 loader 的相关配置(该配置项是在 .san 单文件构建且启用 css modules 的必要选项)。
关于 tree shaking 失效的问题:在 webpack5 升级之前,为保证构建的一致性,在 babel 使用时引入了 @babel/plugin-transform-modules-commonjs 插件,将代码转换为 commonjs 后再进行处理,我们知道,webpack 的 tree shaking 是基于 ES module 的语法实现,因此在 San CLI 的默认 babel 配置中移除了该插件,推荐工程内部采用 ES module 的语法,以便更好的利用 tree shaking 减小产出体积。
San CLI 内暂缓升级的部分:尽管 webpack5 更新已有很长时间了,但其周边的相关插件并没有完全适配,San CLI 在升级时也遇到了相关的情况,例如依赖的 webpack-chain 包,由于其未能支持一些 webpack5 新增的 api,导致在 San CLI 内部使用时仍需要单独处理此类配置,此类工具需要静待社区的更新;另外,webpack-dev-server 的 4.x 版本有较多不兼容改变,为保证 San CLI 用户的平滑升级,我们内置的 webpack-dev-server 仍考虑采用 3.x 的版本。
2.3 对业务构建性能的提升
San CLI 4.0 发布后,我们将其应用到了不同的类型的业务,性能有不同程度的提升。整体包体积均有所减小,构建速度有所提升,在不同的应用架构下趋势相同:
- C 端的多页应用(代码行数约 11710)构建包体积减少约 2.7%,生产环境下构建速度提升约13.2%,开发环境尤其是非首次启动时速度提升较明显(约 86%)
- B 端单页应用(代码行数约 70582)构建包体积减少约 0.9%,生产及开发环境下构建速度均有所提升
3 功能增强
除以上提到的架构升级和内置配置的修改外,在 San CLI 4.0 上增加了以下功能。
3.1 typescript 构建支持
在 San CLI 3.0 及之前版本,默认创建 js 类型的工程。使用 San CLI 4.0 创建项目时,支持选择 typescript 作为工程的语言类型。
在实现上主要基于 babel 的预设 @babel/preset-typescript 来支持 ts 文件的语法转换,而语法检测的工作默认采用 @typescript-eslint 来实现,项目创建时已默认配置,用户也可自行配置,利用 tsc 命令或配合 vscode 插件等实现。
3.2 san 单文件构建体验提升
在 San CLI 4.0 我们进一步优化了单文件的构建体验,在全局安装 san-cli 之后,只需以下两步,即可调试一个单文件组件:
- 创建一个 index.san 文件,内容为 san 官网最简单的单文件内容
- 执行 san serve index.san
同样的,执行 san build index.san 即可得到构建产出。
3.3 esm 构建支持
San CLI 4.0 还有一个新增的构建选项 —— 基于 esm 的本地构建。在本地调试场景下,我们更在意的是功能的快速查看和验证,特别是在一些大型的项目中,如果本地一个小的修改需要等待几秒钟完成构建,这个开发体验是很令人崩溃的,也就是说构建的速度很重要。而实际情况中,我们通常使用的本地浏览器的版本较新,能够很好的支持 js 的 esnext 版本,并不需要构建中通过 babel 等工具做代码的 es5 转换,因此在本地构建场景下,只需要实现基于 esm 的构建即可满足需求。
从构建工具的角度来看,随着社区构建工具的不断更新,出现了一些类似 esbuild 的构建工具,从上图数据来看,esbuild 构建速度远远大于 Webpack。esbuild 更适合处理 js 和 ts (对比 babel )来做代码转换,而在本地构架的场景下,恰好可以满足只构建 es6 以上版本,因此我们在 San CLI 内利用 esbuild-loader 来实现基于 esm 的构建功能,通过 san serve --esm 命令即可启动,通过 demo 数据的对比来看,本地调试的启动时间可降低 32.7%。
最后
社区的工具不断推陈出新,我们也在持续跟进,不断优化 San CLI 的功能,丰富 San CLI 的使用场景,以期给用户带来更好的使用体验,如果有任何疑问或想法,欢迎提出 issue 或 pr 。
点击进入获得更多技术信息~~
San CLI 4.0 升级指南相关推荐
- Spring Boot 3.0 正式发布,这份升级指南必须收藏
Spring Boot 3.0 现已正式发布,它包含了 12 个月以来 151 个开发者的 5700 多次代码提交.这是自 4.5 年前发布 2.0 以来,Spring Boot 的第一次重大修订. ...
- PyTorch 0.4新版本 升级指南 no_grad
PyTorch 0.4新版本 升级指南 [导读]今天大家比较关心的是PyTorch在GitHub发布0.4.0版本,专知成员Huaiwen详细讲解了PyTorch新版本的变动信息, 本次升级, 只做了 ...
- [转] PyTorch 0.4新版本 升级指南 no_grad
转自PyTorch 0.4新版本 升级指南,博主为ShellCollector. PyTorch 0.4新版本 升级指南 PyTorch 终于从0.3.1升级到0.4.0了, 首先引入眼帘的,是PyT ...
- 小米9什么时间升级android10,小米9/MIX 3 现在即可升级安卓10.0!升级指南戳这里...
原标题:小米9/MIX 3 现在即可升级安卓10.0!升级指南戳这里 [手机频道·原创] 最近小米接连有消息爆出,在今天早些时候的I/O开发者大会上,谷歌在Android Q中推出了许多新功能.现在, ...
- 52ABP前端升级2.0.x指南
52ABP前端升级2.0.x指南 前言 本篇内容为指导从 yoyo-ng-module 1.x 升级到 yoyo-ng-module 2.x 详细说明 52ABP前端框架采用的是 基于NG-Zorro ...
- TiDB 4.0 升级 5.1 二三事——避坑指南
\n> 原文来源: https://tidb.net/blog/ce260ea4 \n\n# 1. 背景 TiDB 5.1 版本 GA 到目前已经有一年时间,在稳定性.易用性.性能提升等各个方面 ...
- VMware vSphere 6.0 升级已知问题
官方链接 已知问题 已知问题分为如下类别. 安装问题 升级问题 许可问题 vCenter Single Sign-On 和证书管理问题 网络连接问题 存储问题 服务器配置问题 vCenter Serv ...
- ESXI 4.0 升级 ESXI 4.1 手记
一开始,以为Vmware vSphere Host Update Utility4能支持升级 4.1,结果报错··· 出错了 Google了一下,发现也有外国朋友遇到这样的问题,呵呵,我这里只是讲升级 ...
- Vue CLI 3.0 正式发布,Vue.js 开发标准化工具
Vue CLI 3.0 已发布,该版本经历了重构,旨在: 减少现代前端工具的配置烦扰,尤其是在将多个工具混合在一起使用时: 尽可能在工具链中加入最佳实践,让它成为任意 Vue 应用程序的默认实践. V ...
最新文章
- android之http协议编程(源码ppt),Android网络编程(八)源码解析OkHttp中篇[复用连接池]...
- linux vi de ce,linux下vi命令Vi命令集
- Windows命令行参数的知识(一)
- vb在服务器上新建文件夹,vb.net-如果不存在,如何在VB中创建文件夹?
- 160 - 51 DueList.6
- 取一定范围内随机小数 c_算伪随机概率中C值的快捷方法
- string和StringBuilder的选择
- js判断url是否有效
- Android开发性能优化大总结
- Android Studio 技巧
- 理解文档对象模型(2)
- 公务员从事计算机网络工作,干程序员好,还是从事公务员更有前途?网友:要是我就当公务员!...
- java 生成 顺序 uuid_Java 生成有序 UUID
- 数字孪生CIM智慧城市BIM,城市cim可视化解决方案公司
- 2021年全球与中国数字频率计行业市场规模及发展前景分析
- 学习OpenCV——计算邻接区域列表(build_adjoin)
- html 中 超链接的写法,网页超链接样式的CSS写法
- Redhat相关快捷键
- 阿里云部署公司网盘实例
- 网站只有首页能打开,其他页面404