做暧暧小视频网站,南京网页设计培训机构,wordpress 页面内容,5000元做百度推广效果怎么样前言#xff1a;希望像做游戏一样做 Web 开发的 dexteryy 同学今天在 GMTC 技术大会上又搞了一场「跨年演讲」#xff08;内容超多的意思#xff09;#xff0c;不但现场爆满、超时严重#xff0c;而且一如既往的讲完之后只要把讲稿和幻灯片拼起来就能发出来#xff0c;大… 前言希望像做游戏一样做 Web 开发的 dexteryy 同学今天在 GMTC 技术大会上又搞了一场「跨年演讲」内容超多的意思不但现场爆满、超时严重而且一如既往的讲完之后只要把讲稿和幻灯片拼起来就能发出来大家可按需取用。亮点为了方便大家理解dexteryy 同学为这次分享画了 90 张图工具是 Keynote其实在内部版《Modern Web Stack》里有 120 多张图…大家好我是来自字节跳动 Web Infra 部门的杨扬。在开始分享前先解释下可以看到幻灯片上的标题跟会议日程里的标题有些不一样「现代 Web 开发」这几个字加上了引号做这个修改是因为原文很容易被断句成「现代的Web 开发实践」「现代」看上去只是一个普通的形容词其实「现代 Web 开发」是作为一个整体的专有名词来代指现在全球技术社区和全行业里越来越重要的一个「大趋势」Megatrend、一场正在进行中的「范式转移」。今天这场分享的主题就是字节跳动如何把「现代 Web 开发」转化成具体的技术栈和研发工具体系在内部广泛落地和从中获益。这次分享的内容可以分成三个部分。第一部分先整体回顾「传统 Web 开发」范式中的「前端开发」技术和工程体系有哪些瓶颈问题。第二部分对于在这些问题的背后、在这些问题的驱动下正在发生的转变做一下归纳和比较。第三部分介绍字节跳动在落地和推动这种转变中发展和建设出的技术体系。对于字节这个「App 工厂」来说这种发展相当于一场「引擎升级」的过程。大家都知道字节跳动在业界有一个既含贬义也含褒义的外号叫作「App 工厂」如果我们从软件研发的角度来看待这个外号那其实在字节内部各种产品、工具、软件应用的开发比大家从外部看到的更像「App 工厂」无论数量还是多样性形态和场景的丰富度都是非常高、海量的。而这些软件项目中基于 Web 技术、前端技术的占了大部分这并不是因为字节有特殊的技术选型而是行业的大背景和必然规律我在19年一次关于「现代 Web 开发」的分享里有介绍过。由于字节有这种特点所以前端技术和工程体系中的问题和瓶颈在字节会体现的很全面、很典型很多时候也会体现的更明显。* 现代 Web 开发的现状与未来https://zhuanlan.zhihu.com/p/88616149传统的前端技术体系无论在字节内部还是在全行业都可以总结为图上这个样子。图中从下到上代表抽象层从底层到顶层。最右边三个方块都从最下面延伸到了最上面代表它们都是端到端的解决方案跟左边的体系以及彼此之间都是割裂的包含大量重复这次分享因为时间关系不讲这几个部分。蓝色的方块都是代码层面的绿色的方块都是平台层面的。这套体系是字节曾经的主流是从业务中自然发展出来的但随着这种发展趋于停滞这套技术栈正在同样自然的演变成历史遗留的「祖传技术栈」其中每个部分都有比较大的瓶颈问题。我们逐个看一下图里的每个问题域首先是大家最熟悉的「前端脚手架」。不管哪种形式的脚手架本质都是复制粘贴一堆样板代码组成新的项目。虽然跟建筑行业使用的脚手架一样都是在搭建过程中使用用完就放到一边只留下搭完的项目。但建筑脚手架拆掉之后留下的建筑有一套不能动的钢筋混凝土骨架而脚手架生成的前端项目是混杂在一起的样板代码虽然有文件结构但可以随意修改而且因为基建和示例代码混在一起所以不仅是「可以改」而且经常是「必须改」样板文件的内容和结构才能完成真实项目的完整搭建。假设一个脚手架包含 A、B、C 三块功能用这个脚手架创建出的三个项目最初都是一样的也都包含 A、B、C 功能。接下来三个项目必然需要在脚手架的生成结果上做各种增删改可能是因为业务需求也可能是因为技术沉淀和工程改进。时间长了之后三个项目之间会差别非常大如果要做统一的改进或者把一个项目的沉淀和改进应用到另一个项目里都会很困难。有时甚至要推迟需求开发先对这些项目做一轮统一的重构但这也只能应付眼下之后这些项目仍然会继续分裂和腐化。另一方面脚手架本身也在迭代改进但因为脚手架是一次性的一用即抛这些改进不能对原先创建的项目带来好处引入这些改进的成本跟从其他项目里引入改进的成本差不多。进一步看看脚手架中「项目模板」的问题。脚手架的必然结果是需要各种项目模板。不但脚手架建设者需要提供多种模板覆盖不同的需求使用者也经常需要复制原有模板修改成新的模板比如产品的技术形态是 SPA 还是 MPA都会产生不同的模板。图上每个方块都代表一个真实存在的模板可以看到这些模板中有大量重复、又不会完全相同的内容升级维护模板、在模板之间同步技术沉淀都有成本。很多模板会缺少更新长期停滞把成本留给搭建项目的人。如果从项目场景的角度出发来设计和维护模板也有相同的问题。图中的方块是一些最基础、最典型的场景和场景中的技术需求可以看到不同场景之间的技术需求重合度很高。除了场景类型一个项目还有很多类型维度图中的每个方块代表一种维度比如按照图上的第三种维度不同项目之间仅仅因为「组件库」和「设计系统」不同就要设计和建设不同的模板。这些维度之间的排列组合要么会导致模板进一步分裂和数量爆炸每种模板的维护成本更高应用场景更小ROI 因此变低更加倾向于停滞要么会导致模板对很多维度中的需求不做考虑只覆盖小部分需求对项目开发的支持局限在比较低的水平。「传统技术栈」的第三个问题域来自前端工程化建设中常见的对 Webpack 的「包装」。为了避免每个前端开发者都成为「Webpack 工程师」 很多脚手架、工程化建设都会对 Webpack 做图上这样的包装在最上层提供围绕编译构建的两个命令 dev 和 build搞出不同「规范」的配置文件和插件机制。这种包装的第一个问题是抽象程度很有限配置 API 的设计也五花八门体现不同的个人偏好和业务经验这种配置虽然被称作「规范」但在真实业务项目中存在感不高业务项目还是要直接靠 Webpack 来解决很多问题项目中包含很多 webpack 配置脚手架模板也包含大量相关的样板代码避免不了前面说的问题。图中这段话来自 Redux 作者 Dan 写的一篇文章讲 JS 工具的配置 API 的设计这段话就是在讲这方面的抽象和设计能带来巨大的影响有很高的门槛需要非常严肃专业的对待这种工作也需要高度的集中而不是交给「Webpack 工程师」们搞各种各样的「规范」。* The melting pot of JavaScript: https://increment.com/development/the-melting-pot-of-javascript/业务项目深度依赖 Webpack、包含很多 Webpack 配置还带来另一个问题JS 开发工具从去年开始又出现新一轮更新换代的征兆有人把这种趋势称作 「JS 的第三纪元」新范式的项目涌现开始进入到日常业务的开发实践很多场景下已经没有 Webpack。* The Third Age of JavaScript: https://www.swyx.io/writing/js-third-age图中右侧的 esbuild 和 swc 这样的构建工具把编译、构建、打包、压缩等在 Webpack 里属于不同环节的部分合并在一起加上非 JS 的系统编程语言的帮助大幅提升构建速度。另一方面也能支持 ESM 优先的、不需要打包的构建场景。Snowpack、Vite 这样的工具在此基础上实现了开发者体验DX优先的、不打包Unbundled的开发调试模式。这些工具和模式跟 Webpack 的设计有一些本质矛盾目前已经被用于公共库的构建、业务项目的开发调试等真实场景里。基于 Webpack 包装的工程化建设第三个问题是对项目开发的工程支持只停留在比较低的水平比如就像 dev 和 build 命令一样局限于跟编译构建有关的环节。而随着行业和业务的发展随着前端技术的发展一个前端工程的完整需求就像图中一样会包含蓝色方块代表的整个研发链路的每个环节以及每个环节下面绿色方块代表的工程需求。这些都超出了 Webpack 的能力范围。刚才说的这个问题其实也是传统前端工程化建设本身的问题。传统的工程化建设就像图中文字说的只能实现「代码层面」的基础建设在创建项目的时候做的事情大部分都属于「代码初始化」。现代的 web 工程和前端工程越来越多的包含「代码层面」之外的「平台层面」。图中绿色方块代表的是靠「代码层面」来实现工程需求橙色方块代表的是要靠「平台层面」才能更好实现的需求。第五个问题域是很多前端开发场景比如像字节内部的前端开发都在统一收敛到 React 技术栈但 React 本身也是有局限的。在 Web Infra 部门建立之前字节内部的业务方向比如今日头条和抖音就已经在推进统一到 React 技术栈目前字节的现代 Web 研发体系建设也有意收敛和围绕着 React 来进行。选择 React 的原因可以归纳为图上这四个其中符合技术趋势设计演进更快走在最前面这两点让 React 在基础建设中在有基础建设团队支持的业务场景中都具备很大的优势。图上高亮的这句话很好的表达了 React 引领业界和社区发展的特点。刚才在选择 React 的原因里还提到 React 庞大的生态红利或验证规模。图中可以看到在比较贴近实际使用情况的依赖下载数据里React 在绝对数量遥遥领先的情况下增长势头也是更快的React 生态下的 CRA、Next.js单独拿出来都达到或接近其他非 React 技术的使用量。* https://www.npmtrends.com/babel/preset-react-vs-vue/cli-shared-utils-vs-next-vs-nuxt-vs-react-vs-react-scripts-vs-vue-vs-vue-loader-vs-vite这种生态和规模上的差距在国内环境中也回避不了国内 JS 开发者的数量差不多是全球的十分之一所以单靠国内开发者影响不了整个行业和技术社区的生态和基建导致在业务支持和工程建设中React 目前都无法取代。* 「全球的 JS 开发者已经上千万了」https://zhuanlan.zhihu.com/p/111204309但在工程体系中只靠 React 自己是远远不够的React 本身只解决视图层的问题距离一个 Web 框架还缺很多东西在框架层面上React 是无偏见的比如没有限制路由实现、组件类型、SSR 解决方案等也没提供默认的配置和工具体系跟一个真正框架的必备要素是完全相反的。* Advancing the web framework ecosystem (Chrome Dev Summit 2019): https://youtu.be/QDljY2I1Pfw由于 Webpack、React 都不解决全链路的问题缺乏框架级别的解决方案很多前端项目会把目光转向发展时间更长、已经形成框架级别基建的服务器端框架领域但这方面的 Node.js 框架也有瓶颈问题。业界主流的 Node.js 框架 NestJS 的作者在文档首页的设计理念部分就指出 React、Vue、各种开发工具都没有解决「应用架构」的问题而 NestJS 就是要提供开箱即用的应用架构。传统的前端开发局限于视图层跟完整的软件开发、产品开发相比最缺的就是「应用架构」。* NestJS Philosophy: https://docs.nestjs.com/#philosophy但是 Node.js 框架能提供的只是「服务器端应用架构」是以服务器端开发为中心的。有些情况下比如活动页面客户端部分本来就很薄谈不上「客户端应用架构」但这种情况下的业务关注点仍然在客户端部分如果基于有完整服务器端应用架构的 Node.js 框架去开发这种项目对前端开发者来说有些偏离重点。在另一些情况下客户端部分比较厚这种情况下需要的「客户端应用架构」就像图中右边的蓝色部分跟左边代表「服务器端应用架构」的橙色部分是完全不同的如果使用 Node.js 框架蓝色部分仍然需要自己摸索和搭建。不管什么软件架构核心都是「分层」和「关注点分离」完善的现代 Web 工程里「服务器端应用架构」和「客户端应用架构」不会割裂而是混为一体的。* The Clean Architecture: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html除了架构Node.js 框架也解决不了前面说的其他问题同时还引入了图中右边的新问题业务逻辑既分散割裂同时又重复导致项目变得「低内聚高耦合」。在「前后端分离」之后从「后端项目」里独立出来的「前端项目」使用 Node.js 框架之后又混入了很重的后端业务逻辑和研发需求。而 Node.js 框架随着发展本质也越来越清楚还是服务于专业服务器端开发的降低不了前端开发者的服务器端开发门槛这是一个最大的瓶颈。从这张图可以看到包含服务器端部分的「前端项目」并不是真正的「全栈」只是包含了服务器端最上面的、很薄的一层解决 Web 和 BFF 需求注意这里说的 Web 是指处理 HTML 请求而 BFF 这个词在国内有很多误用实际上是专指面向特定 UI 的 API 服务对于前端项目里的这些服务器端需求用 Node.js 框架来开发很多时候带来的问题比解决的问题更多。* The BFF Pattern (Backend for Frontend): An Introduction: https://blog.bitsrc.io/bff-pattern-backend-for-frontend-an-introduction-e4fa965128bf最后看下最底层的 IaaS 和 PaaS 部分。传统云计算中的 IaaS 和 PaaS就像图中的绿色部分从最底层到最上层有这样几层最上面这层有不同的平台和服务形态传统上前端项目跟后端项目一样直接部署这一层上比如字节内部后端技术栈的项目都部署在被称作 TCE 的 PaaS 上而前端技术栈的项目以前也只能这样部署。* 《容器云在头条的落地和实践》https://time.geekbang.org/dailylesson/detail/100016772但是在这种 PaaS 上或直接在 IaaS 上做部署和运维对前端开发者来说不但复杂低效而且在很多前端部署需求上没有获得任何支持。比如图中粉色部分中这些前端部署方面的通用需求。由于 IaaS 和 PaaS 都源自后端开发场景是后端研发技术的平台化沉淀设计和演进都天然的受到局限对前端研发场景缺乏理解就算理解也无法在相同的基础设施里去兼顾这些前端部署需求。也就是说多数前端项目和底层的 IaaS 和 PaaS 之间存在一大片空白也就是图中粉色的区域。在真实业务中为了避免每个前端项目都直接跟 IaaS 和 PaaS 打交道很多业务都会有意无意的做一些集中建设填补这片空白。比如字节的一些 web app 项目会由后端负责的 go server 来运行。很多有 SSR 需求的业务会搞一个统一的 SSR server 项目在开发各种前端仓库的时候需要本地有 SSR server 的仓库才能运行和调试这些前端项目。像这样的集中建设要么把前端项目中的正常组成部分放到了前端开发者无法掌控的地方要么反复重复的建设出被业务需求扭曲的部署方案难以沉淀和演进最大化的提效。所以图中粉色这片区域的空缺该由什么来填补是传统前端技术栈里的一个大问题。回顾了「祖传技术栈」的这些问题接下来我们看下在这些问题的驱动下业界和技术社区里已经形成的趋势这些趋势带来的发展和优势也反过来让前面说的这些问题变得更明显更急需解决。这种趋势可以归纳为「传统 Web 开发」范式到「现代 Web 开发」范式的转变。我在图中这两次技术活动上分别介绍过「现代 Web 开发」范式的起源、背景和发展状态这里不再重复了。* 现代 Web 开发的现状与未来JSDC 2019 演讲全文: https://zhuanlan.zhihu.com/p/88616149* 理解现代 Web 开发JSConf China 2017https://youtu.be/515pkXWHgnEhttps://2017.jsconfchina.com/files/02-modern-web-dev-dexteryy.pdf这种转变可以称得上是一场「范式转移」原有的理解和习以为常的假设被打破在原有的东西上小修小补解决不了问题需要建一套新的东西做出根本性的变化。图中左边蓝色部分是最能代表「传统 Web 开发」的一些技术栈和规范右边橙色部分是在「现代 Web 开发」趋势下出现的技术栈和技术形态接下来把它们展开看看包含哪些要素就会看到左边的东西跟右边的东西差别非常大。* 「范式转移」https://wiki.mbalib.com/wiki/%E8%8C%83%E5%BC%8F%E8%BD%AC%E6%8D%A2Ruby on Rails 是「传统 Web 开发」范式的一个典型代表 本质上是以服务器端开发为中心的、MVC 架构的「服务器端 Web 框架」就像图上右边这样产出网页和 API。网页部分需要的前端代码和工程化一般包含在同一个仓库里框架本身也会内置一些前端相关的工程化经常会需要被专业全面的前端工程化替代掉。* The Asset Pipeline: https://guides.rubyonrails.org/asset_pipeline.html* Hotwire: https://github.com/hotwired/hotwire-rails「十二要素应用宣言」本质上是一种工程标准是进入云计算时代之后服务器端应用和工程项目中形成的规范这套标准可以保证应用能很好的运行在「后端 PaaS」或其他的传统云计算平台上。 可以看到在 Node.js 帮助下形成的前端工程规范不管有没有服务器端代码也都受到了这个规范很大影响。* The Twelve-Factors App: https://12factor.net/MERN 技术栈是前端代码和工程从其他技术栈的服务器端框架中「分离」出来之后又融合相同技术栈的服务器端框架形成的「全栈」开发方案。组成 MERN 的 4 个首字母能体现这套技术栈的本质也就是图上右边的 4 个组成要素整体上还是以服务器端的研发方式、应用架构、平台基建为中心的。* MERN Stack: https://www.mongodb.com/mern-stack在「现代 Web 开发」趋势下在国外被称作「JAMstack」的技术栈变得越来越清晰和主流。它还有另一种命名建议是图中第二行的「SHAMstack」。这两个缩写的首字母组合虽然不同但就像图中的推导结果本质是一样的都是由 4 个要素组成。* JAMstack: https://jamstack.org/* SHAMstack: https://css-tricks.com/jamstack-more-like-shamstack/* Content Mesh: https://www.gatsbyjs.com/blog/2018-10-04-journey-to-the-content-mesh/再展开看这 4 个要素。跟刚才说的 MERN 技术栈比较Serverless 模式和基建取代了 M 代表的传统后端基建前端应用的构建产物 、 服务器端渲染、静态网站生成、前端程序中的 BFF、等等取代了 E 代表的服务器端 Web 框架和服务器端代码。这种技术栈的项目仍然是「全栈」的 Web 项目但变成以客户端研发方式、客户端应用架构为中心看上去很像是纯静态的、纯前端的项目。* ooooops I guess we’re* full-stack developers now: https://css-tricks.com/ooooops-i-guess-were-full-stack-developers-now/还有人归纳了这种叫「STAR」的技术栈本质上是图中右边这4个要素组成。同一个现代 Web 项目可以同时符合 JAMstack 和 STARJAMstack 强调的是前后端架构和开发范式STAR 强调的是专业的编程方式。特别要注意的是STAR 其实体现了一个现代 Web 项目中的「前端工程化」除了编译环节也需要 Runtime 环节和代码编写环节的支持除了视图层也需要完整的应用架构和 Model 层的支持。* STAR Apps: A New Generation of Front-End Tooling for Development Workflow: https://css-tricks.com/star-apps-a-new-generation-of-front-end-tooling-for-development-workflows/在「现代 Web 开发」趋势下国外技术社区里越来越多的提到 meta-framework本质上是把 JAMstack 和 STAR 强调的部分加起来用以客户端为中心的、包含更上层抽象的、通用的 Web 框架的形式整体系统的满足这些需求抽象、简化这里面的各种模式。在「现代 Web 开发」里这种 meta-framework 是更合适的基础抽象层取代了以脚手架和构建工具为代表的更原始的基础。「S 型曲线」是一种事物「发展成长规律」的表示方法这张 JS 框架的 S 型曲线图很好的表达了 meta-framework 在 JS 技术发展中的意义。在图中左侧的早期阶段各种 UI 框架在行业和技术社区里不断涌现包含各种各样的尝试和破坏性创新随着发展UI 框架不再是快速发展的前沿了选择也不再那么多技术发展逐渐稳定和收敛成了基于 React 做上层的整合和框架建设这种框架变成了新的发展前沿也产生了大量选择同时作为更成熟的技术以更快的速度被采纳使用之后又逐渐稳定和收敛形成主流技术。* React Distros and The Deployment Age of JavaScript Frameworks: https://www.swyx.io/react-distros/比较了「传统 Web 开发」和「现代 Web 开发」中的不同现象最后我们来归纳和定义一下这两种范式的本质特征和组成要素。从框架和 UI 的角度来看「传统 Web 开发」是以服务器端框架为中心来做全栈开发客户端是围绕 HTML 和对象树的编程范式。「现代 Web 开发」是以新一代客户端框架为中心来做全栈开发客户端同样围绕专业、通用的软件开发语言和编程范式。从架构的角度来看「传统 Web 开发」中存在两套比较独立和欠缺融合的程序「前后端分离」改善了分工协作但对于分离出来的「前端技术栈的 Web 项目」在架构和开发范式上没有真正实现「分离」前端开发者需要跟服务器代码打交道。「现代 Web 开发」实现了在同一套程序里一体化开发在开发、调试、运行、部署等环节都能做到「无服务器化」让前端技术栈的开发者更容易成为真正的「产品开发者」。从抽象的角度来看「传统 Web 开发」中前端部分的基础抽象是原始、初级的比如脚手架、样板代码、基本的 Webpack 包装和 CLI 工具、React 和 JS 生态中的海量选择很有「前端特色」跟成熟的软件开发有显著差距。图中的 DX 是指开发者自身的效率UX 是指开发出的应用的能力和质量传统范式中的抽象太原始导致 DX 和 UX 没法同时提升提升其中一个就会损害另一个。「现代 Web 开发」中有了一体化的、更成熟的、框架级别的基础抽象能同时追求和确保 DX 和 UX 的最大化。* What Is DX? (Developer Experience): https://medium.com/swlh/what-is-dx-developer-experience-401a0e44a9d9* What is developer experience?: https://www.tiny.cloud/blog/developer-experience/从部署的角度来看「传统 Web 开发」的项目要么纯静态托管要么作为服务器端应用来部署和运维。不同部署方式会导致整个工程都不同需要不同的脚手架模板。「现代 Web 开发」的项目有更多样强大的运行和部署方式但在 meta-framework 的支持下项目模板的变化变少了申请有机会完全融合、收敛成一个模板成为「Universal App」。* SPR: https://vercel.com/blog/serverless-pre-rendering* SSG: https://www.freecodecamp.org/news/static-site-generation-with-nextjs/* ISG: https://www.smashingmagazine.com/2021/04/incremental-static-regeneration-nextjs/* Micro Frontend: https://micro-frontends.org/最后从平台角度来看「传统 Web 开发」基于后端的云基础设施由于代码层面缺乏抽象客户端代码的复杂性容易停留在很基础的程度有些时候会干脆直接改成 JSON 之类的配置。「现代 Web 开发」基于新一代 Serverless 平台。在 Serverless 的支持下能实现以前难以实用化的云研发。由于代码层面有统一的、上层的抽象在开发中能引入更多低代码模式。针对这些问题和趋势背景字节在起步比较晚的 Web Infra 建设中主动发展和建设了整套「现代 Web 技术栈」的研发体系建立了「MWA」 —— 也就是「现代 Web 应用」—— 这种工程标准形成了新一代「研发引擎」支持了大量、多样的真实业务项目。之前第一部分里我们讲了前端的「传统技术栈」是图上这样子。可以看到「现代 Web 技术栈」的这张图发生了非常大的变化所以说这种转变是一场「范式转移」。有几个需要注意的变化是图中绿色代表的平台化基建占比超过蓝色代表的纯代码层面的基建。没有割裂中间的研发平台建立在「前端云」之上工程框架基于研发平台支持研发全链路右边的工程方案跨越上中下三层是指可以通过工程方案定制左边这三层的需求。这套技术栈在字节内部是一套被称作「Goofy」的研发体系可以看到图中有多个名字里 Goofy 开头的产品既可以整体使用获得更多高级能力也可以单独使用其中最早推出、应用最广泛的就是最下层的「前端部署平台」提供了 Serverless 的「前端云」模式明天下午有一场分享是专门介绍这个部分的。这次分享以图中蓝色部分代表的代码层为主这个部分的解决方案形成了一套被称作 Jupiter 的研发框架。先通过视频演示直观的看一下。屏幕上的这个应用是 Goofy 前端研发工作台的 SaaS 版。先在团队里创建一个工程项目。默认会推荐用这套基于 Jupiter 框架的、标准化的工程方案体系这里选择了 符合前面提到的 MWA 工程标准的「MWA 工程方案」。后面会介绍这个工程方案非常强大能力很多但创建过程中需要做的配置很少这里我们什么都不需要改就可以继续创建。可以看到除了初始化代码也会一站式的完成各种底层平台的初始化和配置。刚创建出来的项目已经是一个完备的工程可以马上执行一次上线发布。可以看到发布成功了点击自动生成的域名可以看到 Jupiter 框架的初始运行效果。接下来看看开发环节。在一个开发任务里进入「代码」面板可以看到项目代码的可视化展示和低码编辑界面这个界面显示之前会先初始化任务专用的 Web IDE 研发环境。接下来直接进入 Web IDE。可以看到一个 MWA 工程的代码是极简、轻量的只要在 src 下默认导出一个 React 组件就能得到完善的 web 应用项目默认是零配置的看不到 webpack.config.js 之类的工程配置和样板代码。接下来直接执行 dev esm 命令可以看到瞬间就启动了调试命令几乎没有编译耗时就生成了开发环境的访问地址。接下来快速做一段前后端一体化的开发可以看到我们在 api 目录下准备了一个 BFF 函数文件。可以在 web app 代码中直接导入这个函数文件像普通函数一样调用。可以看到输入代码的过程中我完全不关心代码风格问题保存的时候会自动生成规范的、符合最佳实践的代码。这里我写错了 API会自动提示错误。这个 useLoader 是 Jupiter 框架的运行时 API能支持一体化的 SSR。查看刚才打开的调试页面可以看到修改的效果这段文本实际上是通过 BFF API 获取到的这个视频忘记录相关的演示。接下来回到工作台的低码编辑界面可以看到 MWA 工程的配置状态。把服务器端渲染功能开启。回到 Web IDE可以看到 package.json 里已经自动增加了相关的配置。打开调试页面从 HTML 文件可以看到整个 UI包括通过 BFF API 获取到的内容都已经在提前渲染好了。可以看到这个 MWA 工程的代码虽然极简但能力已经比很多代码复杂的传统前端工程都要更强。刚才演示中的工程项目在传统前端开发里是一个模糊、虚的概念不止包含代码还包括研发环境和各种平台上对应的注册和配置。在字节前端研发体系里「工程」被实体化了在研发平台上「工程」是「看得见摸得着」的对象可以创建和管理在里面做所有研发相关工作每个工程都包含全链路每个环节和一体化的工作流。「工程」可以通过「工程方案」来一键创建「工程方案」相当于「工程」的「模板」取代了传统前端开发中的脚手架而「工程方案」都有一个「工程类型」这种类型相当于「模板的标准」。建立和维护工程标准推进围绕这些标准的基建和技术生态是 Web Infra 部门的工作重点之一。目前的建设已经基本完成了「工程类型」的收敛形成了少量的、数量固定的「默认工程类型」能支持体系中各平台的更多功能。Jupiter 框架实现了这些「工程类型」在代码层面的要求。每种「工程类型」除了直接提供「默认工程方案」也支持开发者创建属于这种类型的、自己的「业务工程方案」能跟标准保持兼容和同步。以 MWA 为例这是默认工程类型中唯一的 Web 项目类型满足所有 Web 项目的开发需求传统前端开发中的各种 Web 项目的模板都被收敛成同一个「模板」。MWA 之所以能承担唯一 Web 项目类型的责任是因为有 MWA 框架的支持MWA 框架不但是前面说过的 meta-framework而且在 JAMstack 技术栈的基础上继续发展把微前端、传统 Web 开发范式中的 Node.js Web 框架、等等抽象融合到了一起。这种融合不但不是简单的叠加导致工程变得大而全、更重。反而通过抽象变得更轻量更简单所以是 111另一方面因为能一体化的考虑多种需求能交付原本单个项目类型不好实现的功能所以也是 112。目前收敛得到的默认工程类型有图上这些每种类型都覆盖一个在研发方式和工程需求上有本质差别的场景领域解决这个场景下的工程标准问题。虽然工程类型要收敛但业务工程方案的数量不做任何限制比如图中是字节GIP 部门做的叫作 GHome 的内部研发门户其中包含大量子平台这些子平台之间有共通的业务逻辑和额外的工程要求。在这种情况下可以基于 MWA 标准定制出 GHome 子平台工程方案。图上右边还列举了其他一些业务工程方案。进一步介绍下 Jupiter 和 MWA 框架。一个最简单的 MWA 项目可以只包含图上左边这样的两个文件这样的MWA 已经有完善的工程能力能马上做产品级的部署。图上右边列出了一部分能力。我们接下来对这个项目做些小调整就能实现传统上需要很多配置和样板代码或是需要不同脚手架才能实现的效果。这个项目当前是图中左上角这样的「单入口」模式改成左下角这样的「多入口」结构就自动变成了 MPA自动得到了服务器端路由和多个 HTML。如果像右上角这样把 landing-page 的 App.tsx 入口组件换成 pages 目录就可以启用约定式路由功能基于文件路径自动得到客户端路由。如果像右下角这样增加 index.ts 和 head.html可以启用高级的自定义能力定制或掌控原本由框架自动处理的环节。之前的演示里我们通过低码界面启用了 SSR 功能其实也可以在代码里增加 Jupiter 配置文件用代码来控制配置。一个 MWA 项目自带产品级的 web server称作 Jupiter Server项目自己就可以运行自己。第一方 Serverless 平台使用相同的 web server但还能基于 MWA 标准来理解项目的代码自动生成更复杂的多进程的集群化的系统。比如 SSR 部分会独立部署业务开发者写出来的 app 代码容易在 SSR 中出现异常报错或内存泄露这时前面的 web server 会让应用自动降级变成兜底的纯 CSR 模式保证用户请求不会出错不会超时。要实现这种自动兜底不但平台和框架的协同也需要 MWA 提供的一体化 SSR 开发方式用同一套 app 代码开发前后端业务逻辑让业务逻辑始终支持 CSR否则兜底就无效了。MWA 支持用一体化的方式开发同一套 app 代码在图上这三个环节中以不同模式运行也支持根据业务需求让 app 代码中的不同部分在不同环节以不同模式运行。这种收敛后的开发方式符合业界的一个发展趋势就是让代码的运行尽可能「前置」优先在编译时运行剩余的才在服务器端 SSR 环节运行最后剩下的才在浏览器里运行。比如可以像图上左边这样app 整体做 SSR 或 SSG把局部留到 CSR。也可以像图上中间这样反过来整体默认 CSR允许对局部做 SSR 和 SSG。还可以进一步实现右边这样更复杂的效果。要实现前面说的 11 1除了合适的抽象MWA 框架也通过插件和微生成器等方式把核心功能拆分出来可以按需启用。可以像图上这样运行 new 命令选择启用这两个功能微生成器会自动重构项目代码增加必要的依赖和配置。也可以在工作台的界面上查看项目可选功能的开关状态做修改调整。之前的演示里我们提前开启过 Unbundled 开发模式功能可以用 dev esm 命令取代默认的 dev 命令耗时可以从几秒减少到1秒不到。* What is Unbundled Development: https://medium.com/habilelabs/snowpack-what-is-unbundled-development-8562205d0539这么快的编译速度是因为背后已经完全没有 webpack也不做任何打包只用 esbuild 编译 ESM 模块用自研的类似 Snowpack 和 Vite 的方案运行项目也会自动从 Goofy PDN 平台上加载预编译的依赖包进一步优化性能。之前的演示里还开启了一体化 BFF 功能可以在项目里写「BFF 函数」文件这种函数文件可以实现任意的 REST API同时自动生成一体化风格的客户端 SDK通过 SDK 调用就像调用普通文件里的函数。用这种一体化 API 调用 BFF不但更直观、安全也因为多了框架的抽象框架可以自动做更多事情比如在 SSR 中运行的时候自动把 BFF 请求切换成内网方式。Serverless 平台也会自动对 BFF 做优化做独立部署BFF 和 Web 之间不会互相干扰。MWA 实现了图上这种「三位一体」应用图上右边三种开发方式之间可以无缝切换。比如可以从现代 Web 开发范式切换成传统的 Node.js Web 应用。也可以把 MWA 项目中的 BFF 拆分成独立的纯 API 服务项目。一个纯 API 服务也可以随时切换成包含 web 的 MWA 项目。这种能力有利于业务项目从传统 Web 开发范式向现代 Web 开发范式的转换。前面说的这种「三位一体」实际上是 MWA 最重要的「Universal App」功能的一部分。「Universal JS」是指同一份 JS 代码既支持在浏览器端运行也支持在服务器端运行。而「Universal App」是进一步发展让同一份 app 代码可以用图上中间这一排的方框代表的任意方式来运行也支持同时部署多个不同运行方式的版本。比如一个静态网站切换成 SSR或启用 SPR 的时候不需要调研技术选型和考量成本收益几乎什么都不用改。也可以随时退回原来的方式。比如为中后台项目同时提供 SaaS 版、桌面安装版和私有化部署版。比如让微前端子应用既能在主应用里访问也能独立访问。前面提到过 Node.js Web 框架只能提供「服务器端应用架构」MWA 提供开箱即用的、符合现代 Web 开发范式、以客户端应用为中心、前后端一体化的应用架构类似图上这样。可以用 createModel、useModel 这样的 API轻易实现 React 开发中欠缺的 Model 层和 Controller 层。可以利用 Redux 的 FP 编程优势和生态红利同时不需要关心创建和配置 store如何组织和组装 reducer、action 等。前面说过在抽象不足的情况下前端开发中一直存在 DX 和 UX 不可兼得的问题比如如果降低了开发成本产品功能上可能会不灵活性能不够好反之把业务需求和性能做到位开发体验就会很差。MWA 框架在尽可能多的环节实现最大化的抽象类似图上这样帮助前端开发者脱离「软件开发的石器时代」获得更成熟的软件开发范式。Jupiter 和 MWA 框架在字节内部经历了半年的内测和一年的正式使用在内部已经进入推广普及阶段。这个项目也很快会开源出来帮助行业和社区里的更多项目落地「现代 Web 开发」范式。这个开源项目叫作 Modern.js目前我们已经创建了 Github 项目上线了开源内测主页和一个现代 Web 开发者问卷调查希望大家帮忙填写和转发下这个问卷调查报告之后会公开出来。由于 modernjs.dev 这个域名还没备案没办法部署在我们自己的 Serverless 平台上目前是用 Github Pages 部署似乎有被墙的问题正在解决* https://modernjs.dev/* https://github.com/modern-js-dev/modern.js* https://webinfra.org/点击上方卡片关注我、加个星标学习源码整体架构系列、年度总结、JS基础系列