大家好,很高兴地向大家宣布,Modern.js v2 版本已经正式发布了!
Modern.js 是字节跳动 Web Infra 团队开源的一套 Web 工程体系。 在开源以来的一年多时间里,Modern.js 保持稳定的迭代节奏,数十位贡献者参与了开发,累计提交 2000+ 个 Pull Request,并支持了 Rspack 构建、嵌套路由、流式渲染等新特性。
在这篇文章里,我们会和大家一起聊一聊 Modern.js 在过去一年多时间里的变化。
Modern.js v2 首页
首先介绍一下我们为什么要做 Modern.js v2 版本,主要有以下几个原因:
以上因素促使我们完成了 Modern.js v2 版本。
在 v2 版本中,我们重新明确了 Modern.js 的定位:Modern.js 是字节跳动 Web 工程体系的开源版本,它提供多个解决方案,来帮助开发者解决不同研发场景下的问题。
目前我们开源了三个解决方案,分别面向 Web 应用开发场景、npm 包开发场景和文档站开发场景:
Modern.js 解决方案
作为 Modern.js 工程体系的一部分,以上每个解决方案都可以被单独使用,并且各自部署了独立的文档站点。开发者可以按需选择其中的一个或多个解决方案来使用。
在代码层面,这三个解决方案按照统一的研发规范迭代,并复用同一套插件机制,因此,它们提供的研发体验也较为一致。大家如果对内部实现感兴趣,可以在 GitHub 上的 Modern.js 仓库 中找到它们的源代码。
Modern.js 仓库:https://github.com/web-infra-dev/modern.js
下面让我们来了解一下这三个解决方案提供的最新能力。
Modern.js 框架是一个基于 React 的渐进式 Web 开发框架。 在字节跳动内部,我们将 Modern.js 封装为上层框架,并支撑了数千个 Web 应用的研发。
由于 Modern.js 框架的使用最为广泛,在下文中,我们会省略「框架」,直接称其为 Modern.js。
在 Modern.js 落地的过程中,我们收到很多业务同学提出的诉求,包括构建性能、框架的灵活性和可扩展性、页面加载性能等方面,相信社区中的开发者也会面临相似的问题。
为了更好地满足这些诉求,Modern.js v2 提供了以下特性:
Modern.js v2 提供开箱即用的双构建工具支持,开发者可以在成熟的 Webpack 和更快的 Rspack 之间进行切换。大家对 Rspack 可能还不太了解,Rspack 是由字节跳动开源的 Web 构建工具,基于 Rust 语言开发,具有高性能、可定制、兼容 Webpack 生态等特性。
Rspack Logo
相较于 Webpack,Rspack 的构建性能有明显提升,除了 Rust 带来的语言优势,这也来自于它的并行架构和增量编译等特性。经过 benchmark 验证,Rspack 可以给 Modern.js 项目带来 5 ~ 10 倍编译性能的提升。
Rspack Benchmark 截图
Modern.js 已支持在 Rspack 模式下使用框架的 70% 功能和配置项,包括服务器端渲染(SSR),静态站点生成(SSG)、嵌套路由、CSS Modules 和 Tailwind CSS 等功能。除了功能,Modern.js 在 Rspack 模式下的配置项也与 Webpack 模式基本一致,在我们的实际验证中,一个小型项目花几分钟就可以平滑切换到 Rspack 模式。
目前,Rspack 项目以及 Modern.js 的 Rspack 模式仍在快速迭代中。在未来几个月内,我们将逐步对齐 Webpack 模式和 Rspack 模式的绝大多数功能和配置,使更多项目能从 Webpack 平滑地过渡到 Rspack。
Rspack 已于 2023.03.10 号正式开源,你也可以在非 Modern.js 的项目中直接使用 Rspack 进行构建。如果你对 Rspack 感兴趣,请阅读 「Rspack 正式发布了」来了解更多。
「Rspack 正式发布了」:https://www.rspack.dev/zh/blog/announcement.html
大家对 Modern.js 框架的第一印象可能是「一个大而全的框架」,但事实上,为了避免变得臃肿,Modern.js 采取了渐进式设计,将所有功能建立在灵活的插件系统之上,因此具备按需启用和可插拔的能力。
Modern.js 期望能支持不同规模的项目研发,考虑到中大型项目和小型项目对功能的诉求存在差异,Modern.js 的大多数功能都是按需启用的。 在创建项目时,Modern.js 默认只安装核心模块,使 npm 依赖保持轻量;当需要用到额外功能时,你可以通过 modern new 命令一键开启,并自动安装相关依赖。
modern new 命令
比如:
目前,你可以通过 modern new 命令来按需开启以下功能,未来我们也会将更多功能加入到 new 命令中,使其能够被便捷地集成。
开发者在实际项目中使用 Web 研发框架时,除了使用开箱即用的能力,也会有很强的定制化诉求。因此,Modern.js 设计了一套灵活的插件系统来满足这一点。
Modern.js 可以划分为三个核心部分: CLI 工具、服务端和运行时。其中,CLI 工具负责提供 CLI 命令和打包构建能力;服务端提供 SSR、BFF 等能力;运行时提供状态管理、路由等能力。
Modern.js 核心模块
我们为这三者分别设计了插件:
这三种插件使用统一的 Hook 模型,并提供丰富的插件 API。比如,你可以使用插件做到:
在字节跳动内部,我们借助这些插件 API,结合公司内的基建和平台,封装出内部的企业级框架。如果你需要对 Modern.js 框架进行深度定制,也可以借助这些插件 API 来完成。
如果你对 Modern.js 的插件系统感兴趣,请阅读 「Modern.js - 自定义插件」文档。
Modern.js - 自定义插件: https://modernjs.dev/guides/topic-detail/framework-plugin/introduction.html
Modern.js v2 基于 React Router v6 提供了新的路由方式 —— 嵌套路由(Nested Routes)。
如果大家了解过 Remix 或 Next.js 13,应该对嵌套路由不陌生了。嵌套路由与 Modern.js v1 提供的约定式路由相似,也是一种基于文件系统的路由。
在 Modern.js v2 中,我们约定在 src/routes 目录下的文件,在应用启动时会自动生成对应的路由结构,页面的路由与文件结构是相呼应的,并且可以为资源加载带来一些性能优化。
Modern.js 的嵌套路由包含以下功能:
在 Modern.js v2 中,只需要配置 runtime.router ,即可开启嵌套路由:
如果你对嵌套路由的细节感兴趣,请阅读「Modern.js - 路由」文档。
Modern.js - 路由: https://modernjs.dev/guides/basic-features/routes.html#%E8%B7%AF%E7%94%B1
Modern.js v2 基于 React v18 的全新 API 支持了流式渲染(Streaming SSR )。
如果大家关注去年 React v18 的版本更新,可能会注意到它提供了新的 Server Side APIs,并对 Suspense 做了完整支持。在 Modern.js v2 中,我们通过 React Router v6 暴露的能力,在框架层面支持了流式渲染。
流式渲染利用 HTTP 的能力,允许将页面的 HTML 分割成较小的块,并逐步将这些块从服务器发送到客户端。页面无需等待所有数据加载完成,即可呈现完整用户界面,因此与数据无关的局部内容能够更早地显示出来。
在 Modern.js v2 中,只需要配置 server.ssr.mode,即可开启流式渲染:
如果你想在 Modern.js 中使用 SSR 和流式渲染,请阅读「 Modern.js 服务端渲染(SSR) 」文档。
Modern.js 服务端渲染(SSR): https://modernjs.dev/guides/advanced-features/ssr.html
Modern.js Module 是我们针对 npm 包开发场景提供的解决方案,它为开发者提供了专业的 npm 包开发工具,能够更轻松地构建、调试和发布一个 npm 包。
Modern.js Module 首页
Modern.js Module 的核心能力包括:
在 v2 版本中,我们以 esbuild 为核心,扩展其插件机制,并结合 SWC 实现了一个通用的模块构建工具,它的特性包括:
在生成 TS 类型文件上,Modern.js Module v2 也支持新的方式:
总的来说,相较于 v1 版本,Modern.js Module v2 提供了更完整的构建能力,同时构建效率也有明显提升。
如果你对 Modern.js Module 感兴趣,请移步「Modern.js Module 文档」来了解更多。
Modern.js Module 文档: https://modernjs.dev/module-tools
Modern.js Doc 是一个面向文档站场景的框架,它的目标是给开发者提供一个简单、高效、可扩展的文档站解决方案。
Modern.js Doc 官网介绍页
目前,Modern.js Doc 包含如下能力:
我们做 Modern.js Doc 的初心,是为了解决我们团队内的文档站搭建需求。随着 Modern.js Doc 的功能逐渐完整,我们也将它开放给社区使用,使它能发挥更大的价值。
目前,Modern.js Doc 仍处于 beta 测试状态,相关源代码已经开放在 Modern.js 仓库 中,并提供了基础的 使用文档。在未来,我们将继续投入,使之成为一个完成度更高的文档解决方案。
Modern.js 仓库 :https://github.com/web-infra-dev/modern.js
使用文档:https://modernjs.dev/doc-tools
Modern.js 中的部分代码实现参考了社区中的开源项目,我们对这些项目表示衷心的感谢:
现阶段 Modern.js 仍是一个很年轻的开源项目,在未来,我们将继续拥抱长期主义,持续打磨功能和文档,并以更透明的方式与社区共同协作。
如果你有兴趣尝试一下 Modern.js,欢迎试用并留下你的反馈意见~