@dsh-workbench/module-tools 0.3.10 → 1.0.0-beta.0
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/LICENSE +21 -0
- package/README.md +223 -177
- package/bin/dsh-wb-module.mjs +89 -34
- package/package.json +18 -3
- package/src/arch.mjs +158 -129
- package/src/build.mjs +6 -30
- package/src/changelog.mjs +167 -0
- package/src/check-flags.mjs +0 -7
- package/src/check.mjs +115 -53
- package/src/checks/alias.mjs +0 -9
- package/src/checks/arch.mjs +3 -25
- package/src/checks/bundles.mjs +2 -34
- package/src/checks/cards.mjs +26 -30
- package/src/checks/contracts.mjs +61 -222
- package/src/checks/kit.mjs +2 -42
- package/src/checks/lint.mjs +9 -82
- package/src/checks/markers.mjs +48 -17
- package/src/checks/primitives.mjs +0 -39
- package/src/checks/protocol.mjs +0 -18
- package/src/checks/source.mjs +163 -29
- package/src/checks/standalone.mjs +4 -14
- package/src/checks/style.mjs +71 -241
- package/src/css-injection.mjs +0 -11
- package/src/css-shell.mjs +3 -31
- package/src/datasource-file.mjs +104 -0
- package/src/declared-tools.mjs +0 -24
- package/src/design.mjs +116 -38
- package/src/discover.mjs +2 -10
- package/src/font-scale.mjs +1 -61
- package/src/init.mjs +2 -17
- package/src/lint.mjs +24 -144
- package/src/market-index.mjs +569 -0
- package/src/market-init.mjs +80 -0
- package/src/primitives-surface.mjs +2 -28
- package/src/publish.mjs +6 -24
- package/src/release-changelog.mjs +29 -0
- package/src/release-journal.mjs +131 -0
- package/src/release-report.mjs +99 -0
- package/src/release-util.mjs +80 -0
- package/src/release.mjs +1251 -0
- package/src/seed.mjs +0 -25
- package/src/shell-type-files.mjs +3 -30
- package/src/sync.mjs +41 -24
- package/template/AGENTS.md.tpl +33 -0
- package/template/CHANGELOG.md.tpl +7 -0
- package/template/README.md.tpl +6 -33
- package/template/package.json.tpl +2 -2
- package/template/src/client.tsx.tpl +1 -18
- package/template/src/host.ts.tpl +2 -15
- package/template/types/globals.d.ts +1 -14
- package/template-diy/AGENTS.md.tpl +33 -0
- package/template-diy/CHANGELOG.md.tpl +7 -0
- package/template-diy/README.md.tpl +4 -133
- package/template-diy/package.json.tpl +2 -2
- package/template-diy/src/client.tsx.tpl +1 -29
- package/template-diy/src/host.ts.tpl +1 -15
- package/template-diy/src/messages.ts.tpl +4 -4
- package/template-diy/src/plugin.test.ts.tpl +1 -1
- package/template-diy/types/globals.d.ts +1 -14
- package/template-diy/types/styles.d.ts +0 -10
package/src/lint.mjs
CHANGED
|
@@ -1,57 +1,12 @@
|
|
|
1
|
-
// 模块包的**语法卫生方言**(eslint 的模块版)。
|
|
2
|
-
//
|
|
3
|
-
// 为什么要有这一份:arch-guard 的 README 把自己的边界写得很清楚 ——「本工具不是 linter:
|
|
4
|
-
// 单文件语法卫生(any、console、`!important`、颜色字面量、行数上限…)交给 eslint / oxlint /
|
|
5
|
-
// stylelint / knip」。上一期(`./arch.mjs`)把**结构**那半边管住了,语法这半边一条都没有:
|
|
6
|
-
// `as any` 把契约绕过去、`console.log` 留在产物里、渲染期写 ref、漏依赖、内联颜色 ——
|
|
7
|
-
// 这些都不改变文件的形状,S16 / S23 那种判据永远看不见。
|
|
8
|
-
//
|
|
9
|
-
// 为什么方言住 module-tools、而不是让每个模块抄一份配置:与 `moduleArch()` 逐条同一个理由 ——
|
|
10
|
-
// ① 抄一份就会各自漂成十几份"方言";② 方言应当跟**工具链**同代(工坊三个包随外壳同代自愈,
|
|
11
|
-
// 见 ADR-0056),规则变严时用户重跑一次门禁就跟着严,不用重抄。模板里那份 `eslint.config.mjs`
|
|
12
|
-
// 只留一行工厂调用,要改规则就在**这一处**改。
|
|
13
|
-
//
|
|
14
|
-
// 为什么依赖装在 module-tools 一家(eslint / @eslint/js / typescript-eslint / 两个 react 插件):
|
|
15
|
-
// 模块与工坊根的清单**一个字都不用改** —— 这个文件 import 的是 module-tools 自己的依赖,
|
|
16
|
-
// Node 从 module-tools 的位置解析;代价是工坊安装多约 17MB(第一次),换来的是用户拿到
|
|
17
|
-
// `dsh-wb-module lint [--fix]` 就能跑,不必自己装一套 eslint 再跟版本漂移打架。
|
|
18
|
-
//
|
|
19
|
-
// 为什么是这几条规则(逐条的口径都在下面各块的注释里):挑的是"语法级就能判、命中了基本
|
|
20
|
-
// 就是真错"的那批 —— 不做类型感知规则(`no-floating-promises` 那种要建 program,模块 tsconfig
|
|
21
|
-
// 形状各异、慢一个量级;外壳自己那份也把它排到 L2,见 `.scratch/eslint/spec.md`)。
|
|
22
|
-
//
|
|
23
|
-
// 指纹(**逐块比整份方言**,不只是比个名字):本文件导出的 `DIALECT_BLOCKS` 是 `moduleLint()`
|
|
24
|
-
// (不带 options)产出的**全部块**(`@eslint/js/recommended` · 三块 `typescript-eslint/*` ·
|
|
25
|
-
// `dsh-wb/module-lint` 那四块),只排除两块 options 驱动的(`/overrides`、`/root`)。
|
|
26
|
-
// 全局 ignores 那一块单列成 `DIALECT_IGNORES`,按**超集**比(模块可以多忽略,不许少忽略)。
|
|
27
|
-
// 判据(`./checks/lint.mjs`)import 模块那份配置之后**逐块对**:名字 / `files` / `rules` 有一处
|
|
28
|
-
// 不一致就红。这不是风格洁癖:没有它,模块可以把下限悄悄削掉(只留一个同名空块、筛掉基础层)
|
|
29
|
-
// 而门禁照绿 —— 2026-10-19 verifier 先用 `export default [{ name: 'dsh-wb/module-lint',
|
|
30
|
-
// rules: {} }]` 绕过去;随后又量到"只比 `dsh-wb/module-lint*` 那 4 块"还不够:**基础层**
|
|
31
|
-
//(`@eslint/js/recommended` 与三块 `typescript-eslint/*`)与**全局 ignores 块**都不在比对面里。
|
|
32
|
-
// 两者入口不同:前者**有名字**,要筛掉得显式点名(`filter((b) => b.name !== '@eslint/js/recommended')`);
|
|
33
|
-
// 后者是唯一**没有名字**的那块(全局 ignores 不能带 `name`),`filter((b) => b.name !== undefined)`
|
|
34
|
-
// 筛掉的正是它。后果一样(下限被削),所以比对面扩到整份。
|
|
35
|
-
//
|
|
36
|
-
// **残余(这类校验的天花板,文档要如实写)**:模块若自己 import 本方言、再把这几块**照抄**成
|
|
37
|
-
// 一份自己的配置(`moduleLint().map((b) => ({ ...b }))` 这类),判据分不出来 —— 它比的是形状,
|
|
38
|
-
// 不是"这段代码从哪来"。这条的目标是**抬高门槛 + 让改动必须明着写**(改方言那几块会被点名;
|
|
39
|
-
// 开口子只能走 `moduleLint({ rules, ignores })` 或自己追加一块),**不是**防住蓄意伪造。
|
|
40
|
-
|
|
41
1
|
import js from '@eslint/js';
|
|
42
2
|
import react from 'eslint-plugin-react';
|
|
43
3
|
import reactHooks from 'eslint-plugin-react-hooks';
|
|
44
4
|
import tseslint from 'typescript-eslint';
|
|
45
5
|
|
|
46
|
-
/** 方言主块的名字。判据按它认"这一块属于方言";改名字等于改协议。 */
|
|
47
6
|
export const FINGERPRINT = 'dsh-wb/module-lint';
|
|
48
7
|
|
|
49
|
-
// 只有 options 才会变的两块:它们不进"固定的方言"清单(判据不拿它们比 —— 开口子正是改它们)。
|
|
50
8
|
const OPTION_BLOCK_NAMES = new Set([`${FINGERPRINT}/overrides`, `${FINGERPRINT}/root`]);
|
|
51
9
|
|
|
52
|
-
// 全局 ignores 那一块(`{ ignores: [...] }`:没有 `name` / `files` / `rules`)。它**不按形状**比,
|
|
53
|
-
// 单列成下面的 `DIALECT_IGNORES` 按**超集**比 —— 模块多忽略几条可以(那是开口子),少一条不行。
|
|
54
|
-
// 导出它是为了让判据按**同一处**认出这一块,不在判据里另写一份"什么样的块算全局 ignores"。
|
|
55
10
|
export function isGlobalIgnoresBlock(block) {
|
|
56
11
|
return (
|
|
57
12
|
block !== null &&
|
|
@@ -62,7 +17,6 @@ export function isGlobalIgnoresBlock(block) {
|
|
|
62
17
|
);
|
|
63
18
|
}
|
|
64
19
|
|
|
65
|
-
/** 对象/数组递归重建、对象键排序:同一份形状在任何机器上 `JSON.stringify` 都是同一个串。 */
|
|
66
20
|
function sortedDeep(value) {
|
|
67
21
|
if (Array.isArray(value)) return value.map(sortedDeep);
|
|
68
22
|
if (value === null || typeof value !== 'object') return value;
|
|
@@ -73,11 +27,6 @@ function sortedDeep(value) {
|
|
|
73
27
|
);
|
|
74
28
|
}
|
|
75
29
|
|
|
76
|
-
/**
|
|
77
|
-
* 一块方言的**规范形状**(判据逐块比的就是它):名字 + `files`(没有就是 `null`)+ 键排序后的
|
|
78
|
-
* `rules`。只认这三样 —— `plugins` / `settings` / `languageOptions` 是"怎么跑起来"的细节,
|
|
79
|
-
* 掉了它们 ESLint 自己会报错,不必在这里比。
|
|
80
|
-
*/
|
|
81
30
|
export function dialectShapeOf(block) {
|
|
82
31
|
return {
|
|
83
32
|
name: block.name,
|
|
@@ -86,11 +35,6 @@ export function dialectShapeOf(block) {
|
|
|
86
35
|
};
|
|
87
36
|
}
|
|
88
37
|
|
|
89
|
-
// 产物与声明不判:`dist/**` 是 build 出来的,`client.js` 是浏览器面的产物,`*.d.ts` 是声明
|
|
90
|
-
// (`types/styles.d.ts` 那种)。
|
|
91
|
-
//
|
|
92
|
-
// `src/components/vendor/**` 是**唯一**允许 `!important` 的地方 —— 与 arch 方言的
|
|
93
|
-
// `DESIGN.vendorDir` 同一处(`./arch.mjs`):那是"覆盖第三方样式"的那一格,不是我们的代码。
|
|
94
38
|
const DEFAULT_IGNORES = [
|
|
95
39
|
'**/node_modules/**',
|
|
96
40
|
'**/dist/**',
|
|
@@ -100,9 +44,6 @@ const DEFAULT_IGNORES = [
|
|
|
100
44
|
'**/components/vendor/**',
|
|
101
45
|
];
|
|
102
46
|
|
|
103
|
-
// `src/**` 里能一眼看出"手搓外观"的两串字面量。CSS 那一半归 arch-guard 的 D 族
|
|
104
|
-
// (`*.module.css` 已经管着 D09 / D12 / D17),这一半管 **TS 里的内联样式** —— 两条合起来
|
|
105
|
-
// "手搓外观"才闭合:写进 CSS 文件的和写进 style={{}} 的都跑不掉。
|
|
106
47
|
const COLOR_LITERAL = {
|
|
107
48
|
selector:
|
|
108
49
|
'Literal[value=/^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/], Literal[value=/^(?:rgba?|hsla?)\\(/]',
|
|
@@ -112,12 +53,18 @@ const BANG_IMPORTANT = {
|
|
|
112
53
|
selector: 'Literal[value=/!important/]',
|
|
113
54
|
message: '!important:只许在 src/components/vendor/** 里覆盖第三方样式',
|
|
114
55
|
};
|
|
56
|
+
const PLATFORM_READ = {
|
|
57
|
+
selector:
|
|
58
|
+
"MemberExpression[object.name='process'][property.name='platform'], " +
|
|
59
|
+
"MemberExpression[object.object.name='process'][object.property.name='versions'][property.name='electron'], " +
|
|
60
|
+
"MemberExpression[object.name='window'][property.name='dshDesktop'], " +
|
|
61
|
+
"MemberExpression[property.name='hostOs'], " +
|
|
62
|
+
"MemberExpression[object.name='navigator'][property.name='userAgent']",
|
|
63
|
+
message:
|
|
64
|
+
'平台/外壳差异走能力面(HostSurface / ClientSurface):模块源码不直接读 ' +
|
|
65
|
+
'process.platform / versions.electron / dshDesktop / hostOs / navigator.userAgent',
|
|
66
|
+
};
|
|
115
67
|
|
|
116
|
-
// `js.configs.recommended` 的 `no-undef` 在 `.mjs` / `.js` 上是开的(TS 那边 typescript-eslint
|
|
117
|
-
// 把它关了,类型才是那里的真相)。脚本与配置文件要干"算路径、起进程"的活,Node 的全局量得列出来。
|
|
118
|
-
//
|
|
119
|
-
// `URLSearchParams` 那一行是**实测**撞出来的:模板自带的 `scripts/smoke.mjs` 用它拼取数地址,
|
|
120
|
-
// 照抄仓库根那份 globals(没有它)会让模板开箱就两条 `no-undef`。
|
|
121
68
|
const NODE_GLOBALS = {
|
|
122
69
|
Buffer: 'readonly',
|
|
123
70
|
URL: 'readonly',
|
|
@@ -130,12 +77,6 @@ const NODE_GLOBALS = {
|
|
|
130
77
|
clearTimeout: 'readonly',
|
|
131
78
|
};
|
|
132
79
|
|
|
133
|
-
// 非源码那一组(脚本 / 配置)。为什么不判 `console`:`scripts/smoke.mjs` 里那 6 处 `console.log`
|
|
134
|
-
// 是它的**本职工作**(把一次冒烟的结果打给人看)—— 把 `no-console` 加到这一组,模板开箱就红,
|
|
135
|
-
// 而那是误报。所以 `no-console` 只住在下面那个 `src/**` 块里。
|
|
136
|
-
//
|
|
137
|
-
// 这一组是 2026-10-19 拆 selfcheck 时真被两类**静默**错误咬过才补的(标识符少写引号、模板串
|
|
138
|
-
// 写进了普通字符串),与仓库根那份同表;命中基本就是真错,不必跟噪声搏斗。
|
|
139
80
|
const SCRIPT_RULES = {
|
|
140
81
|
'no-template-curly-in-string': 'error',
|
|
141
82
|
'require-atomic-updates': ['error', { allowProperties: true }],
|
|
@@ -154,50 +95,13 @@ const SCRIPT_RULES = {
|
|
|
154
95
|
const SRC_FILES = ['src/**/*.{ts,tsx}'];
|
|
155
96
|
const TSX_FILES = ['**/*.tsx'];
|
|
156
97
|
const TS_FILES = ['**/*.{ts,tsx}'];
|
|
157
|
-
|
|
158
|
-
// 以后可能有的 `*.config.mjs`)一起收进来;`scripts/**` 是模块自己的脚本。
|
|
98
|
+
|
|
159
99
|
const SCRIPT_FILES = ['scripts/**/*.{js,mjs,cjs}', '*.config.{js,mjs,cjs}'];
|
|
160
100
|
|
|
161
|
-
/**
|
|
162
|
-
* 模块包的 eslint 方言。模板里那两行就是默认值:
|
|
163
|
-
*
|
|
164
|
-
* ```js
|
|
165
|
-
* import { moduleLint } from '@dsh-workbench/module-tools/lint';
|
|
166
|
-
* export default moduleLint({ rootDir: import.meta.dirname });
|
|
167
|
-
* ```
|
|
168
|
-
*
|
|
169
|
-
* (为什么模板那份带 `rootDir`、不传行不行:见上面 `rootDir` 那一段 —— 单配置可省,多份并存必需。)
|
|
170
|
-
*
|
|
171
|
-
* 复杂模块要开口子时**从参数进**(每条口子都有名字,评审时看得见),别换掉方言:
|
|
172
|
-
*
|
|
173
|
-
* - `ignores`:追加忽略的 glob(默认那六条见 `DEFAULT_IGNORES`)
|
|
174
|
-
* - `rules`:追加 / 覆盖规则,**最后一块**,所以它对所有文件生效、且压过前面每一块
|
|
175
|
-
* - `rootDir`:这份配置所在的那个目录(模块自己那份配置里写 `import.meta.dirname`)。
|
|
176
|
-
* 为什么要有它:typescript-eslint 的 parser 在**没拿到** `tsconfigRootDir` 时会去猜 —— 猜法是看
|
|
177
|
-
* "现在正在评估哪份 `eslint.config.*`"(V8 调用栈)。一个进程里只有一份配置时它猜得对(用户在
|
|
178
|
-
* 自己模块里 `eslint .` 就是这种情形,所以**不传也能跑**);但只要同时有多份(本仓根上那份
|
|
179
|
-
* + 模块自己那份,ESLint 会按目录就近选一份),它就猜不出来,**每个文件一条解析错**
|
|
180
|
-
* (`No tsconfigRootDir was set, and multiple candidate TSConfigRootDirs are present`,
|
|
181
|
-
* 2026-10-19 整链实测)。模块这份配置声明了自己的根目录,这一条就没了。
|
|
182
|
-
*
|
|
183
|
-
* 要按目录细调(比如"只给 `src/legacy/**` 放行 `no-explicit-any`"),就在自己那份配置里
|
|
184
|
-
* 展开再追一块:
|
|
185
|
-
*
|
|
186
|
-
* ```js
|
|
187
|
-
* export default [
|
|
188
|
-
* ...moduleLint({ rules: { 'no-console': 'off' } }),
|
|
189
|
-
* { files: ['src/legacy/**'], rules: { '@typescript-eslint/no-explicit-any': 'off' } },
|
|
190
|
-
* ];
|
|
191
|
-
* ```
|
|
192
|
-
*
|
|
193
|
-
* @param {{ ignores?: string[], rules?: Record<string, unknown>, rootDir?: string }} [options]
|
|
194
|
-
* @returns {import('eslint').Linter.Config[]} 标准 flat config 数组(编辑器与 eslint 认的就是它)
|
|
195
|
-
*/
|
|
196
101
|
export function moduleLint(options = {}) {
|
|
197
102
|
const { ignores = [], rules = {}, rootDir } = options;
|
|
198
103
|
const overrideRules = Object.keys(rules).length === 0 ? [] : [{ name: 'dsh-wb/module-lint/overrides', rules }];
|
|
199
|
-
|
|
200
|
-
// 猜得对,且不给用户的模块凭空塞一个他不知道的 parserOptions)。
|
|
104
|
+
|
|
201
105
|
const rootBlock =
|
|
202
106
|
rootDir === undefined
|
|
203
107
|
? []
|
|
@@ -209,43 +113,39 @@ export function moduleLint(options = {}) {
|
|
|
209
113
|
];
|
|
210
114
|
|
|
211
115
|
return [
|
|
212
|
-
|
|
116
|
+
|
|
213
117
|
{ ignores: [...DEFAULT_IGNORES, ...ignores] },
|
|
214
118
|
...rootBlock,
|
|
215
|
-
|
|
119
|
+
|
|
216
120
|
js.configs.recommended,
|
|
217
|
-
|
|
218
|
-
// (不建 program),所以它不属于"被推迟的类型感知规则"。
|
|
121
|
+
|
|
219
122
|
...tseslint.configs.recommended,
|
|
220
123
|
{
|
|
221
124
|
name: FINGERPRINT,
|
|
222
125
|
files: SRC_FILES,
|
|
223
126
|
rules: {
|
|
224
|
-
|
|
127
|
+
|
|
225
128
|
'no-empty': ['error', { allowEmptyCatch: true }],
|
|
226
129
|
'prefer-const': 'error',
|
|
227
|
-
|
|
130
|
+
|
|
228
131
|
'@typescript-eslint/no-explicit-any': 'error',
|
|
229
|
-
|
|
132
|
+
|
|
230
133
|
'@typescript-eslint/no-unused-vars': [
|
|
231
134
|
'error',
|
|
232
135
|
{ args: 'after-used', argsIgnorePattern: '^_', caughtErrors: 'none', ignoreRestSiblings: true },
|
|
233
136
|
],
|
|
234
|
-
|
|
235
|
-
// 调试残留(`log` / `info` / `debug`)不许留。
|
|
137
|
+
|
|
236
138
|
'no-console': ['error', { allow: ['warn', 'error'] }],
|
|
237
139
|
'no-debugger': 'error',
|
|
238
|
-
|
|
239
|
-
'no-restricted-syntax': ['error', COLOR_LITERAL, BANG_IMPORTANT],
|
|
140
|
+
|
|
141
|
+
'no-restricted-syntax': ['error', COLOR_LITERAL, BANG_IMPORTANT, PLATFORM_READ],
|
|
240
142
|
},
|
|
241
143
|
},
|
|
242
144
|
{
|
|
243
145
|
name: 'dsh-wb/module-lint/react',
|
|
244
146
|
files: TSX_FILES,
|
|
245
147
|
plugins: { react },
|
|
246
|
-
|
|
247
|
-
// 这类规则照样咬得住手写的 `h()`。版本写死而不是 `detect`:`detect` 要读文件系统、
|
|
248
|
-
// 还会打一句警告,而模块拿到的 react 是外壳经模块表给的那一份(与外壳同代)。
|
|
148
|
+
|
|
249
149
|
settings: { react: { version: '19.3.0', pragma: 'h', fragment: 'Fragment' } },
|
|
250
150
|
rules: {
|
|
251
151
|
'react/jsx-key': 'error',
|
|
@@ -263,9 +163,7 @@ export function moduleLint(options = {}) {
|
|
|
263
163
|
files: TS_FILES,
|
|
264
164
|
plugins: { 'react-hooks': reactHooks },
|
|
265
165
|
rules: {
|
|
266
|
-
|
|
267
|
-
// 漏订阅、依赖写错)就是没有 lint 造成的。recommended 全量先按 **warn** 收进来(新规则
|
|
268
|
-
// 先看一段时间,不挡门禁),四条已知会真炸的提到 **error**。
|
|
166
|
+
|
|
269
167
|
...Object.fromEntries(Object.keys(reactHooks.configs.recommended.rules).map((rule) => [rule, 'warn'])),
|
|
270
168
|
'react-hooks/rules-of-hooks': 'error',
|
|
271
169
|
'react-hooks/refs': 'error',
|
|
@@ -283,27 +181,9 @@ export function moduleLint(options = {}) {
|
|
|
283
181
|
];
|
|
284
182
|
}
|
|
285
183
|
|
|
286
|
-
/**
|
|
287
|
-
* `moduleLint()`(不带 options)产出的**整份方言**的规范形状 —— 判据拿它**逐块比**。
|
|
288
|
-
*
|
|
289
|
-
* 比对面(2026-10-19 扩过一次,是个行为变更):**全部块**,只排除两块 options 驱动的
|
|
290
|
-
* (`/overrides`、`/root`);全局 ignores 那一块也不在这里(它没有 `name` / `files` / `rules`,
|
|
291
|
-
* 形状比不了),单列成下面的 `DIALECT_IGNORES` 按**超集**比。也就是说现在这些块也必须在:
|
|
292
|
-
* `@eslint/js/recommended` · `typescript-eslint/base` · `typescript-eslint/eslint-recommended` ·
|
|
293
|
-
* `typescript-eslint/recommended`,以及 `dsh-wb/module-lint` 那四块 —— 一共 8 块。
|
|
294
|
-
*
|
|
295
|
-
* 为什么算一次就够:方言只有这一份,`moduleLint()` 不带 options 时产出是确定的(同一套常量、
|
|
296
|
-
* 同一个 `tseslint.configs.recommended`),所以"该长什么样"可以在导入时钉死,判据不必自己
|
|
297
|
-
* 再拼一遍。放在文件**最尾**:`moduleLint()` 读的是上面那批模块级常量,早算会撞 TDZ。
|
|
298
|
-
*/
|
|
299
184
|
export const DIALECT_BLOCKS = moduleLint()
|
|
300
185
|
.filter((block) => !isGlobalIgnoresBlock(block))
|
|
301
186
|
.filter((block) => !(typeof block?.name === 'string' && OPTION_BLOCK_NAMES.has(block.name)))
|
|
302
187
|
.map(dialectShapeOf);
|
|
303
188
|
|
|
304
|
-
/**
|
|
305
|
-
* 全局 ignores 的默认那几条("一条都不许少"的那半)。判据按**超集**比:模块可以再多忽略几条
|
|
306
|
-
* (那是 `moduleLint({ ignores })` 这个命名口子),但少一条就点名缺哪条。
|
|
307
|
-
*/
|
|
308
189
|
export const DIALECT_IGNORES = [...DEFAULT_IGNORES];
|
|
309
|
-
|