@morlay/dsh-client-modules 0.2.11-alpha.2 → 0.2.11

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/src/index.ts CHANGED
@@ -97,10 +97,13 @@ export interface ClientRow {
97
97
  * 自己的 client 半里 import,不该出现在装配清单里;混进来就会多装配一次(`apply` 里那些"同 namespace 的
98
98
  * locale 已注册"的报错就是这么来的),也会在入口打出一串 `skip (no apply/default)`。
99
99
  */
100
- async function clientRowsOf(loader: { entries(): Generator<LoaderEntry> }): Promise<ClientRow[]> {
100
+ // 参数只声明"能迭代条目":上游 `Entry` 的类型面随版本演进(alpha.3 换了 `Generator` 的返回/next 参数),
101
+ // 我们只要下面那几个字段,边界收成 `unknown` 再窄化,别让版本演进每次都在这里报类型错。
102
+ async function clientRowsOf(loader: { entries(): Iterable<unknown> }): Promise<ClientRow[]> {
101
103
  const found = new Map<string, ClientRow>();
102
104
  // `entries()` 是生成器(cordis 的 Loader 就是这么给的),直接迭代即可。
103
- for (const entry of loader.entries()) {
105
+ for (const raw of loader.entries()) {
106
+ const entry = raw as LoaderEntry;
104
107
  if (entry.disabled === true || entry.fiber === undefined) continue;
105
108
  const name = entry.options?.name;
106
109
  if (typeof name !== "string" || name === "") continue;
@@ -395,6 +398,10 @@ export function apply(ctx: Context): void {
395
398
  ): Promise<string | undefined> => {
396
399
  // `@/…` 是本地文件(alias 管),不是包——`packageNameOf` 会把它切成 `@/vendor` 这种假包名。
397
400
  if (specifier.startsWith("@/")) return undefined;
401
+ // 样式引用交给 vite 的 CSS 管线内联:改写成联邦 URL 会让浏览器把 `text/css` 当 ESM 模块加载
402
+ // (`Failed to load module script: … MIME type "text/css"`)。联邦构建那侧有对应的内联(见
403
+ // `dsh-css-specifiers`)。
404
+ if (specifier.endsWith(".css")) return undefined;
398
405
  // `zlib` / `stream` 这类**裸名的 node 内置**不是包:接管成联邦地址只会换来一串 404。留给 alias
399
406
  // 的替身(名单同一份)。
400
407
  if (NODE_BUILTIN.test(specifier)) return undefined;
@@ -576,8 +583,11 @@ export function apply(ctx: Context): void {
576
583
  // **不发 304**:这边的响应最终要由上游包成 Fetch `Response`,而它不接受 304
577
584
  // (`Invalid response status code 304`)——请求会以异常告终。产物本来就不大,直接 200 全量。
578
585
  const etag = `"${bundled.rev}"`;
586
+ // 产物类型由文件扩展名决定:CSS 出口就是 CSS 文本,其余是 JS 模块。
587
+ const extension = target.slice(target.lastIndexOf(".") + 1).toLowerCase();
579
588
  res.writeHead(200, {
580
- "content-type": "text/javascript; charset=utf-8",
589
+ "content-type":
590
+ extension === "css" ? "text/css; charset=utf-8" : "text/javascript; charset=utf-8",
581
591
  "cache-control": cacheControl,
582
592
  etag,
583
593
  });
package/src/resolve.ts CHANGED
@@ -268,7 +268,8 @@ export async function exportTargetOf(
268
268
  // `exports` 的三种形状(都要认):
269
269
  // · 以 `.` 开头的键映射(标准)→ 取 `exports["."]` / `exports["./sub"]`;
270
270
  // · **条件对象本身**(`{ development, default }`,`mdast-util-*` 就是这形状)→ 它**就是**根出口;
271
- // · 没有 `exports` → 按 node 规则退回 `module` → `main`(老包如 `fortune-sheet`)。
271
+ // · 没有 `exports` → 打包器约定:`module`(ESM)→ `main`。有 ESM 就走 ESM,不把双形态包
272
+ // 降级成 CJS 再来适配(`rrule` / `@xterm/xterm` 的 `module` 都是它们的 ESM 面)。
272
273
  const table = manifest.exports;
273
274
  const isSubpathMap =
274
275
  table !== undefined &&
package/src/serve-vite.ts CHANGED
@@ -11,7 +11,8 @@ import { fileURLToPath } from "node:url";
11
11
  import type { Context } from "@deepseek-ai/cordis";
12
12
  import { traceOf } from "./trace.ts";
13
13
  import { createServer, type ServerOptions, type ViteDevServer } from "vite";
14
- import { clientModulesAlias } from "./bundle.ts";
14
+ import { browserProcessPlugin, clientModulesAlias } from "./bundle.ts";
15
+ import { clientBuildMeta } from "./client-meta.ts";
15
16
  import { dshClientRowsPlugin, ROWS_VIRTUAL } from "./vite-plugin.ts";
16
17
  import { packageRootOf } from "./resolve.ts";
17
18
 
@@ -93,11 +94,9 @@ export async function startViteDev(
93
94
  // **不要**把 base 改成 `/@/` 去"统一前缀":vite 会给所有不以 base 开头的绝对 URL 再补一层,
94
95
  // 联邦地址(`/@client-modules/…`)会变成 `/@/@client-modules/…`,两条链全断。
95
96
  base: "/",
96
- // 浏览器没有 `process`:客户端半常读 `process.env.NODE_ENV`(上游 client 打包也做同样的替换)。
97
+ // 浏览器没有 `process`:裸 `process` 给空壳(逐文件服务的源码里会读它)。`process.env` 与版本元数据
98
+ // (`DSH_CLIENT_*`)由 `browserProcessPlugin` 处理——与联邦构建同一份规则,顺序只写在一处。
97
99
  define: {
98
- "process.env.NODE_ENV": JSON.stringify(process.env["NODE_ENV"] ?? "development"),
99
- "process.env": "{ env: {} }",
100
- // 裸 `process` 同样要给空壳(逐文件服务的源码里也会读它)。
101
100
  process: "{ env: {} }",
102
101
  },
103
102
  publicDir: false,
@@ -142,18 +141,17 @@ export async function startViteDev(
142
141
  // 表现为一串"没被 vite 接手"的 404)。
143
142
  fs: { strict: false, allow: [repoRoot] },
144
143
  },
145
- // **不用** vite 的 `optimizeDeps`:裸说明符已由插件统一改写成 `@deps/`(我们自己预打包的产物),
146
- // vite 再打一份就会与聚合产物里的那份形成两个实例。
147
- // **不用** vite 的 `optimizeDeps`(关掉自动发现):非开发模块与三方都由我们的联邦链产出,裸说明符
148
- // 已在插件里改写成 `@client-modules/…`,这里没有任何东西需要预打包。开着只会多出第二条链(浏览器里
149
- // 同时出现 `.vite/deps/react.js` 与我们的 `@client-modules/react@…/index.js`)与一次全仓扫描。
150
- // **彻底不用** vite 的依赖优化器:裸说明符已由插件统一改写成 `@client-modules/…`(我们自己的联邦链产出),
151
- // 这里没有任何东西需要它预打包。`noDiscovery: true` 只关了"自动发现",扫描器仍会去解析那些包名——而行清单
152
- // 是**虚拟模块**、里面写的包名 vite 按 `package.json` 的去向解析,落到工作区解析面上就报
153
- // `Cannot find package … imported from …/package.json`(上游 workspace 内部包只存在于 vendor / 闭包)。
154
- // `disabled` 是官方给的"整个关掉"(标了 deprecated,但语义正是这个)。
155
- optimizeDeps: { disabled: true, noDiscovery: true, include: [] },
144
+ // **不用** vite 的依赖优化器:裸说明符已由插件统一改写成 `@client-modules/…`(我们自己的联邦链产出),
145
+ // 这里没有任何东西需要它预打包。开着只会多出第二条链(浏览器里同时出现 `.vite/deps/react.js` 与我们的
146
+ // `@client-modules/react@…/index.js`,两个实例)与一次全仓扫描。行清单是**虚拟模块**、里面写的包名 vite
147
+ // 会按 `package.json` 的去向解析,落到工作区解析面上就报
148
+ // `Cannot find package … imported from …/package.json`(上游 workspace 内部包只存在于 vendor / 闭包),
149
+ // 所以必须连"扫描"一起关掉。
150
+ // 官方口径的"整个关掉"就是这两个字段(`optimizeDeps.disabled` 在 Vite 5.1 已移除,传它只会换来一条告警)。
151
+ optimizeDeps: { noDiscovery: true, include: [] },
156
152
  plugins: [
153
+ // 与联邦构建同一份 `process.env` 处理(含 `DSH_CLIENT_*` 的版本元数据)。
154
+ browserProcessPlugin(await clientBuildMeta(repoRoot)),
157
155
  dshClientRowsPlugin({
158
156
  repoRoot,
159
157
  rows: () => rowsOf(options.rows),