201 - 《手撕源码 28:island.js》
发布于 2022年10月24日
今天来看下三元同学的 islands.js 是如何实现的,其实在官网文档 https://island.sanyuan0704.top/zh/guide/islands-arch.html#islandjs-的实现 有介绍,下面以我的语言重新组织下。
islands.js 是如何实现 islands 的?
假如你有一个文件,
import A from 'A';
import B from 'B';
<A />
<B __islands />
由于 islands.js 约定带 __islands
props 的组件即 islands。上述文件中,<A />
会静态渲染,<B />
会动态注水。
先做 server build,产出用于 ssr 或 ssg(渲染 html)的脚本。这里有个关键步骤,1)通过 babel 插件加 islands import 信息,2)hack jsx/runtime 收集当前页面的 islands 信息。
babel 插件转换后,上述代码会转换为,
import A from 'A';
import B from 'B';
<A />
<B __islands="B!!ISLAND!!当前文件路径" foo="bar" />
然后通过 hack jsx/runtime,用于收集 islandToPathMap 和 islandsProps 信息。
export const data = { islandProps, islandToPathMap };
function hackJsx(jsx, type, props, ...args) {
if (props && props.__island) {
data.islandProps.push(props);
data.islandToPathMap[type.name] = props.__islands;
}
}
通过 server 产物导出的 render 方