feat: deploy on edge environment#8097
Conversation
🦋 Changeset detectedLatest commit: d746cd3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 113 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for modernjs-v3 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
感谢对 Modern.js 的支持和贡献!🙏 由于这次改动涉及范围较大,为了确保发布后的质量和用户体验,有几个问题想和你一起探讨:
|
|
esm 运行时已经跑通,但发现二次打包会造成多实例问题,故先标记为 draft,等我尝试一下另外的解决方式 |
|
@yimingjfe Hello,目前已经完成主要涉及包的ESM迁移。主要改动:
pure-esm-project 在CF/EO上的运行演示(阿里云 ESA 暂时没办法支持 BFF)
测试运行:
排查问题过程中发现一个潜在问题,因为暂时没触发所以也就暂时没解决,先放上来 solutions/app-tools/src/builder/shared/builderPlugins/adapterBasic.ts 中,在 applyNodeCompat 中通过 extensionAlias 定义了后缀优先级,例如 .node.js 优先于 .js。 但不确定是因为其他插件有注入配置还是因为默认配置,实际上生效的 extensionAlias 中, 另有几个问题暂时没什么好想法:
|
|
感谢贡献,改动确实比较大,我们讨论看看 @zllkjc |
我认为,讨论的关键应该是定义“worker环境的特征”。看看这种“基于产物二次打包产生单一文件、没有真实文件系统”是不是worker环境的普遍特征。 如果是,那么SSR ENV=worker时,处理文件树结构也合理? web worker 理论上可以支持 import 方式的“多文件”,但本质上仍然没有目录树。从我目前接触到的各个云计算平台看,似乎没有真正支持多文件环境的 worker。 又或者说,你认为更好的方式是给这种环境用一个新变量,而不与 worker 强绑定?比如 BUNDLE_MODE=single ? |
|
Hello 同学你好,这个 PR 是否可以拆分一下。我理解这里涉及几个内容:
现在上下文和改动点有点太多了,如果出现问题我们不太好追因和回滚~ 再次感谢对 Modern.js 的支持! |
这两个可能没法拆,因为哪怕是最小SSR Demo,本身也依赖好几个包的ESM改造。 或者,先Review ESM改造,再对部署打包逻辑单独提一个? 但本身两者是依赖比较紧密的,如果ESM改造出问题需要回滚,这几个平台部署也会受影响
硬要拆的话,应该只有一个BFF功能能拆出来?但BFF功能本身涉及的包也不多,我判断下来也就 |
|
@sylingd 可以的,先把 ESM 改造单独拆一个 |
|
这个 PR 要先 close 吗 |
Summary
支持部署至边缘计算环境(包括腾讯云 EdgeOne、阿里云 ESA、Cloudflare Workers)(顺便修复了#7758 )
Support deploy application to edge computing environments (including Tencent EdgeOne, Alibaba Cloud ESA, and Cloudflare Workers).
Related Links
Checklist
pnpm run change.详细说明
支持了哪些平台
为什么没有在原有的 workerSSR 基础上做
有试图完善这个功能。但发现存在几个问题:
后重新考虑方案,决定基于node版本实现,原因如下:
第三方平台环境特点
运行环境
入口文件
同时,三者都有一个共同特点:会对产物进行二次打包,生成单一文件供运行。因此,会破坏原有文件结构,即使CF对fs相关API进行了兼容,也没有办法直接使用。
没有支持腾讯云EO的Edge Functions的原因是其缺失太多Node API,比如async_hooks库。实际上我最早开始尝试支持的也是它,理论上我可以改出一个我自己可以用的版本,但工作量很大且会对原有功能造成 break change,不具备通用性,所以最终放弃。
主要改动说明
依赖方式的核心改动
app-tools不改变原有产物结构。将这三个平台的产物生成入口+deps.js的方式,供其特有的打包工具二次打包。其中,deps.js会扫描所有node产物,并生成一个包含文件结构+内容的结构。在后续工具中,可以通过该结构读取依赖信息。server/core新增了 edge-function 的适配器,包含原有 node 插件的实现。plugin-bffserver/bff-core改动了 bff 插件,以适配上文提到的“deps.js”形式的依赖结构。Hono API暴露
server/core将 bindings 通过 loaderContext 暴露给用户。原因是其中包含了一些平台特有信息,如腾讯云EO的节点信息(其中包含了GeoIP地理信息、服务器节点等)、CF Workers的环境信息(用户需要通过它调用内置服务,如D1等)。其他
prod-serverapp-tools增加了相关入口server/create-request优先使用全局的fetch APIapp-tools增加了对各平台的入口及编译兼容配置app-tools复制 cjs 和 mjs 文件,避免被 rslib 编译一遍toolkit/utils在生成的 esm 产物中保留 import 语句,避免编译后出现 createRequire(此功能在阿里云ESA中不可用)toolkit/pluginserver/core在 package.json 中增加 esm 指向,以支持在编译时对相关包进行 tree shaking(否则会因为 cjs 没法 tree shaking 引入过多包,可能出现部分包不兼容、体积过大等问题)其他
为什么没有使用ndepe复制依赖,而是单独打包了一份modern-server
RSC 相关
暂未对 edge 环境实现 RSC 相关插件。主要原因:该功能似乎看起来还没做完。文档中也没有相关说明,无法测试。可以在后续该功能正式上线后再进行适配。
已经测试内容
在上述三个平台及node中对以下功能进行了简单测试:
未测试:vercel、netlify(从改动上分析不会对原有功能造成影响,因没有账号故未做实际测试)