v0.18.0 引入的 Universal WC Engine 让 openElement 能自动识别第三方 Web Component 包的兼容性,安全决定谁可以 SSR、谁只能跑在浏览器。
第三方 Web Component 包来自不同的生态:有些用 Lit、有些用 Vanilla、有些只能在浏览器运行。 openElement 不做"一刀切"假设,而是通过读取标准的 custom-elements.json 文件来了解每个包。
目前很多 Web Component 包(如 @shoelace-style/shoelace)不发布custom-elements.json。没有 CEM,检测结果为空,这些包会按照 packageIslands里的显式声明来处理。
| 等级 | 含义 | 构建行为 |
|---|---|---|
ssr-capable | 有显式的 openElement SSR 声明或适配器支持 | 导入 SSR bundle,参与 DSD 渲染 |
client-only | 浏览器专用,或无 SSR 声明
| 排除出 SSR bundle,生成 client 注册/水合元数据 |
rejected | 无效 manifest、重复 tag、不安全路径 | 在代码生成前报错 |
experimental-dom | 可选的 DOM 模拟候选(需要显式开启) | 仅当 flag 开启时渲染,记录所有结果 |
在 Vite 插件的 buildStart() 阶段,openElement 会自动扫描node_modules 下的所有包,寻找 custom-elements.json:
// 伪代码 - 实际实现在 route-scanner.ts
for (const pkg of node_modules) {
const cemPath = join(pkg, 'custom-elements.json');
if (exists(cemPath)) {
const parsed = parseCem(cemPath); // CEM 解析器
const classified = classify(parsed); // 兼容性分类
results.push(classified);
}
}@org/pkg 模式构建完成后,dsd-report.json 中新增了 cemCompatibility 部分:
{
"reportVersion": "1.1.0",
"cemCompatibility": {
"packageCount": 2,
"packages": [
{
"packageName": "@third-party/wc-button",
"tier": "client-only",
"reason": "No openElement SSR extension in CEM",
"componentCount": 5
}
]
}
}每条记录包含包名、兼容等级、原因说明和组件数量,方便调试和审计。
虽然 v0.18.0 的检测能力已经就绪,但当前 www 示例站点使用的第三方包@shoelace-style/shoelace 和 media-chrome都没有发布 custom-elements.json。 因此自动检测在它们上不会返回结果--它们仍然依赖vite.config.ts 中 packageIslands 的显式声明。
| 场景 | CEM 检测结果 | 默认行为 |
|---|---|---|
| 包有 CEM + openElement SSR 扩展 | ssr-capable | 自动加入 SSR bundle |
| 包有 CEM + 无 SSR 声明 | client-only | 安全 fallback,不在服务端渲染 |
| 包无 CEM | 空(检测不到) | 通过 packageIslands 手动声明 |
| 包无 CEM + 未在 packageIslands | 空 | 不注册(需要用户显式引用) |
less validate-manifest CLI - 安装前手动验证open add - 一键安装 + 配置第三方包