@webmate-studio/builder 0.2.76 → 0.2.77
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/build-service.js +37 -2
- package/package.json +1 -1
package/build-service.js
CHANGED
|
@@ -168,6 +168,20 @@ async function buildComponent(payload) {
|
|
|
168
168
|
console.log(`[Build Service] Wrote ${assets.length} asset(s)`);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
// Detect which islands are actually used in component.html (top-level islands)
|
|
172
|
+
// These become Custom Elements, others are just utilities/sub-components
|
|
173
|
+
const usedIslands = new Set();
|
|
174
|
+
if (html) {
|
|
175
|
+
// Find all custom elements in HTML (e.g. <MenuMobile />, <SearchModal />)
|
|
176
|
+
// Match: <ComponentName or <ComponentName> or <ComponentName/>
|
|
177
|
+
const componentTagRegex = /<([A-Z][a-zA-Z0-9]*)\s*\/?>/g;
|
|
178
|
+
let match;
|
|
179
|
+
while ((match = componentTagRegex.exec(html)) !== null) {
|
|
180
|
+
const componentName = match[1]; // e.g. "MenuMobile"
|
|
181
|
+
usedIslands.add(componentName);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
171
185
|
// Build islands
|
|
172
186
|
const bundledIslands = [];
|
|
173
187
|
if (islands && islands.length > 0) {
|
|
@@ -189,12 +203,29 @@ async function buildComponent(payload) {
|
|
|
189
203
|
await writeFile(inputPath, content);
|
|
190
204
|
}
|
|
191
205
|
|
|
192
|
-
// SECOND: Bundle
|
|
206
|
+
// SECOND: Bundle only top-level islands (those used in component.html)
|
|
207
|
+
// Others are utilities/sub-components that get bundled via imports
|
|
193
208
|
for (const island of islands) {
|
|
209
|
+
// Extract component name from filename (e.g. "MenuMobile.svelte" → "MenuMobile")
|
|
210
|
+
const componentName = island.file.replace(/\.(jsx?|tsx?|svelte|vue)$/, '');
|
|
211
|
+
const isTopLevel = usedIslands.has(componentName);
|
|
212
|
+
|
|
213
|
+
// Skip non-component files (e.g. .js utilities that aren't top-level islands)
|
|
214
|
+
if (!island.file.match(/\.(jsx?|tsx?|svelte|vue)$/)) {
|
|
215
|
+
console.log(`[Build Service] Skipping ${island.file} (utility file, not an island)`);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Only bundle top-level islands (those referenced in HTML)
|
|
220
|
+
if (!isTopLevel) {
|
|
221
|
+
console.log(`[Build Service] Skipping ${island.file} (sub-component, will be bundled via import)`);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
194
225
|
const inputPath = join(islandsDir, island.file);
|
|
195
226
|
const outputPath = join(islandsDir, island.file.replace(/\.(jsx?|tsx?|svelte|vue)$/, '.js'));
|
|
196
227
|
|
|
197
|
-
console.log(`[Build Service] Bundling ${island.file}...`);
|
|
228
|
+
console.log(`[Build Service] Bundling ${island.file} (top-level island)...`);
|
|
198
229
|
|
|
199
230
|
// Bundle with esbuild (pass tmpDir for node_modules resolution)
|
|
200
231
|
const result = await bundleIsland(inputPath, outputPath, {
|
|
@@ -222,6 +253,10 @@ async function buildComponent(payload) {
|
|
|
222
253
|
|
|
223
254
|
console.log(`[Build Service] ✓ ${island.file} → ${outputFilename} (${(result.size / 1024).toFixed(2)}kb)`);
|
|
224
255
|
}
|
|
256
|
+
|
|
257
|
+
if (usedIslands.size > 0) {
|
|
258
|
+
console.log(`[Build Service] Detected ${usedIslands.size} top-level island(s): ${Array.from(usedIslands).join(', ')}`);
|
|
259
|
+
}
|
|
225
260
|
}
|
|
226
261
|
|
|
227
262
|
// Transform HTML: Convert <IslandName /> to <island-name> Custom Elements
|