@mzzsfy/dsh-toast 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MECHANISM.md +1 -1
- package/package.json +1 -1
- package/src/client.js +5 -1
- package/test/mount.test.mjs +6 -1
package/MECHANISM.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-toast 装载机制原理
|
|
2
2
|
|
|
3
|
-
本文记录公共 client 依赖包(dsh-toast 为参考实现)不进 profile 表层 manifest 却能被安装、解析、装载的完整原理。规约条目见
|
|
3
|
+
本文记录公共 client 依赖包(dsh-toast 为参考实现)不进 profile 表层 manifest 却能被安装、解析、装载的完整原理。规约条目见 `DEVELOPMENT/client-dependency.md` 与 `DEVELOPMENT/profile-link.md` 第 4 条;本文是其推导与实证依据。
|
|
4
4
|
|
|
5
5
|
## 问题:市场为什么曾显示它
|
|
6
6
|
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -120,15 +120,19 @@ window.__ModuleLoader__.load({
|
|
|
120
120
|
|
|
121
121
|
// ---- 渲染:容器直挂 body,不依赖宿主生命周期 ----
|
|
122
122
|
|
|
123
|
-
// 样式内容原位比对:一致跳过,不一致(HMR 新代 CSS 变化)
|
|
123
|
+
// 样式内容原位比对:一致跳过,不一致(HMR 新代 CSS 变化)原位替换;
|
|
124
|
+
// 在位节点无论新旧一律幂等补 data-plugin,防历史代残留缺标记被宿主 claimStyles 误归属
|
|
124
125
|
function ensureStyle() {
|
|
125
126
|
const stale = document.getElementById(STYLE_ID)
|
|
126
127
|
if (stale !== null) {
|
|
127
128
|
if (stale.textContent !== CSS) stale.textContent = CSS
|
|
129
|
+
stale.setAttribute('data-plugin', '@mzzsfy/dsh-toast')
|
|
128
130
|
return
|
|
129
131
|
}
|
|
130
132
|
const style = document.createElement('style')
|
|
131
133
|
style.id = STYLE_ID
|
|
134
|
+
// 自带 data-plugin:缺失时宿主 claimStyles 会把它归属给后续材质化插件,其 HMR 重建即误删
|
|
135
|
+
style.setAttribute('data-plugin', '@mzzsfy/dsh-toast')
|
|
132
136
|
style.textContent = CSS
|
|
133
137
|
document.head.appendChild(style)
|
|
134
138
|
}
|
package/test/mount.test.mjs
CHANGED
|
@@ -22,7 +22,7 @@ function makeState() {
|
|
|
22
22
|
function makeDocument(state) {
|
|
23
23
|
const byId = state.byId
|
|
24
24
|
const createElement = (tag) => {
|
|
25
|
-
const node = { tag, id: '', style: {}, writes: 0, remove() { byId.delete(this.id) } }
|
|
25
|
+
const node = { tag, id: '', style: {}, writes: 0, attrs: {}, setAttribute(name, value) { this.attrs[name] = value }, remove() { byId.delete(this.id) } }
|
|
26
26
|
Object.defineProperty(node, 'textContent', {
|
|
27
27
|
get() { return node._text || '' },
|
|
28
28
|
set(value) { node._text = value; node.writes += 1 },
|
|
@@ -94,6 +94,8 @@ test('首次 show 惰性挂载:容器挂 body、样式挂 head', () => {
|
|
|
94
94
|
assert.notEqual(state.byId.get(HOST_ID), undefined)
|
|
95
95
|
assert.equal(state.headChildren.some((node) => node.id === STYLE_ID), true, '样式挂宿主文档级')
|
|
96
96
|
assert.equal(state.bodyChildren.some((node) => node.id === HOST_ID), true, '容器直挂 body')
|
|
97
|
+
const styleNode = state.headChildren.find((node) => node.id === STYLE_ID)
|
|
98
|
+
assert.equal(styleNode.attrs['data-plugin'], '@mzzsfy/dsh-toast', '样式自带 data-plugin,防宿主 claimStyles 误归属后随他插件 HMR 整批误删')
|
|
97
99
|
})
|
|
98
100
|
|
|
99
101
|
test('重复 show 幂等:容器只创建一次,样式一致零写入', () => {
|
|
@@ -260,10 +262,13 @@ test('样式内容不一致原位替换:节点不重建,内容与写入计数还
|
|
|
260
262
|
// 模拟 HMR 期间 CSS 变更或旧代残留:在位样式内容与本代不一致
|
|
261
263
|
// (直写 _text 绕过写入计数,只统计实现侧的写入)
|
|
262
264
|
styleNode._text = '/* 残留的旧代样式 */'
|
|
265
|
+
// 模拟修复前旧代注入的无标记残留:原位替换须幂等补标记
|
|
266
|
+
delete styleNode.attrs['data-plugin']
|
|
263
267
|
mod.show('触发替换')
|
|
264
268
|
assert.equal(state.byId.get(STYLE_ID), styleNode, '样式节点原位保留')
|
|
265
269
|
assert.equal(styleNode.writes, 2, '替换恰新增一次写入')
|
|
266
270
|
assert.equal(styleNode.textContent, currentCss, '内容还原为当前 CSS')
|
|
271
|
+
assert.equal(styleNode.attrs['data-plugin'], '@mzzsfy/dsh-toast', '原位替换路径幂等补 data-plugin')
|
|
267
272
|
})
|
|
268
273
|
|
|
269
274
|
test('CSS 内容齐备:选择器、变体、动画与减弱动态块', () => {
|