@cloudwerk/vite-plugin 0.7.0 → 0.8.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/dist/index.d.ts +2 -0
- package/dist/index.js +186 -72
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -95,6 +95,8 @@ interface ClientComponentInfo {
|
|
|
95
95
|
bundlePath: string;
|
|
96
96
|
/** Absolute file path */
|
|
97
97
|
absolutePath: string;
|
|
98
|
+
/** Named export name (undefined means default export) */
|
|
99
|
+
exportName?: string;
|
|
98
100
|
}
|
|
99
101
|
/**
|
|
100
102
|
* Information about a CSS import detected in a layout or page.
|
package/dist/index.js
CHANGED
|
@@ -1101,9 +1101,12 @@ function generateClientEntry(clientComponents, cssImports, options, manifest) {
|
|
|
1101
1101
|
}
|
|
1102
1102
|
function generateStaticImportsAndMap(clientComponents) {
|
|
1103
1103
|
const components = Array.from(clientComponents.values());
|
|
1104
|
-
const imports = components.map(
|
|
1105
|
-
(info
|
|
1106
|
-
|
|
1104
|
+
const imports = components.map((info, index) => {
|
|
1105
|
+
if (info.exportName) {
|
|
1106
|
+
return `import { ${info.exportName} as Component${index} } from '${info.absolutePath}'`;
|
|
1107
|
+
}
|
|
1108
|
+
return `import Component${index} from '${info.absolutePath}'`;
|
|
1109
|
+
}).join("\n");
|
|
1107
1110
|
const componentMapEntries = components.map(
|
|
1108
1111
|
(info, index) => ` '${info.componentId}': Component${index}`
|
|
1109
1112
|
).join(",\n");
|
|
@@ -1195,7 +1198,10 @@ import { jsx } from 'hono/jsx/jsx-runtime'`,
|
|
|
1195
1198
|
});
|
|
1196
1199
|
}
|
|
1197
1200
|
const bundleMap = Object.fromEntries(
|
|
1198
|
-
Array.from(clientComponents.values()).map((info) => [
|
|
1201
|
+
Array.from(clientComponents.values()).map((info) => [
|
|
1202
|
+
info.componentId,
|
|
1203
|
+
{ path: `/@fs${info.absolutePath}`, exportName: info.exportName ?? null }
|
|
1204
|
+
])
|
|
1199
1205
|
);
|
|
1200
1206
|
return `/**
|
|
1201
1207
|
* Generated Cloudwerk Client Entry (Hono JSX)
|
|
@@ -1244,19 +1250,19 @@ async function hydrate() {
|
|
|
1244
1250
|
continue
|
|
1245
1251
|
}
|
|
1246
1252
|
|
|
1247
|
-
const
|
|
1248
|
-
if (!
|
|
1253
|
+
const bundle = bundles[componentId]
|
|
1254
|
+
if (!bundle) {
|
|
1249
1255
|
console.warn('[Cloudwerk] Unknown client component:', componentId)
|
|
1250
1256
|
continue
|
|
1251
1257
|
}
|
|
1252
1258
|
|
|
1253
1259
|
try {
|
|
1254
1260
|
const props = propsJson ? JSON.parse(propsJson) : {}
|
|
1255
|
-
const module = await loadComponent(
|
|
1256
|
-
const Component = module.default
|
|
1261
|
+
const module = await loadComponent(bundle.path)
|
|
1262
|
+
const Component = bundle.exportName ? module[bundle.exportName] : module.default
|
|
1257
1263
|
|
|
1258
1264
|
if (!Component) {
|
|
1259
|
-
console.error('[Cloudwerk] No
|
|
1265
|
+
console.error('[Cloudwerk] No export found in component:', componentId)
|
|
1260
1266
|
continue
|
|
1261
1267
|
}
|
|
1262
1268
|
|
|
@@ -1472,6 +1478,57 @@ function findDefaultExport(ast) {
|
|
|
1472
1478
|
}
|
|
1473
1479
|
return { type: null, name: null, index: -1 };
|
|
1474
1480
|
}
|
|
1481
|
+
function findNamedExports(ast) {
|
|
1482
|
+
const results = [];
|
|
1483
|
+
for (let i = 0; i < ast.body.length; i++) {
|
|
1484
|
+
const node = ast.body[i];
|
|
1485
|
+
if (node.type === "ExportDeclaration") {
|
|
1486
|
+
const decl = node.declaration;
|
|
1487
|
+
if (decl.type === "FunctionDeclaration" && decl.identifier) {
|
|
1488
|
+
const name = decl.identifier.value;
|
|
1489
|
+
if (/^[A-Z]/.test(name)) {
|
|
1490
|
+
results.push({
|
|
1491
|
+
name,
|
|
1492
|
+
type: "function",
|
|
1493
|
+
index: i,
|
|
1494
|
+
spanStart: node.span.start,
|
|
1495
|
+
spanEnd: node.span.end,
|
|
1496
|
+
isAsync: decl.async
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
if (decl.type === "ClassDeclaration" && decl.identifier) {
|
|
1501
|
+
const name = decl.identifier.value;
|
|
1502
|
+
if (/^[A-Z]/.test(name)) {
|
|
1503
|
+
results.push({
|
|
1504
|
+
name,
|
|
1505
|
+
type: "class",
|
|
1506
|
+
index: i,
|
|
1507
|
+
spanStart: node.span.start,
|
|
1508
|
+
spanEnd: node.span.end
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
if (decl.type === "VariableDeclaration") {
|
|
1513
|
+
for (const declarator of decl.declarations) {
|
|
1514
|
+
if (declarator.id.type === "Identifier") {
|
|
1515
|
+
const name = declarator.id.value;
|
|
1516
|
+
if (/^[A-Z]/.test(name)) {
|
|
1517
|
+
results.push({
|
|
1518
|
+
name,
|
|
1519
|
+
type: "const",
|
|
1520
|
+
index: i,
|
|
1521
|
+
spanStart: node.span.start,
|
|
1522
|
+
spanEnd: node.span.end
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
return results;
|
|
1531
|
+
}
|
|
1475
1532
|
function transformClientComponent(code, options) {
|
|
1476
1533
|
const { componentId, bundlePath } = options;
|
|
1477
1534
|
try {
|
|
@@ -1481,7 +1538,8 @@ function transformClientComponent(code, options) {
|
|
|
1481
1538
|
comments: true
|
|
1482
1539
|
});
|
|
1483
1540
|
const exportInfo = findDefaultExport(ast);
|
|
1484
|
-
|
|
1541
|
+
const namedExports = findNamedExports(ast);
|
|
1542
|
+
if (exportInfo.type === null && namedExports.length === 0) {
|
|
1485
1543
|
return {
|
|
1486
1544
|
code,
|
|
1487
1545
|
success: false,
|
|
@@ -1492,97 +1550,134 @@ function transformClientComponent(code, options) {
|
|
|
1492
1550
|
const wrapperImport = `import { createClientComponentWrapper as __createWrapper } from '@cloudwerk/ui/client'
|
|
1493
1551
|
`;
|
|
1494
1552
|
const metaObj = JSON.stringify({ componentId, bundlePath });
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1553
|
+
const wrappedExports = [];
|
|
1554
|
+
if (namedExports.length > 0) {
|
|
1555
|
+
const sorted = [...namedExports].sort((a, b) => b.spanStart - a.spanStart);
|
|
1556
|
+
for (const namedExport of sorted) {
|
|
1557
|
+
const namedMetaObj = JSON.stringify({
|
|
1558
|
+
componentId: `${componentId}__${namedExport.name}`,
|
|
1559
|
+
bundlePath
|
|
1560
|
+
});
|
|
1561
|
+
const originalName = `__${namedExport.name}_original`;
|
|
1562
|
+
switch (namedExport.type) {
|
|
1563
|
+
case "function": {
|
|
1564
|
+
const asyncPrefix = namedExport.isAsync ? "async " : "";
|
|
1565
|
+
transformed = transformed.replace(
|
|
1566
|
+
new RegExp(`export\\s+${asyncPrefix}function\\s+${namedExport.name}\\s*\\(`),
|
|
1567
|
+
`${asyncPrefix}function ${originalName}(`
|
|
1568
|
+
);
|
|
1569
|
+
break;
|
|
1570
|
+
}
|
|
1571
|
+
case "class": {
|
|
1572
|
+
transformed = transformed.replace(
|
|
1573
|
+
new RegExp(`export\\s+class\\s+${namedExport.name}\\s`),
|
|
1574
|
+
`class ${originalName} `
|
|
1575
|
+
);
|
|
1576
|
+
break;
|
|
1577
|
+
}
|
|
1578
|
+
case "const": {
|
|
1579
|
+
transformed = transformed.replace(
|
|
1580
|
+
new RegExp(`export\\s+(const|let|var)\\s+${namedExport.name}\\s*=`),
|
|
1581
|
+
`const ${originalName} =`
|
|
1582
|
+
);
|
|
1583
|
+
break;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
transformed += `
|
|
1587
|
+
export const ${namedExport.name} = __createWrapper(${originalName}, ${namedMetaObj})
|
|
1588
|
+
`;
|
|
1589
|
+
wrappedExports.push(namedExport.name);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
if (exportInfo.type !== null) {
|
|
1593
|
+
switch (exportInfo.type) {
|
|
1594
|
+
case "function": {
|
|
1595
|
+
if (exportInfo.name) {
|
|
1596
|
+
const asyncPrefix = exportInfo.isAsync ? "async " : "";
|
|
1597
|
+
transformed = transformed.replace(
|
|
1598
|
+
new RegExp(`export\\s+default\\s+${asyncPrefix}function\\s+${exportInfo.name}`),
|
|
1599
|
+
`${asyncPrefix}function ${exportInfo.name}`
|
|
1600
|
+
);
|
|
1601
|
+
transformed += `
|
|
1505
1602
|
const __WrappedComponent = __createWrapper(${exportInfo.name}, ${metaObj})
|
|
1506
1603
|
export default __WrappedComponent
|
|
1507
1604
|
`;
|
|
1508
|
-
|
|
1509
|
-
|
|
1605
|
+
} else {
|
|
1606
|
+
const asyncPrefix = exportInfo.isAsync ? "async " : "";
|
|
1607
|
+
transformed = transformed.replace(
|
|
1608
|
+
new RegExp(`export\\s+default\\s+${asyncPrefix}function\\s*\\(`),
|
|
1609
|
+
`const __OriginalComponent = ${asyncPrefix}function(`
|
|
1610
|
+
);
|
|
1611
|
+
transformed += `
|
|
1612
|
+
const __WrappedComponent = __createWrapper(__OriginalComponent, ${metaObj})
|
|
1613
|
+
export default __WrappedComponent
|
|
1614
|
+
`;
|
|
1615
|
+
}
|
|
1616
|
+
break;
|
|
1617
|
+
}
|
|
1618
|
+
case "arrow": {
|
|
1510
1619
|
transformed = transformed.replace(
|
|
1511
|
-
|
|
1512
|
-
|
|
1620
|
+
/export\s+default/,
|
|
1621
|
+
"const __OriginalComponent ="
|
|
1513
1622
|
);
|
|
1514
|
-
transformed = wrapperImport + transformed;
|
|
1515
1623
|
transformed += `
|
|
1516
1624
|
const __WrappedComponent = __createWrapper(__OriginalComponent, ${metaObj})
|
|
1517
1625
|
export default __WrappedComponent
|
|
1518
1626
|
`;
|
|
1627
|
+
break;
|
|
1519
1628
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1629
|
+
case "class": {
|
|
1630
|
+
if (exportInfo.name) {
|
|
1631
|
+
transformed = transformed.replace(
|
|
1632
|
+
new RegExp(`export\\s+default\\s+class\\s+${exportInfo.name}`),
|
|
1633
|
+
`class ${exportInfo.name}`
|
|
1634
|
+
);
|
|
1635
|
+
transformed += `
|
|
1636
|
+
const __WrappedComponent = __createWrapper(${exportInfo.name}, ${metaObj})
|
|
1637
|
+
export default __WrappedComponent
|
|
1638
|
+
`;
|
|
1639
|
+
} else {
|
|
1640
|
+
transformed = transformed.replace(
|
|
1641
|
+
/export\s+default\s+class\s*\{/,
|
|
1642
|
+
"const __OriginalComponent = class {"
|
|
1643
|
+
);
|
|
1644
|
+
transformed += `
|
|
1529
1645
|
const __WrappedComponent = __createWrapper(__OriginalComponent, ${metaObj})
|
|
1530
1646
|
export default __WrappedComponent
|
|
1531
1647
|
`;
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1648
|
+
}
|
|
1649
|
+
break;
|
|
1650
|
+
}
|
|
1651
|
+
case "identifier": {
|
|
1536
1652
|
transformed = transformed.replace(
|
|
1537
|
-
|
|
1538
|
-
|
|
1653
|
+
/export\s+default\s+\w+\s*;?\s*$/m,
|
|
1654
|
+
""
|
|
1539
1655
|
);
|
|
1540
|
-
transformed = wrapperImport + transformed;
|
|
1541
1656
|
transformed += `
|
|
1542
1657
|
const __WrappedComponent = __createWrapper(${exportInfo.name}, ${metaObj})
|
|
1543
1658
|
export default __WrappedComponent
|
|
1544
1659
|
`;
|
|
1545
|
-
|
|
1660
|
+
break;
|
|
1661
|
+
}
|
|
1662
|
+
case "named-export": {
|
|
1546
1663
|
transformed = transformed.replace(
|
|
1547
|
-
/export\s+
|
|
1548
|
-
"
|
|
1664
|
+
/export\s*\{\s*\w+\s+as\s+default\s*\}\s*;?/,
|
|
1665
|
+
""
|
|
1549
1666
|
);
|
|
1550
|
-
transformed = wrapperImport + transformed;
|
|
1551
1667
|
transformed += `
|
|
1552
|
-
const __WrappedComponent = __createWrapper(__OriginalComponent, ${metaObj})
|
|
1553
|
-
export default __WrappedComponent
|
|
1554
|
-
`;
|
|
1555
|
-
}
|
|
1556
|
-
break;
|
|
1557
|
-
}
|
|
1558
|
-
case "identifier": {
|
|
1559
|
-
transformed = transformed.replace(
|
|
1560
|
-
/export\s+default\s+\w+\s*;?\s*$/m,
|
|
1561
|
-
""
|
|
1562
|
-
);
|
|
1563
|
-
transformed = wrapperImport + transformed;
|
|
1564
|
-
transformed += `
|
|
1565
1668
|
const __WrappedComponent = __createWrapper(${exportInfo.name}, ${metaObj})
|
|
1566
1669
|
export default __WrappedComponent
|
|
1567
1670
|
`;
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
case "named-export": {
|
|
1571
|
-
transformed = transformed.replace(
|
|
1572
|
-
/export\s*\{\s*\w+\s+as\s+default\s*\}\s*;?/,
|
|
1573
|
-
""
|
|
1574
|
-
);
|
|
1575
|
-
transformed = wrapperImport + transformed;
|
|
1576
|
-
transformed += `
|
|
1577
|
-
const __WrappedComponent = __createWrapper(${exportInfo.name}, ${metaObj})
|
|
1578
|
-
export default __WrappedComponent
|
|
1579
|
-
`;
|
|
1580
|
-
break;
|
|
1671
|
+
break;
|
|
1672
|
+
}
|
|
1581
1673
|
}
|
|
1582
1674
|
}
|
|
1675
|
+
transformed = wrapperImport + transformed;
|
|
1583
1676
|
return {
|
|
1584
1677
|
code: transformed,
|
|
1585
|
-
success: true
|
|
1678
|
+
success: true,
|
|
1679
|
+
wrappedExports: wrappedExports.length > 0 ? wrappedExports : void 0,
|
|
1680
|
+
hasDefaultExport: exportInfo.type !== null
|
|
1586
1681
|
};
|
|
1587
1682
|
} catch (error) {
|
|
1588
1683
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2726,6 +2821,25 @@ function cloudwerkPlugin(options = {}) {
|
|
|
2726
2821
|
map: null
|
|
2727
2822
|
};
|
|
2728
2823
|
}
|
|
2824
|
+
if (result.wrappedExports && result.wrappedExports.length > 0) {
|
|
2825
|
+
for (const exportName of result.wrappedExports) {
|
|
2826
|
+
const namedComponentId = `${componentId}__${exportName}`;
|
|
2827
|
+
const namedBundlePath = `${state.options.hydrationEndpoint}/${namedComponentId}.js`;
|
|
2828
|
+
const namedInfo = {
|
|
2829
|
+
componentId: namedComponentId,
|
|
2830
|
+
bundlePath: namedBundlePath,
|
|
2831
|
+
absolutePath: id,
|
|
2832
|
+
exportName
|
|
2833
|
+
};
|
|
2834
|
+
state.clientComponents.set(`${id}::${exportName}`, namedInfo);
|
|
2835
|
+
if (state.options.verbose) {
|
|
2836
|
+
console.log(`[cloudwerk] Detected named client component: ${namedComponentId}`);
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
if (!result.hasDefaultExport) {
|
|
2840
|
+
state.clientComponents.delete(id);
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2729
2843
|
return {
|
|
2730
2844
|
code: result.code,
|
|
2731
2845
|
map: null
|