Skip to content

Commit

Permalink
Update Storybook to ^8.3.0 (#4085)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding authored Sep 13, 2024
1 parent 7a5215a commit 2295601
Show file tree
Hide file tree
Showing 7 changed files with 648 additions and 1,001 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/publish-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- name: "Delete stats.json if it exists"
run: rm -f ./storybook-static/preview-stats.json

- name: Publish
uses: cloudflare/pages-action@v1
id: publish
Expand Down
6 changes: 6 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ const config: StorybookConfig = {
};

if (configType === "PRODUCTION" && config.root) {
config.plugins = config.plugins?.filter(
(p) =>
!p ||
!("name" in p) ||
p?.name !== "storybook:rollup-plugin-webpack-stats",
);
customConfig.plugins?.push(typescriptTurbosnap({ rootDir: config.root }));
}

Expand Down
15 changes: 0 additions & 15 deletions .yarn/patches/@storybook-test-npm-8.2.4-0a53c854b7.patch

This file was deleted.

38 changes: 19 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"lint:style:lab": "yarn stylelint -f verbose \"packages/lab/src/**/*.css\"",
"lint:style:ag-theme": "yarn stylelint -f verbose \"packages/ag-grid-theme/css/**/*.css\"",
"storybook": "storybook dev -p 6006",
"build-storybook": "yarn build:ag-grid-theme && yarn bundle:css && storybook build",
"build-storybook": "yarn build:ag-grid-theme && yarn bundle:css && storybook build --stats-json",
"typecheck": "tsc --noEmit",
"chromatic": "chromatic"
},
Expand All @@ -59,23 +59,23 @@
"@fontsource/open-sans": "^4.5.13",
"@fontsource/pt-mono": "^5.0.12",
"@mswjs/data": "^0.16.1",
"@storybook/addon-a11y": "^8.2.9",
"@storybook/addon-actions": "^8.2.9",
"@storybook/addon-docs": "^8.2.9",
"@storybook/addon-essentials": "^8.2.9",
"@storybook/addon-interactions": "^8.2.9",
"@storybook/addon-links": "^8.2.9",
"@storybook/addon-mdx-gfm": "^8.2.9",
"@storybook/addon-storysource": "^8.2.9",
"@storybook/blocks": "^8.2.9",
"@storybook/components": "^8.2.9",
"@storybook/addon-a11y": "^8.3.0",
"@storybook/addon-actions": "^8.3.0",
"@storybook/addon-docs": "^8.3.0",
"@storybook/addon-essentials": "^8.3.0",
"@storybook/addon-interactions": "^8.3.0",
"@storybook/addon-links": "^8.3.0",
"@storybook/addon-mdx-gfm": "^8.3.0",
"@storybook/addon-storysource": "^8.3.0",
"@storybook/blocks": "^8.3.0",
"@storybook/components": "^8.3.0",
"@storybook/icons": "^1.2.10",
"@storybook/manager-api": "^8.2.9",
"@storybook/react": "^8.2.9",
"@storybook/react-vite": "^8.2.9",
"@storybook/test": "patch:@storybook/test@npm%3A8.2.9#~/.yarn/patches/@storybook-test-npm-8.2.4-0a53c854b7.patch",
"@storybook/theming": "^8.2.9",
"@storybook/types": "^8.2.9",
"@storybook/manager-api": "^8.3.0",
"@storybook/react": "^8.3.0",
"@storybook/react-vite": "^8.3.0",
"@storybook/test": "^8.3.0",
"@storybook/theming": "^8.3.0",
"@storybook/types": "^8.3.0",
"@tanstack/react-query": "^4.28.0",
"@testing-library/cypress": "^10.0.0",
"@testing-library/dom": "^10.0.0",
Expand All @@ -91,7 +91,7 @@
"ag-grid-enterprise": "^31.3.0",
"ag-grid-react": "^31.3.0",
"axe-core": "^4.9.0",
"chromatic": "^11.3.2",
"chromatic": "^11.10.1",
"ci-info": "^3.3.1",
"clsx": "^2.0.0",
"cypress": "^13.8.0",
Expand All @@ -109,7 +109,7 @@
"react-dom": "^18.3.1",
"rifm": "^0.12.0",
"sass": "^1.52.3",
"storybook": "^8.2.9",
"storybook": "^8.3.0",
"stylelint": "^16.0.0",
"typescript": "4.6.4",
"vite": "^4.4.9",
Expand Down
10 changes: 5 additions & 5 deletions tooling/css-variable-docgen-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
"README.md"
],
"dependencies": {
"@storybook/addon-docs": "^8.2.9",
"@storybook/blocks": "^8.2.9",
"@storybook/components": "^8.2.9",
"@storybook/docs-tools": "^8.2.9",
"@storybook/theming": "^8.2.9",
"@storybook/addon-docs": "^8.3.0",
"@storybook/blocks": "^8.3.0",
"@storybook/components": "^8.3.0",
"@storybook/docs-tools": "^8.3.0",
"@storybook/theming": "^8.3.0",
"polished": "^4.0.5"
}
}
202 changes: 123 additions & 79 deletions tooling/typescript-turbosnap/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/**
* A modified version of: https://github.com/IanVS/vite-plugin-turbosnap
* Reason, Module and Stats types; isUserCode, normalize, the plugin shell and generateBundle are copied.
* A modified version of: https://github.com/storybookjs/storybook/blob/8b16feb67674d6ccfdf3a1c539ca35e56f3e1968/code/builders/builder-vite/src/virtual-file-names.ts
*/

import { writeFile } from "node:fs/promises";
import path from "node:path";
import path, { relative } from "node:path";
import slash from "slash";
import type { BuilderStats } from "storybook/internal/types";
import { Project } from "ts-morph";
import type { Plugin } from "vite";
import { normalizePath } from "vite";

/*
* Reason, Module, and Stats are copied from chromatic types
Expand All @@ -31,130 +30,175 @@ type TurbosnapPluginOptions = {
rootDir: string;
};

const SB_VIRTUAL_FILES = {
VIRTUAL_APP_FILE: "/virtual:/@storybook/builder-vite/vite-app.js",
VIRTUAL_STORIES_FILE:
"/virtual:/@storybook/builder-vite/storybook-stories.js",
VIRTUAL_PREVIEW_FILE: "/virtual:/@storybook/builder-vite/preview-entry.js",
VIRTUAL_ADDON_SETUP_FILE: "/virtual:/@storybook/builder-vite/setup-addons.js",
};

function getResolvedVirtualModuleId(virtualModuleId: string) {
return `\0${virtualModuleId}`;
}

function getOriginalVirtualModuleId(resolvedVirtualModuleId: string) {
return resolvedVirtualModuleId.slice(1);
}

/**
* Strips off query params added by rollup/vite to ids, to make paths compatible for comparison with
* git.
*/
function stripQueryParams(filePath: string): string {
return filePath.split("?")[0];
}

/**
* We only care about user code, not node_modules, vite files, or (most) virtual files.
*/
function isUserCode(moduleName: string) {
if (!moduleName) {
return false;
}

// keep Storybook's virtual files because they import the story files, so they are essential to the module graph
if (
Object.values(SB_VIRTUAL_FILES).includes(
getOriginalVirtualModuleId(moduleName),
)
) {
return true;
}

return Boolean(
moduleName &&
!moduleName.startsWith("vite/") &&
!moduleName.startsWith("\x00") &&
!moduleName.startsWith("\u0000") &&
!moduleName.startsWith("vite/") &&
!moduleName.startsWith("\0") &&
moduleName !== "react/jsx-runtime" &&
!/node_modules\//.exec(moduleName),
!moduleName.match(/node_modules\//),
);
}

/**
* Convert an absolute path name to a path relative to the vite root, with a starting `./`
*/
function normalize(rootDir: string, filename: string) {
/** Convert an absolute path name to a path relative to the vite root, with a starting `./` */
function normalize(workingDir: string, filename: string) {
// Do not try to resolve virtual files
if (filename.startsWith("/virtual:")) {
return filename;
}
// ! Maintain backwards compatibility with the old virtual file names
// ! to ensure that the stats file doesn't change between the versions
// ! Turbosnap is also only compatible with the old virtual file names
// ! the old virtual file names did not start with the obligatory \0 character
if (
Object.values(SB_VIRTUAL_FILES).includes(
getOriginalVirtualModuleId(filename),
)
) {
return getOriginalVirtualModuleId(filename);
}

// We need them in the format `./path/to/file.js`.
const relativePath = normalizePath(path.relative(rootDir, filename));
// Otherwise, we need them in the format `./path/to/file.js`.

const relativePath = relative(workingDir, stripQueryParams(filename));
// This seems hacky, got to be a better way to add a `./` to the start of a path.
return `./${relativePath}`;
return `./${slash(relativePath)}`;
}

type StatsPlugin = Plugin & { storybookGetStats: () => BuilderStats };

export function typescriptTurbosnap({
rootDir,
}: TurbosnapPluginOptions): Plugin {
const moduleMap: Record<string, Module> = {};
}: TurbosnapPluginOptions): StatsPlugin {
const statsMap = new Map<string, Module>();

function addFilesToModuleMap(filePath: string, reasonPaths: string[]) {
const normalizedFilePath = normalize(rootDir, filePath);
const normalizedReasons = reasonPaths.map((reasonPath) => ({
moduleName: normalize(rootDir, reasonPath),
}));

if (!moduleMap[normalizedFilePath]) {
moduleMap[normalizedFilePath] = {
let m = statsMap.get(normalizedFilePath);

if (!m) {
m = {
id: normalizedFilePath,
name: normalizedFilePath,
reasons: [],
};
}

moduleMap[normalizedFilePath].reasons =
moduleMap[normalizedFilePath].reasons?.concat(normalizedReasons);
m.reasons = m.reasons?.concat(normalizedReasons);

statsMap.set(normalizedFilePath, m);
}

const project = new Project({
tsConfigFilePath: "./tsconfig.json",
});

return {
name: "vite-plugin-typescript-turbosnap",
name: "storybook:rollup-plugin-webpack-stats",
enforce: "post",
moduleParsed: (mod) => {
if (isUserCode(mod.id)) {
const file = project.getSourceFile(path.resolve(mod.id));

if (file) {
const filePath = file.getFilePath();
const declarations = file.getVariableDeclarations();
declarations?.forEach((declaration) => {
const x = Array.from(
new Set(
declaration
.findReferences()
.flatMap((references) =>
references
.getReferences()
.map((reference) =>
reference.getSourceFile().getFilePath(),
),
)
.filter((path) => path !== filePath),
),
);

addFilesToModuleMap(filePath, x);
});

file
.getImportDeclarations()
// This gets modules imports for side effects e.g. css files
.filter((importDeclaration) => !importDeclaration.getImportClause())
.forEach((importDeclaration) => {
const cssFile = path.resolve(
path.dirname(filePath),
importDeclaration.getModuleSpecifierValue(),
);
addFilesToModuleMap(cssFile, [filePath]);
});
}
if (!isUserCode(mod.id)) {
return;
}

if (
[
"/virtual:/@storybook/builder-vite/storybook-stories.js",
"/virtual:/@storybook/builder-vite/vite-app.js",
].includes(mod.id)
) {
mod.importedIds
.concat(mod.dynamicallyImportedIds)
.filter((name) => isUserCode(name))
.forEach((depId) => {
addFilesToModuleMap(depId, [mod.id]);
});
const file = project.getSourceFile(path.resolve(mod.id));

if (!file) {
const moduleImports = mod.importedIds.concat(
mod.dynamicallyImportedIds,
);

for (const moduleImport of moduleImports) {
if (isUserCode(moduleImport)) {
addFilesToModuleMap(moduleImport, [mod.id]);
}
}

return;
}
},
generateBundle: function (this, outOpts) {
const stats: Stats = { modules: Object.values(moduleMap) };

// If we don't know where the output is going, we can't guarantee we'll put the results in the right spot.
if (!outOpts.dir) {
throw new Error("Vite option `build.outDir` was not configured.");
const filePath = file.getFilePath();
const declarations = file.getVariableDeclarations() ?? [];
const importDeclarations = file.getImportDeclarations() ?? [];

for (const declaration of declarations) {
const x = Array.from(
new Set(
declaration
.findReferences()
.flatMap((references) =>
references
.getReferences()
.map((reference) => reference.getSourceFile().getFilePath()),
)
.filter((path) => path !== filePath),
),
);

addFilesToModuleMap(filePath, x);
}

const filename = path.resolve(outOpts.dir, "preview-stats.json");
console.log(`vite-plugin-typescript-turbosnap: writing to ${filename}`);
return writeFile(filename, JSON.stringify(stats, null, 2));
for (const importDeclaration of importDeclarations) {
if (importDeclaration.getImportClause()) {
return;
}

const cssFile = path.resolve(
path.dirname(filePath),
importDeclaration.getModuleSpecifierValue(),
);
addFilesToModuleMap(cssFile, [filePath]);
}
},
storybookGetStats() {
const stats: Stats = { modules: Array.from(statsMap.values()) };
return { ...stats, toJson: () => stats };
},
};
}
Loading

0 comments on commit 2295601

Please sign in to comment.