Commit eb4d01c6 by luoqi

fix(build): .swcrc 的 exclude 是正则,必须锚定

跟刚 revert 的 hover 改动无关,单独留下 —— 这是个静默的构建坑,任何人加文件都可能撞上。

原写 ["node_modules", "dist"],看着像目录名,swc 实际当**正则**匹配整个文件路径。
于是文件名里含 "dist" 的源文件被直接跳过:271 个源文件只编译出 270 个,swc 不报错
(照样打印 "Successfully compiled: 270 files"),直到进程启动才 MODULE_NOT_FOUND。
同类地雷:distinct / distance / district / redistribute…

更难查的是两边表现不一致 —— 只在 swc 路径(dev / --builder swc)复现,
nest build 走 tsc 一切正常。

锚定成 ["^node_modules/", "^dist/"],并加断言:exclude 必须以 ^ 开头,
且遍历 src 下全部 .ts 确认一个都没被误伤。

456 tests green。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
parent 0eddcffa
...@@ -21,5 +21,5 @@ ...@@ -21,5 +21,5 @@
"module": { "module": {
"type": "commonjs" "type": "commonjs"
}, },
"exclude": ["node_modules", "dist"] "exclude": ["^node_modules/", "^dist/"]
} }
import { readdirSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
/**
* `.swcrc` 的 exclude 必须是**锚定**正则。
*
* 踩过的坑:原本写成 `["node_modules", "dist"]`,看着像目录名,实际 swc 当**正则**去匹配
* 整个文件路径 —— 于是新加的 `priority-distribution.service.ts` 因为文件名里含 "dist"
* 被静默跳过。271 个源文件只编译出 270 个,swc **不报任何错**
* ("Successfully compiled: 270 files"),直到进程启动才
* `Cannot find module './priority-distribution.service'`。
*
* 同类地雷:任何文件名撞上 dist / node_modules 子串的都会中招(distinct、distance、
* district、redistribute…)。而且只在 swc 构建路径(dev / `--builder swc`)复现,
* `nest build` 走 tsc 一切正常 —— 两边表现不一致,极难排查。
*/
describe('.swcrc exclude 必须锚定', () => {
const root = join(__dirname, '..');
const swcrc = JSON.parse(readFileSync(join(root, '.swcrc'), 'utf8')) as { exclude?: string[] };
const patterns = (swcrc.exclude ?? []).map((p) => new RegExp(p));
test('⭐ 每条 exclude 都以 ^ 开头(否则会误伤文件名含该子串的源文件)', () => {
const unanchored = (swcrc.exclude ?? []).filter((p) => !p.startsWith('^'));
expect(unanchored).toEqual([]);
});
test('⭐ 现有源文件一个都不会被 exclude 误伤', () => {
const files: string[] = [];
const walk = (rel: string) => {
for (const e of readdirSync(join(root, rel), { withFileTypes: true })) {
const p = `${rel}/${e.name}`;
if (e.isDirectory()) walk(p);
else if (e.name.endsWith('.ts')) files.push(p);
}
};
walk('src');
const hit = files.filter((f) => patterns.some((re) => re.test(f)));
expect(hit).toEqual([]);
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment