Skip to content

fix(wujie-core): 按 href 去重入口 HTML 与动态 preload 的 stylesheet - #1109

Open
KeyToLove wants to merge 2 commits into
Tencent:masterfrom
KeyToLove:fix/css-href-dedupe
Open

KeyToLove wants to merge 2 commits into
Tencent:masterfrom
KeyToLove:fix/css-href-dedupe

Conversation

@KeyToLove

@KeyToLove KeyToLove commented Sep 12, 2026

Copy link
Copy Markdown
Checklist
  • 提交符合commit规范
  • 文档更改
  • 测试用例添加
  • npm run test通过

说明:已添加 packages/wujie-core/__test__/unit/css-href-dedupe.test.ts(5 项,其中「命中去重后的 load 派发时机」2 项为本次补充);本地 jest -c __test__/unit/jest.config.js 21 suites / 99 tests 通过。未跑 puppeteer 集成测试。未改文档站。

详细描述
  • 特性
    • 入口 HTML 将 CSS 转成 <style> 时写入 data-wujie-css-href
    • 动态 loadStyleSheet 插入前按该属性和注释 /* href */ 查找;命中则不再插入第二份 style,改为异步(setTimeout(..., 0))对原 link 派发 load。消费方是在 appendChild 返回之后才 addEventListener("load"),在调用栈内同步派发会丢事件,导致 Vite preload 的 promise 不落定、动态 import 的 chunk 不执行。
    • 动态插入成功后也设置 data-wujie-css-href
    • 用于 Vite 8 生产构建:同一份 CSS 既在 HTML <link> 中,又被 __vite__mapDeps preload 时,避免两份 style 导致后插入的默认宽高盖住原子类。
  • 关联issue

最小复现:https://github.com/KeyToLove/wujie-vite8-css-dup-demo

Skip inserting a second style when the same href was already inlined from
the entry HTML or a prior dynamic placeholder. Still dispatch load on the
original link so Vite preload can settle.

close Tencent#1108
Dispatching load synchronously inside the hijacked appendChild loses the event
when the consumer registers its listener only after appendChild returns. Vite's
preload helper appends the link first and calls addEventListener("load") second,
so its promise never settled and the lazily imported chunk never executed.

Dispatch in a macrotask instead. Covered by two unit cases: a listener attached
after the dispatch still receives load, and nothing is dispatched in the same tick.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vite 8 入口 HTML CSS 与动态 mapDeps preload 会重复插入两份 style

1 participant