storybook-addon-stencil
Version:
A Stencil compiler integration for Storybook.
49 lines (46 loc) • 1.92 kB
JavaScript
import path from "node:path";
import { transpile, createSystem } from "@stencil/core/compiler";
import { ProgramService } from "./ProgramService.js";
import { generateCustomElementDeclaration, generateCustomElementsManifest } from "./CustomElementsManifest.js";
const programService = new ProgramService();
const sys = createSystem();
export default function stencilPlugin(options = {}) {
return {
name: "vite:stencil",
enforce: "pre",
async transform(source, id) {
const fileName = id.split("?")[0];
const components = await programService.getComponents();
const { code, data } = await transpile(source, {
sys,
target: "es2017",
...options,
file: fileName,
});
if (!data.length) {
return;
}
const { componentClassName, htmlTagNames } = data[0];
const sourceFile = programService.getSourceFile(fileName);
const declaration = generateCustomElementDeclaration(data[0], sourceFile);
return `${htmlTagNames
.filter((tagName) => components.has(tagName))
.map((tagName) => `import '${components.get(tagName)}';`)
.join("\n")}
import { setCustomElementsManifest, getCustomElements } from '@storybook/web-components';
${
// Replace the CSS imports with JS imports
code.replace(/\.css\?tag=/g, ".css.js?tag=")}
const customElementsManifest = ${JSON.stringify(generateCustomElementsManifest(declaration, path.relative(process.cwd(), id).split(path.sep).join("/")))};
setCustomElementsManifest({
...(getCustomElements() || {}),
...customElementsManifest,
modules: [
...((getCustomElements() || {}).modules || []),
...customElementsManifest.modules,
],
});
export { ${componentClassName} };`;
},
};
}