@webmate-studio/builder 0.2.127 → 0.2.130
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.js +63 -1
package/package.json
CHANGED
package/src/bundler.js
CHANGED
|
@@ -41,12 +41,65 @@ export async function bundleIsland(islandPath, outputPath, options = {}) {
|
|
|
41
41
|
// NEW: Component-specific node_modules (highest priority)
|
|
42
42
|
const componentNodeModules = componentDir ? path.join(componentDir, 'node_modules') : null;
|
|
43
43
|
|
|
44
|
+
// Check if island source already registers as Custom Element
|
|
45
|
+
// If not (plain class export), create a wrapper entry that auto-registers it
|
|
46
|
+
let entryPoint = islandPath;
|
|
47
|
+
let wrapperPath = null;
|
|
48
|
+
|
|
49
|
+
const isSvelte = islandPath.endsWith('.svelte');
|
|
50
|
+
if (!isSvelte) {
|
|
51
|
+
const sourceCode = await fs.readFile(islandPath, 'utf-8');
|
|
52
|
+
if (!sourceCode.includes('customElements.define')) {
|
|
53
|
+
// Derive tag name from filename: NewsSlider.js → news-slider
|
|
54
|
+
const baseName = path.basename(islandPath).replace(/\.(js|jsx|ts|tsx|vue)$/, '');
|
|
55
|
+
const tagName = baseName
|
|
56
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
57
|
+
.toLowerCase();
|
|
58
|
+
|
|
59
|
+
// Create temporary wrapper entry file
|
|
60
|
+
wrapperPath = islandPath.replace(/\.(js|jsx|ts|tsx|vue)$/, '.__wm-wrapper.js');
|
|
61
|
+
const wrapperCode = `
|
|
62
|
+
import IslandClass from './${path.basename(islandPath)}';
|
|
63
|
+
|
|
64
|
+
class WmIsland extends HTMLElement {
|
|
65
|
+
connectedCallback() {
|
|
66
|
+
let props = {};
|
|
67
|
+
const propsJson = this.getAttribute('data-island-props');
|
|
68
|
+
if (propsJson) {
|
|
69
|
+
try { props = JSON.parse(propsJson); } catch {}
|
|
70
|
+
} else {
|
|
71
|
+
for (const attr of this.attributes) {
|
|
72
|
+
if (attr.name === 'data-island-props') continue;
|
|
73
|
+
try { props[attr.name] = JSON.parse(attr.value); }
|
|
74
|
+
catch { props[attr.name] = attr.value; }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
this._instance = new IslandClass(this, props);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error('[Island] Failed to initialize <${tagName}>:', err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
disconnectedCallback() {
|
|
84
|
+
if (this._instance && typeof this._instance.destroy === 'function') {
|
|
85
|
+
this._instance.destroy();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
customElements.define('${tagName}', WmIsland);
|
|
90
|
+
`;
|
|
91
|
+
await fs.writeFile(wrapperPath, wrapperCode, 'utf-8');
|
|
92
|
+
entryPoint = wrapperPath;
|
|
93
|
+
console.log(pc.dim(` ↳ Wrapping ${baseName} as Custom Element <${tagName}>`));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
44
97
|
// Determine if this file should use JSX loader
|
|
45
98
|
// Only use JSX for .jsx files (React/Preact), not for .js files (Lit/Alpine/Vue/Vanilla)
|
|
46
99
|
const useJsxLoader = islandPath.endsWith('.jsx');
|
|
47
100
|
|
|
48
101
|
const result = await esbuild.build({
|
|
49
|
-
entryPoints: [
|
|
102
|
+
entryPoints: [entryPoint],
|
|
50
103
|
bundle: true,
|
|
51
104
|
minify,
|
|
52
105
|
sourcemap,
|
|
@@ -175,6 +228,11 @@ export async function bundleIsland(islandPath, outputPath, options = {}) {
|
|
|
175
228
|
logLevel: 'warning'
|
|
176
229
|
});
|
|
177
230
|
|
|
231
|
+
// Clean up temporary wrapper file
|
|
232
|
+
if (wrapperPath) {
|
|
233
|
+
await fs.unlink(wrapperPath).catch(() => {});
|
|
234
|
+
}
|
|
235
|
+
|
|
178
236
|
return {
|
|
179
237
|
success: true,
|
|
180
238
|
outputPath,
|
|
@@ -182,6 +240,10 @@ export async function bundleIsland(islandPath, outputPath, options = {}) {
|
|
|
182
240
|
warnings: result.warnings
|
|
183
241
|
};
|
|
184
242
|
} catch (error) {
|
|
243
|
+
// Clean up temporary wrapper file on error
|
|
244
|
+
if (wrapperPath) {
|
|
245
|
+
await fs.unlink(wrapperPath).catch(() => {});
|
|
246
|
+
}
|
|
185
247
|
return {
|
|
186
248
|
success: false,
|
|
187
249
|
error: error.message,
|