@mandujs/core 0.9.29 → 0.9.31
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/package.json +1 -1
- package/src/bundler/dev.ts +112 -1
package/package.json
CHANGED
package/src/bundler/dev.ts
CHANGED
|
@@ -18,6 +18,17 @@ export interface DevBundlerOptions {
|
|
|
18
18
|
onRebuild?: (result: RebuildResult) => void;
|
|
19
19
|
/** 에러 콜백 */
|
|
20
20
|
onError?: (error: Error, routeId?: string) => void;
|
|
21
|
+
/**
|
|
22
|
+
* 추가 watch 디렉토리 (공통 컴포넌트 등)
|
|
23
|
+
* 상대 경로 또는 절대 경로 모두 지원
|
|
24
|
+
* 기본값: ["src/components", "components", "src/shared", "shared", "src/lib", "lib", "src/hooks", "hooks", "src/utils", "utils"]
|
|
25
|
+
*/
|
|
26
|
+
watchDirs?: string[];
|
|
27
|
+
/**
|
|
28
|
+
* 기본 watch 디렉토리 비활성화
|
|
29
|
+
* true로 설정하면 watchDirs만 감시
|
|
30
|
+
*/
|
|
31
|
+
disableDefaultWatchDirs?: boolean;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
export interface RebuildResult {
|
|
@@ -34,12 +45,33 @@ export interface DevBundler {
|
|
|
34
45
|
close: () => void;
|
|
35
46
|
}
|
|
36
47
|
|
|
48
|
+
// 기본 공통 컴포넌트 디렉토리 목록
|
|
49
|
+
const DEFAULT_COMMON_DIRS = [
|
|
50
|
+
"src/components",
|
|
51
|
+
"components",
|
|
52
|
+
"src/shared",
|
|
53
|
+
"shared",
|
|
54
|
+
"src/lib",
|
|
55
|
+
"lib",
|
|
56
|
+
"src/hooks",
|
|
57
|
+
"hooks",
|
|
58
|
+
"src/utils",
|
|
59
|
+
"utils",
|
|
60
|
+
];
|
|
61
|
+
|
|
37
62
|
/**
|
|
38
63
|
* 개발 모드 번들러 시작
|
|
39
64
|
* 파일 변경 감시 및 자동 재빌드
|
|
40
65
|
*/
|
|
41
66
|
export async function startDevBundler(options: DevBundlerOptions): Promise<DevBundler> {
|
|
42
|
-
const {
|
|
67
|
+
const {
|
|
68
|
+
rootDir,
|
|
69
|
+
manifest,
|
|
70
|
+
onRebuild,
|
|
71
|
+
onError,
|
|
72
|
+
watchDirs: customWatchDirs = [],
|
|
73
|
+
disableDefaultWatchDirs = false,
|
|
74
|
+
} = options;
|
|
43
75
|
|
|
44
76
|
// 초기 빌드
|
|
45
77
|
console.log("🔨 Initial client bundle build...");
|
|
@@ -57,6 +89,7 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
57
89
|
// clientModule 경로에서 routeId 매핑 생성
|
|
58
90
|
const clientModuleToRoute = new Map<string, string>();
|
|
59
91
|
const watchDirs = new Set<string>();
|
|
92
|
+
const commonWatchDirs = new Set<string>(); // 공통 디렉토리 (전체 재빌드 트리거)
|
|
60
93
|
|
|
61
94
|
for (const route of manifest.routes) {
|
|
62
95
|
if (route.clientModule) {
|
|
@@ -79,13 +112,85 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
79
112
|
// slots 디렉토리 없으면 무시
|
|
80
113
|
}
|
|
81
114
|
|
|
115
|
+
// 공통 컴포넌트 디렉토리 추가 (기본 + 커스텀)
|
|
116
|
+
const commonDirsToCheck = disableDefaultWatchDirs
|
|
117
|
+
? customWatchDirs
|
|
118
|
+
: [...DEFAULT_COMMON_DIRS, ...customWatchDirs];
|
|
119
|
+
|
|
120
|
+
const addCommonDir = async (dir: string): Promise<void> => {
|
|
121
|
+
const absPath = path.isAbsolute(dir) ? dir : path.join(rootDir, dir);
|
|
122
|
+
try {
|
|
123
|
+
const stat = await fs.promises.stat(absPath);
|
|
124
|
+
const watchPath = stat.isDirectory() ? absPath : path.dirname(absPath);
|
|
125
|
+
await fs.promises.access(watchPath);
|
|
126
|
+
commonWatchDirs.add(watchPath);
|
|
127
|
+
watchDirs.add(watchPath);
|
|
128
|
+
} catch {
|
|
129
|
+
// 디렉토리 없으면 무시
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
for (const dir of commonDirsToCheck) {
|
|
134
|
+
await addCommonDir(dir);
|
|
135
|
+
}
|
|
136
|
+
|
|
82
137
|
// 파일 감시 설정
|
|
83
138
|
const watchers: fs.FSWatcher[] = [];
|
|
84
139
|
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
85
140
|
|
|
141
|
+
// 파일이 공통 디렉토리에 있는지 확인
|
|
142
|
+
const isInCommonDir = (filePath: string): boolean => {
|
|
143
|
+
const normalizedFile = path.resolve(filePath).replace(/\\/g, "/");
|
|
144
|
+
for (const commonDir of commonWatchDirs) {
|
|
145
|
+
const normalizedCommon = path.resolve(commonDir).replace(/\\/g, "/");
|
|
146
|
+
if (normalizedFile.startsWith(normalizedCommon + "/")) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
};
|
|
152
|
+
|
|
86
153
|
const handleFileChange = async (changedFile: string) => {
|
|
87
154
|
const normalizedPath = changedFile.replace(/\\/g, "/");
|
|
88
155
|
|
|
156
|
+
// 공통 컴포넌트 디렉토리 변경 → 전체 재빌드
|
|
157
|
+
if (isInCommonDir(changedFile)) {
|
|
158
|
+
console.log(`\n🔄 Common file changed: ${path.basename(changedFile)}`);
|
|
159
|
+
console.log(` Rebuilding all islands...`);
|
|
160
|
+
const startTime = performance.now();
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
const result = await buildClientBundles(manifest, rootDir, {
|
|
164
|
+
minify: false,
|
|
165
|
+
sourcemap: true,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const buildTime = performance.now() - startTime;
|
|
169
|
+
|
|
170
|
+
if (result.success) {
|
|
171
|
+
console.log(`✅ Rebuilt ${result.stats.bundleCount} islands in ${buildTime.toFixed(0)}ms`);
|
|
172
|
+
onRebuild?.({
|
|
173
|
+
routeId: "*", // 전체 재빌드 표시
|
|
174
|
+
success: true,
|
|
175
|
+
buildTime,
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
console.error(`❌ Build failed:`, result.errors);
|
|
179
|
+
onRebuild?.({
|
|
180
|
+
routeId: "*",
|
|
181
|
+
success: false,
|
|
182
|
+
buildTime,
|
|
183
|
+
error: result.errors.join(", "),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
188
|
+
console.error(`❌ Build error:`, err.message);
|
|
189
|
+
onError?.(err, "*");
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
89
194
|
// clientModule 매핑에서 routeId 찾기
|
|
90
195
|
let routeId = clientModuleToRoute.get(normalizedPath);
|
|
91
196
|
|
|
@@ -173,6 +278,12 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
173
278
|
|
|
174
279
|
if (watchers.length > 0) {
|
|
175
280
|
console.log(`👀 Watching ${watchers.length} directories for changes...`);
|
|
281
|
+
if (commonWatchDirs.size > 0) {
|
|
282
|
+
const commonDirNames = Array.from(commonWatchDirs)
|
|
283
|
+
.map(d => path.relative(rootDir, d) || ".")
|
|
284
|
+
.join(", ");
|
|
285
|
+
console.log(`📦 Common dirs (full rebuild): ${commonDirNames}`);
|
|
286
|
+
}
|
|
176
287
|
}
|
|
177
288
|
|
|
178
289
|
return {
|