feat(client): 删除 rc.7 宿主的 __DSH_MODULES__ 回退路径

peer 基线已是 ^0.1.2-rc.1(全部 dsh-* peer),最后提供
window.__DSH_MODULES__ 页面全局的宿主是 0.1.0-rc.7,远低于下限,
装不上本插件——回退在受支持宿主上不可达。受支持宿主上 apply() 在
任何懒加载发生前调 setChunkModuleSystem(ctx.modules),moduleSystem()
前两跳(注入变量 + 插件全局 __dshSidebarModuleSystem__)必中。

回退的唯一活消费者是 vitest fixture:installModuleSystem() 原先经
rc.7 全局投递 fake 模块系统,现改为与生产同路径的 setChunkModuleSystem
注入;无任何专测回退分支的用例,全部断言保持不变。

- chunk-loader.ts: 删 moduleSystem() 第三跳,同步头注 /
  ChunkModuleSystem 接口注中的回退描述
- index.tsx: 删「falls back to the rc.7 global」注释
- README v0.14.0 changelog 与 docs/plans 设计文档中的提及属历史
  存档(描述 PR #232 当时的迁移),保留不改

验证:lint / typecheck / build / vitest 119 文件 1243 用例全绿;
真机挂载 lane(钉版 @deepseek-ai/dsh@0.1.2-rc.1 CLI)mount.e2e
全内置 tab sweep(含终端 / editor 懒加载 chunk)通过;lib/*.js
产物中无 __DSH_MODULES__ 残留。
This commit is contained in:
Menghuan1918
2026-09-03 20:29:59 +08:00
parent 8820efd6bf
commit dc33087ce1
3 changed files with 13 additions and 22 deletions
+5 -6
View File
@@ -23,8 +23,9 @@
* arbitrary file names, so the plugin's own host route serves the chunks),
* 2. read the factory from the global registry,
* 3. call it with a require that resolves the platform externals through
* `__DSH_MODULES__.import(spec)` — the seed-word branch, the one part of
* the module system that is stable across versions.
* the injected module system's `import(spec)` (the `ctx.modules` service)
* — the seed-word branch, the one part of the module system that is
* stable across versions.
*
* Caching contract (three layers, each with a failure path):
* - In-memory: one in-flight promise per chunk, memoized until
@@ -90,8 +91,7 @@ const CHUNK_REVALIDATE_TIMEOUT_MS = 5_000
* The client module system surface this loader needs to resolve externals.
* DSH 0.1.0-rc.8 provides it as the `ctx.modules` service (no page global
* anymore); the plugin injects it at activation via
* {@link setChunkModuleSystem}. The rc.7-era `window.__DSH_MODULES__` global
* remains as a fallback so older hosts and the test harness keep working.
* {@link setChunkModuleSystem}.
*/
export interface ChunkModuleSystem {
import(specifier: string): Promise<unknown>
@@ -123,12 +123,11 @@ export function setChunkModuleSystem(system: ChunkModuleSystem | undefined): voi
}
/** Resolve the shell-installed module system (injected, then the plugin
* global shared with chunk-bundle copies, then the rc.7 page global). */
* global shared with chunk-bundle copies). */
function moduleSystem(): ChunkModuleSystem | undefined {
const g = globalThis as Record<string, unknown>
return injectedModuleSystem
?? g[MODULE_SYSTEM_GLOBAL] as ChunkModuleSystem | undefined
?? (g as { __DSH_MODULES__?: ChunkModuleSystem }).__DSH_MODULES__
}
/** The plugin-owned chunk factory registry the chunk scripts populate. */
+3 -4
View File
@@ -188,10 +188,9 @@ export function apply(ctx: Context): void {
}
}
try {
// rc.8+ exposes the client module system as the `ctx.modules` service
// (no window.__DSH_MODULES__ page global anymore); the chunk loader needs
// it to resolve its externals, so inject it before anything can load a
// lazy chunk. The loader falls back to the rc.7 global when absent.
// rc.8+ exposes the client module system as the `ctx.modules` service;
// the chunk loader needs it to resolve its externals, so inject it
// before anything can load a lazy chunk.
setChunkModuleSystem(ctx.modules)
// Fresh chunk state for this activation: drop per-test fixtures and
// revalidate loaded chunk scripts against the bundle route's ETags —
+5 -12
View File
@@ -8,9 +8,10 @@
* - externals resolve through the module system's seed branch (the stable,
* version-independent part), once per page,
* - resetChunks drops the cache and the externals memo (HMR).
* The production path runs against a fake `window.__DSH_MODULES__` and a
* stub script loader that simulates the executed chunk script by assigning
* the plugin-owned global factory registry.
* The production path runs against a fake module system injected via
* {@link setChunkModuleSystem} (mirroring the client half's `ctx.modules`
* injection) and a stub script loader that simulates the executed chunk
* script by assigning the plugin-owned global factory registry.
*/
import { beforeEach, describe, expect, it, vi } from 'vitest'
import './browser-globals.ts'
@@ -33,14 +34,10 @@ function installModuleSystem(): FakeModuleSystem {
const fake: FakeModuleSystem = {
import: vi.fn(async (specifier: string) => ({ seed: specifier })),
}
;(globalThis as Record<string, unknown>).__DSH_MODULES__ = fake
setChunkModuleSystem(fake)
return fake
}
function removeModuleSystem(): void {
delete (globalThis as Record<string, unknown>).__DSH_MODULES__
}
/** Simulate a chunk script executing: it assigns its factory to the registry. */
function simulateScript(name: string, factory: (require: (spec: string) => unknown) => ChunkExports): void {
const g = globalThis as { __dshChunks__?: Record<string, unknown> }
@@ -49,7 +46,6 @@ function simulateScript(name: string, factory: (require: (spec: string) => unkno
}
beforeEach(() => {
removeModuleSystem()
setChunkModuleSystem(undefined)
delete (globalThis as Record<string, unknown>).__dshChunks__
resetChunks()
@@ -89,9 +85,6 @@ describe('test-registry path (vitest / jsdom-less environments)', () => {
describe('production path (script injection + global registry + externals require)', () => {
it('resolves externals through an injected ctx.modules system (rc.8 — no page global)', async () => {
const modules = installModuleSystem()
// rc.8 drops window.__DSH_MODULES__; the client half injects ctx.modules.
removeModuleSystem()
setChunkModuleSystem(modules)
const loaded: string[] = []
setChunkScriptLoaderForTests(async (src) => {
loaded.push(src)