呜啦!日常碎碎念,偶尔掉落优质前端博文推荐、学习资源等
网页:https://tg.cosine.ren
本频道的搜索Bot 来辣 👉 @cosSearchBot
私聊直接发消息就可以搜索啦~
🔖tags
#优质博文 #资源推荐 #博客更新 #碎碎念 #项目更新 #手工 #书摘 #阮一峰的科技周刊 #新动态
图频:Cosine 🎨 Gallery @CosineGallery
猫片: @cosine_cat
网页:https://tg.cosine.ren
本频道的搜索Bot 来辣 👉 @cosSearchBot
私聊直接发消息就可以搜索啦~
🔖tags
#优质博文 #资源推荐 #博客更新 #碎碎念 #项目更新 #手工 #书摘 #阮一峰的科技周刊 #新动态
图频:Cosine 🎨 Gallery @CosineGallery
猫片: @cosine_cat
#优质博文 #前端 #react #RSC #javascript #工程化
讲 RSC 讲的最明白的一集,写的太牛了。
How Imports Work in RSC
author Dan Abramov
讲 RSC 讲的最明白的一集,写的太牛了。
How Imports Work in RSC
AI 摘要:本文深入探讨了 React Server Components (RSC) 中导入(import)和导出(export)机制的运作方式,重点分析了如何通过 'use client' 和 'use server' 指令在前后端环境中划分代码。作者从模块系统的基本原理出发,解释了 JavaScript 模块的单例特性及其在单一环境中的运作方式,随后扩展到前后端代码共享的挑战和解决方案,提出了 'server-only' 和 'client-only' 的“毒丸”机制来防止代码跨环境误用,并通过 RSC 的指令机制实现前后端模块系统的交互。文章旨在帮助读者构建对 RSC 的准确心智模型,同时也适用于对模块系统感兴趣的开发者。
什么是模块系统?
• 模块系统的定义:模块系统是一套规则,用于将程序拆分为文件,控制代码可见性,并将代码链接为可执行的单一程序。
• 人类需求:模块帮助开发者将复杂程序拆分为可管理的部分,限制代码可见性以保护实现细节,并促进代码复用。
• 计算机执行:计算机需要在内存中“展开”模块代码以执行程序,模块系统弥合了人类编写代码和计算机执行之间的差距。
• JavaScript 模块:通过 import 和 export 关键字实现模块化。
导入就像复制粘贴……但又不完全是
• 基本直觉:JavaScript 的模块系统设计使得 import 和 export 的效果类似于复制粘贴,最终程序在内存中展开为单一代码块。
• 与 C 语言的 #include 对比:C 的 #include 确实是直接复制粘贴,可能导致命名冲突和重复包含问题,而现代模块系统(如 JavaScript)通过自动处理避免这些问题。
JavaScript 模块是单例
• 单例特性:每个模块无论被导入多少次,其代码只执行一次,模块系统通过缓存已加载模块的导出值来实现这一点。
• 优势:避免代码重复导致输出体积膨胀;模块可保持私有状态;简化心智模型,每个模块视为单一实例。
• 实现机制:模块系统通常使用 Map 记录已加载模块及其导出值,例如在 Node.js、Webpack 等工具中均有类似逻辑。
一个程序,一个计算机
• 单一环境设计:大多数 JavaScript 程序是为单一计算机(如浏览器或 Node.js 服务器)设计的,模块系统支持从入口文件开始加载并缓存模块。
• 导入效果:导入模块时,代码被“带入”当前程序,模块保持单例特性,避免重复执行。
两个程序,两个计算机
• 前后端分离:传统上,前端和后端是运行在不同计算机上的两个独立程序,分别负责交互逻辑和 HTML/API 服务。
• 模块系统独立性:前后端各有独立的模块系统,共享代码(如 a.js)会在两个环境中分别加载,实质上是“各自的版本”。
构建失败是好事
• 代码复用风险:共享代码可能引入只适用于一侧的 API(如后端的 fs),导致另一侧构建失败。
• 构建失败的价值:构建失败提供早期反馈,迫使开发者解决代码复用问题,可选择调整代码位置或依赖关系。
仅限服务器端代码
• 问题场景:若共享代码引入服务器端敏感信息(如密钥),可能无构建错误地泄露到前端。
• 解决方案:引入 server-only “毒丸”包,标记不可进入前端的代码,前端构建时遇到则失败,强制开发者修复。
• 传递性:只需在源头文件标记 server-only,依赖链会自动传播此限制。
仅限客户端代码
• 类似机制:引入 client-only “毒丸”,防止特定前端代码(如 DOM 操作)被后端引入,构建失败以避免运行时错误。
• 细粒度控制:如 React 通过条件导出机制将 useState 等 API 标记为 client-only。
一个程序,两个计算机(RSC 视角)
• 前后端协作问题:传统方式依赖约定同步前后端代码,缺乏语法支持,易出错。
• RSC 创新:use client 指令允许后端引用前端代码而不将其引入后端,实质是“打开前端之门”,生成 <script> 标签在前端恢复;use server 则相反。
• 指令作用:非指定代码运行位置,而是创建模块系统间的“门”,用于数据传递而非代码移动。
结论
• RSC 核心:承认前后端模块系统独立性,共享代码在两侧分别存在。
• 两大机制:server-only 和 client-only 防止代码误入错误环境;use client 和 use server 提供跨环境引用和数据传递的“门”。
• 最终模型:RSC 将应用视为跨两台计算机的单一程序,拥有独立模块系统、毒丸保护和交互之门,开发者只需处理构建错误即可。
author Dan Abramov