107 lines
2.7 KiB
TypeScript
107 lines
2.7 KiB
TypeScript
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
import type { StorybookConfig } from "@storybook/react-vite";
|
|
import { mergeConfig } from "vite";
|
|
|
|
const storybookConfigDir = path.dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = path.resolve(storybookConfigDir, "../../..");
|
|
const docsSourceDir = path.resolve(storybookConfigDir, "../src");
|
|
const storybookRootCacheDir = path.resolve(
|
|
storybookConfigDir,
|
|
"../../../.artifacts/cache/storybook"
|
|
);
|
|
const storyFilePattern = /\.stories\.(ts|tsx)$/;
|
|
|
|
function collectStoryPaths(directory: string): string[] {
|
|
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
const storyPaths: string[] = [];
|
|
|
|
for (const entry of entries) {
|
|
const entryPath = path.join(directory, entry.name);
|
|
|
|
if (entry.isDirectory()) {
|
|
storyPaths.push(...collectStoryPaths(entryPath));
|
|
continue;
|
|
}
|
|
|
|
if (storyFilePattern.test(entry.name)) {
|
|
storyPaths.push(path.relative(docsSourceDir, entryPath).split(path.sep).join("/"));
|
|
}
|
|
}
|
|
|
|
return storyPaths;
|
|
}
|
|
|
|
function createStorybookCacheKey() {
|
|
const storyPaths = collectStoryPaths(docsSourceDir).sort();
|
|
|
|
return crypto
|
|
.createHash("sha1")
|
|
.update(JSON.stringify(storyPaths))
|
|
.digest("hex")
|
|
.slice(0, 8);
|
|
}
|
|
|
|
const storybookCacheDir = path.resolve(
|
|
storybookRootCacheDir,
|
|
`vite-${createStorybookCacheKey()}`
|
|
);
|
|
const uiSourceEntry = path.resolve(storybookConfigDir, "../../../packages/ui/src/index.ts");
|
|
const tokensSourceEntry = path.resolve(
|
|
storybookConfigDir,
|
|
"../../../packages/tokens/src/index.ts"
|
|
);
|
|
|
|
const config: StorybookConfig = {
|
|
stories: ["../src/**/*.stories.@(ts|tsx)"],
|
|
addons: [
|
|
"@storybook/addon-a11y",
|
|
"@storybook/addon-essentials",
|
|
"@storybook/addon-interactions"
|
|
],
|
|
framework: {
|
|
name: "@storybook/react-vite",
|
|
options: {}
|
|
},
|
|
async viteFinal(config) {
|
|
return mergeConfig(config, {
|
|
cacheDir: storybookCacheDir,
|
|
plugins: [tailwindcss()],
|
|
optimizeDeps: {
|
|
exclude: ["@ai-ui/ui", "@ai-ui/tokens"]
|
|
},
|
|
resolve: {
|
|
alias: [
|
|
{
|
|
find: /^@ai-ui\/ui$/,
|
|
replacement: uiSourceEntry
|
|
},
|
|
{
|
|
find: /^@ai-ui\/tokens$/,
|
|
replacement: tokensSourceEntry
|
|
}
|
|
]
|
|
},
|
|
server: {
|
|
fs: {
|
|
allow: [repoRoot]
|
|
},
|
|
watch: {
|
|
usePolling: true,
|
|
interval: 120,
|
|
awaitWriteFinish: {
|
|
stabilityThreshold: 80,
|
|
pollInterval: 40
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
export default config;
|