Growing Web 目标 #9
-
描述Growing Web 是一个注重「可生长」的企业级基础前端架构。
动机消除技术孤岛统一的构建工具与模板代码能缓解项目之间各自为政的问题,但随着时间的推移,构建配置与模板代码将会被项目同化,从而产生差异无法直接升级,它们将会成为孤岛。 当企业项目数量变多或规模变大的时候,原来运作良好的部分都会变得糟糕,而工程的复杂度却阻碍了开发工具的升级,这样的问题在不同的企业、不同的团队反复发生,因此我们希望将最基础的部分从业务工程中抽离出来,建设成高可用的解决方案,借机建立必要的约束在当前与未来的发展取得平衡。 在源头解决问题工具是有局限性的,当我们的工程架构过于依赖某个具体的工具上的时候,它们会因为内外部环境变化而产生新的问题,这很容让我们的基础建设工作被这些问题所缠身,而忽视了真正的问题源头——工程缺乏透明度:技术标准缺位、具体工具的职责范围过于模糊且宽泛。 工具应当基于技术标准运行,这样工具可以随时升级或被替换;架构应当为每个环节定义边界,让工具可以被组合。 为生长提供土壤通过技术标准与基于标准的工具链,让不同的技术栈与不同的团队开发的应用或模块可以自然的集成到不同的环境中,通过组合为企业而产生深远的影响:
详细设计常规的企业前端架构模型更关注「可持续」,它建立在稳定的企业商业与产品模式中,在既定的视野范围内它更关注建立「约束」确保各个项目可持续维护。甚至国内有些大公司会尝试构建 IDE 到部署整个链路的研发平台来保障这一点,这样架构的风险是约束过大进而阻碍开发者的技术成长。 可生长的架构将 Web 生态发展视作促进业务发展的机遇,它认为业务的发展以及技术的发展将随时超出人的预期,因此它更关注业务、自身的「可生长」的必备条件。 应用集成的模式页面模式
挂件模式
库模式
技术标准它涵盖应用入口标准、工程清单的标准、应用清单、页面输出配置的标准等,它是此架构中最关键的部分,它的职责是让 Web 工程变得透明,是企业内部生态「可生长」的基础。 应用入口应用的入口是一个包含基本生命周期函数的 JS 文件,和传统的应用入口不一样的地方是它不能自运行,它导出固定范式的生命周期函数,以便应用容器可以运行它。应用通过应用容器实现系统集成与实施统一的用户体验优化策略。
工程清单工程清单是一种高于构建工具配置的抽象,它对源代码入口、产物出口等关键资源进行标准化定义,开发服务器与打包工具根据工程清单而工作。 工程清单采用的是 JSON 而不是 JS 文件描述,这样做的目的是确保它可以随时升级。
应用清单应用清单包含了应用的入口、内容安全策略、共享依赖等基本信息,它们会被企业的应用集成系统读取或者被可视化编辑器读取。 应用清单采用 JSON 描述以便让其他语言可以读取从而进行集成。 包导出清单
在大多数前端工程中使用了可预测的长缓存来优化网站,要正确的找到文件名被 HASH 的构建后的文件通常需要借助构建工具输出的 在已知的导出产物清单格式中,大多数是按照“基于原始文件名到 HASH 文件名的映射”而设计的,例如: {
"src/index.js": "index.1234567890.js",
"src/joker.js": "joker.0987654321.js"
} 这引发了一个潜在的问题:集成工具想去引入一个包的导出产物的时候,它必须知道原始的文件名是什么(例如 模块映射 的发展使得我们有机会在浏览器中更好的使用 ES module——通过它来管理应用或者公共库的更新。现在,我们只需要将构建产物清单靠近Nodejs Package Exports 规范,就能发展通用的网站应用集成工具,这也是 #9 的目标。
模块映射基于 import maps 标准,通过浏览器来管理模块,所有的前端集成工具相关工具都基于支持模块映射展开设计。 <script type="importmap">
{
"imports": {
"vue": "https://cdn.jsdelivr.net/npm/vue@3.2.22/dist/vue.runtime.esm-browser.prod.js",
"@web-widget/container": "https://cdn.jsdelivr.net/npm/@web-widget/container/dist/esm/main.js",
"@org/app": "https://cdn.jsdelivr.net/npm/@org/app/dist/esm/main.js"
}
}
</script> 模块管理的颗粒度:
处理浏览器兼容问题: 现阶段要求项目同时提供 systemjs 与 es 版本,而 systemjs 用来解决浏览器兼容问题。 “低构建”编码约定ES 原生模块的发展使得开发阶段构建成为非必须步骤,例如 @web/dev-server 与 Vite 等工具就是如此。它们和 Webpack 等工具不同,它们开发过程中并不依赖构建(除非有特殊模块),我们在这份文档中以“低构建”概念来称呼它们。“低构建”是一种编码约定,结合工程清单,我们可以通过适配器在项目中立即接入到这样先进的开发工具。 “低构建”是一种构建工具建立在浏览器发展而产生模式上的创新,它们都处于早期阶段,还有机会做到更高层次的抽象: 当浏览器可以识别 JS 模块语法,浏览器就可以正确发出 HTTP 请求,这样有机会通过「服务器」来处理代码,而不再依赖缓慢且复杂的本地构建——这就是开发阶段“低构建”编码约定要素,一切从浏览器与服务开始。具体的特征:
“低构建”的编码约定本质上是在开发服务器、打包工具、浏览器之间取得一种平衡,这种平衡使得我们有机会在不同的维度来处理源代码,最终走向“无构建”:
如果未来有这样的工具,我们可以通过适配器引入它们,如果没有那么 Growing Web 组织可能会来创造它。
开发工具开发服务器与打包工具
专注于生产阶段的打包工具将根据工程清单文件以及“低构建”编码约定而工作,项目无需再配置复杂的针对构建过程的配置文件、插件等。而特殊的的源代码可以通过如下三种方法来自定义构建:
这些自定义的配置将以 NPM 包的形式托管,由开发服务器与打包工具加载,而不是留在本地,避免变成无人关注的碎片。 构建任务管理器ci-task-runner 能够在大型仓库中按需构建、通过多进程并行构建,如今我们有了更好的选择:它们不仅仅能做到 ci-task-runner 的事情,还能管理多包的依赖,例如: 新一代的构建任务管理器与 Growing Web 的开发工具组合,我们有机会彻底的改变大型项目构建效率慢的问题。
应用容器应用容器负责运行应用,它包含三个职责: 运行容器提供抽象容器抽象让应用工作在不同环境中。它提供技术手段管理应用的视图以及权限,包括运用 Shadow DOM、Server Worker、WebSandbox、SSR 等技术手段,使得应用可以工作在路由驱动、局部模块、可视化编辑环境中。 用户体验优化策略例如管理应用加载的时机、Shadow DOM SSR 序列化、构建阶段预渲染内容载入等策略。 扩展能力
应用集成这部分环节将负责版本管理(模块映射)、路由、内容安全策略等众多集成的工作,它由众多的工具组成,通常也和企业的内部其他基础系统保持紧密的联系。 构建集成工具通过构建工具直接生成包含 import maps 的 HTML 入口文件。 服务器集成工具提供专用于 import maps 的注册服务器,提供更加灵活的管理。 技术栈中立的路由系统当前大多数项目的路由的实现会与具体的 Web 框架绑在一起,当应用规模变得庞大后,这样的设计将会增加技术升级的难度,也让不同技术栈与版本的应用集成变得困难。技术栈中立的路由系统将只关注最本质的东西,这样应用在需要的时候可以从局部开始升级技术栈,而不影响其他模块。
技术栈中立的服务器渲染工具
常见问题
这确实是一个大挑战,目前的节奏:
不需要,你可以继续使用 webpack 等构建工具。Growing Web 的构建工具是为了更好的实现“低构建”甚至“无构建”的开发体验目标,非必需项。如果你使用其他构建工具,你只要确保构建产物符合相关技术标准即即可。
“微前端”是一种解决问题的手段,以至于大部分的实践将“微前端”当作目标,而 Growing Web 不是为了“微前端”,它正在努力建设的技术标准与工具都是为了企业基础设施与业务「可生长」目标,在这样的目标下有很多模糊的问题等待被结构化。
Web Widget 和 Web Sandbox 比 Growing Web 成立更早,现在它们已经属于 Growing Web 的一部分,我们将会从整体的角度发展它们。 参考
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
觉得可以包含测试工具:
一些风险:
参考链接: |
Beta Was this translation helpful? Give feedback.
-
经过线下讨论,「Growing Web 架构中的开发工具是否有必要包含测试工具?」问题结论: Growing Web 架构与基于现代浏览器的测试工具没有冲突,并且能够自然的整合。因此当前我们的精力依然围绕在当前 RFC 的关键环节上,此问题延至后续再讨论。 |
Beta Was this translation helpful? Give feedback.
经过线下讨论,「Growing Web 架构中的开发工具是否有必要包含测试工具?」问题结论:
Growing Web 架构与基于现代浏览器的测试工具没有冲突,并且能够自然的整合。因此当前我们的精力依然围绕在当前 RFC 的关键环节上,此问题延至后续再讨论。