@dsh-workbench/module-tools 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -103,9 +103,18 @@ dsh-wb-module design accept # 用户逐条点头之后,把验收清单打勾
103
103
  | `minimal`(默认) | 空壳:卡壳、文案、测试接好了,没有数据源 |
104
104
  | `diy` | 一份真能跑的样板:宿主侧一条只读路由真读盘、卡片五态,**三张表也是填好的** |
105
105
 
106
- `init` 会连模板里的 `*.tpl` 一起拷过去、把 `__UNIT__` / `__NAME__` / `__DESC__` 填上、剥掉 `.tpl` 后缀,
106
+ `init` 会连模板里的 `*.tpl` 一起拷过去、按**已知 token 名**逐个盖章
107
+ (`__UNIT__` / `__NAME__` / `__DESC__` / `__SHELL_RANGE__`)、剥掉 `.tpl` 后缀,
107
108
  再用 `design.json` 生成 README 那一段。
108
109
 
110
+ - `__UNIT__` / `__NAME__` / `__DESC__`:单元 id / 包名 / 一句描述。
111
+ - `__SHELL_RANGE__`:模板里那三处 `@dsh-workbench/*` 声明的**范围**(peer 与 devDependency 用同一个值,
112
+ 否则 `check:kit` 的"peer 下限不许比 devDependency 旧"当场红)。取 **init 所在工程里实装的那份**
113
+ `@dsh-workbench/core` 的版本(`node_modules/@dsh-workbench/core/package.json`);读不到就退回
114
+ `module-tools` 自己的版本(同一次发布同版本);两者都读不到才保持 `^0.1.0`,并在 stderr 上说一句。
115
+ - 按 token 名盖章而不是按 `__[A-Z]+__` 的形状:名字里带下划线的 `__SHELL_RANGE__` 也要认,
116
+ DIY 模板 README 里真写着的 `workbench___UNIT___rebuild` 则仍只认内层那一个。
117
+
109
118
  ## 自己的自检
110
119
 
111
120
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/module-tools",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "模块包的构建与门禁工具:build(单文件 ESM 宿主侧 + 套 loader 壳的浏览器侧)、check(契约/产物边界/源码边界/卡片渲染)。模块包不再各带一份构建脚本。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "esbuild": "^0.28.2",
24
- "@dsh-workbench/shared": "0.3.0"
24
+ "@dsh-workbench/shared": "0.3.1"
25
25
  },
26
26
  "scripts": {
27
27
  "selfcheck": "node scripts/selfcheck.mjs"
package/src/init.mjs CHANGED
@@ -9,6 +9,33 @@ const TEMPLATES = {
9
9
  };
10
10
  const UNIT_ID = /^[a-z][a-z0-9-]*$/;
11
11
 
12
+ // 模板里那三处 `@dsh-workbench/*` 声明的不是"某个死数",而是**盖章那一刻的工具链范围**:
13
+ // 优先 init 所在工程里实际装着的那份外壳(用户手上真正会跑的那个版本),退回 module-tools
14
+ // 自己的版本(同一次发布同版本,`^0.3.0` 这类范围对得上),两者都读不到时保持旧模板的
15
+ // `^0.1.0` 并说一句人话 —— 静默盖个空范围会让生成的 package.json 声明一个谁也不认的依赖。
16
+ // 为什么两个 token 共用一个值:`check:kit` 的口径是 peer 下限不许低于 devDependency 下限。
17
+ const FALLBACK_RANGE = '^0.1.0';
18
+
19
+ const versionIn = (file) => {
20
+ try {
21
+ const version = JSON.parse(readFileSync(file, 'utf8')).version;
22
+ return typeof version === 'string' && version !== '' ? version : undefined;
23
+ } catch {
24
+ return undefined;
25
+ }
26
+ };
27
+
28
+ const shellRange = (root) => {
29
+ const installed = versionIn(join(root, 'node_modules/@dsh-workbench/core/package.json'));
30
+ if (installed !== undefined) return `^${installed}`;
31
+ const own = versionIn(fileURLToPath(new URL('../package.json', import.meta.url)));
32
+ if (own !== undefined) return `^${own}`;
33
+ console.error(
34
+ `读不到 @dsh-workbench/core 与 module-tools 的版本:模板里那三处 @dsh-workbench/* 保持 ${FALLBACK_RANGE}(与以前一样);在装好依赖的工程里 init 就能盖上当下范围`,
35
+ );
36
+ return FALLBACK_RANGE;
37
+ };
38
+
12
39
  export async function init({ root, args = [] }) {
13
40
  const unit = args[0];
14
41
  if (unit === undefined || !UNIT_ID.test(unit)) {
@@ -36,8 +63,13 @@ export async function init({ root, args = [] }) {
36
63
  __UNIT__: unit,
37
64
  __NAME__: `@dsh-workbench/module-${unit}`,
38
65
  __DESC__: description,
66
+ __SHELL_RANGE__: shellRange(root),
39
67
  };
40
- const fill = (text) => text.replace(/__[A-Z]+__/g, (token) => tokens[token] ?? token);
68
+ // 按**已知 token 名**逐个盖章,而不是按 `__[A-Z]+__` 的形状:名字里带下划线的 token
69
+ // (`__SHELL_RANGE__`)也要认;同时 DIY 模板 README 里真写着的 `workbench___UNIT___rebuild`
70
+ // 仍然只认内层那一个(按形状宽匹配会把三重下划线整段吞掉,工具名就盖不成 `workbench_demo_rebuild`)。
71
+ const fill = (text) =>
72
+ text.replace(new RegExp(Object.keys(tokens).join('|'), 'g'), (token) => tokens[token]);
41
73
  const templateDir = fileURLToPath(new URL(template, import.meta.url));
42
74
  if (!existsSync(templateDir)) {
43
75
  console.error(`模板 ${which} 的目录不在:${templateDir}`);
@@ -32,11 +32,11 @@
32
32
  },
33
33
  "workbenchFaces": { "host": "src/host.ts", "client": "src/client.tsx" }
34
34
  },
35
- "peerDependencies": { "@dsh-workbench/core": "^0.1.0", "react": "*" },
35
+ "peerDependencies": { "@dsh-workbench/core": "__SHELL_RANGE__", "react": "*" },
36
36
  "peerDependenciesMeta": { "react": { "optional": true } },
37
37
  "devDependencies": {
38
- "@dsh-workbench/core": "^0.1.0",
39
- "@dsh-workbench/module-tools": "^0.1.0",
38
+ "@dsh-workbench/core": "__SHELL_RANGE__",
39
+ "@dsh-workbench/module-tools": "__SHELL_RANGE__",
40
40
  "@types/node": "^24.19.0",
41
41
  "@types/react": "^19.3.0",
42
42
  "react": "^19.3.0",
@@ -33,11 +33,11 @@
33
33
  },
34
34
  "workbenchFaces": { "host": "src/host.ts", "client": "src/client.tsx" }
35
35
  },
36
- "peerDependencies": { "@dsh-workbench/core": "^0.1.0", "react": "*" },
36
+ "peerDependencies": { "@dsh-workbench/core": "__SHELL_RANGE__", "react": "*" },
37
37
  "peerDependenciesMeta": { "react": { "optional": true } },
38
38
  "devDependencies": {
39
- "@dsh-workbench/core": "^0.1.0",
40
- "@dsh-workbench/module-tools": "^0.1.0",
39
+ "@dsh-workbench/core": "__SHELL_RANGE__",
40
+ "@dsh-workbench/module-tools": "__SHELL_RANGE__",
41
41
  "@types/node": "^24.19.0",
42
42
  "@types/react": "^19.3.0",
43
43
  "react": "^19.3.0",