Skip to content

chore: Chromatic turbosnap#10125

Open
snowystinger wants to merge 15 commits into
mainfrom
chromatic-turbosnap
Open

chore: Chromatic turbosnap#10125
snowystinger wants to merge 15 commits into
mainfrom
chromatic-turbosnap

Conversation

@snowystinger
Copy link
Copy Markdown
Member

@snowystinger snowystinger commented May 28, 2026

First, I upgraded chromatic to the latest CLI version.

After that, I attempted to turn on turbo snap, only to find out that there was a file artifact necessary for it to work, it's included in webpack and there's a community vite version, but there is no parcel version. So I set out to have Claude write me a Parcel Reporter Plugin to generate preview-stats.json.

This is preview-stats.json which contains a json map that tells chromatic what files a story depends on, so that if one of those files changes, it retakes the snapshots for that story file. It looks a little like this:

    {
      "id": "./packages/@react-spectrum/s2/src/TagGroup.tsx",
      "name": "./packages/@react-spectrum/s2/src/TagGroup.tsx",
      "reasons": [
        {"moduleName": "./packages/@react-spectrum/s2/chromatic/Forms.stories.tsx"},
        {"moduleName": "./packages/@react-spectrum/s2/chromatic/TagGroup.stories.tsx"}
      ]
    },

So if I make a change to TagGroup, then Chromatic TurboSnap knows to run Forms and TagGroup.

    {
      "id": "./packages/react-aria-components/src/TagGroup.tsx",
      "name": "./packages/react-aria-components/src/TagGroup.tsx",
      "reasons": [{"moduleName": "./packages/@react-spectrum/s2/src/TagGroup.tsx"}]
    },

And farther back, if I make a change to RAC TagGroup, then it's also a change to S2 TagGroup, which again results in the same stories. We have no RAC Chromatic and v3 doesn't use RAC, so that's why we only see the S2 ones.

There are a few handy methods to debug issues with this.
After running a yarn build:chromatic you can run this

npx chromatic@latest trace ./packages/react-aria/src/tag/useTag.ts -s dist/{{commitHash}}/chromatic/preview-stats.json

To see every story file that a particular file will affect.

You can also run the entire Chromatic command with a --dry-run by appending that flag to our script target. Also, there are various options for --trace-changed and we may want to turn that off entirely when our changes affect many files.

    "chromatic": "NODE_ENV=production CHROMATIC=1 chromatic --project-token $CHROMATIC_PROJECT_TOKEN --build-script-name 'build:chromatic' --only-changed --trace-changed --dry-run",

After running this end to end, I see in my console something like this (I changed the background color of Tag's in S2).
Screenshot 2026-05-28 at 2 01 31 pm

Which I promptly denied here https://www.chromatic.com/build?appId=5f0dd5ad2b5fc10022a2e320&number=1227 You can also see the number of snapshots used in the top right of the report. For instance, the first one has 20 snapshots, 1228 also has the same 20 after reverting my change and all of them pass against the baseline, then finally 1229: https://www.chromatic.com/build?appId=5f0dd5ad2b5fc10022a2e320&number=1229 has zero snapshots because there were no changes that would affect a story.

Resources :

https://github.com/storybookjs/storybook/blob/next/code/builders/builder-vite/src/plugins/webpack-stats-plugin.ts
https://www.youtube.com/watch?v=TZKIlqLF_Xk

📝 Test Instructions:

  1. Make a local change that changes the appearance of something
  2. Run
yarn build:chromatic
npx chromatic@latest trace ./packages/{{path to file you are curious about}} -s dist/{{git commit hash}}/chromatic/preview-stats.json
// change script target to "chromatic": "NODE_ENV=production CHROMATIC=1 chromatic --project-token $CHROMATIC_PROJECT_TOKEN --build-script-name 'build:chromatic' --only-changed --trace-changed --dry-run",
yarn chromatic

@rspbot
Copy link
Copy Markdown

rspbot commented May 28, 2026

@rspbot
Copy link
Copy Markdown

rspbot commented May 28, 2026

@rspbot
Copy link
Copy Markdown

rspbot commented May 29, 2026

Comment thread packages/dev/parcel-reporter-turbosnap-stats/helpers.ts Outdated
Comment thread packages/dev/parcel-reporter-turbosnap-stats/helpers.ts Outdated
}

const STORY_VIRTUAL_RE = /\/storybook-builder-parcel\/generated-entries\/stories\.js$/;
const CANONICAL_CSF_GLOB = './storybook-stories.js';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea where this comes from?

Copy link
Copy Markdown
Member Author

@snowystinger snowystinger May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it comes from this: https://github.com/chromaui/chromatic-cli/blob/f409b3d6900c77263cc8558fe59bc79ba7d28359/node-src/lib/turbosnap/getDependentStoryFiles.ts#L122

Which, the comment at the top seems to imply it's just needed and Claude claims this "TurboSnap won't work unless some module in preview-stats.json references one of those exact strings as a reasons[].moduleName."

}

const STORY_FILE_RE = /\.stories\.(js|jsx|mjs|ts|tsx)$/;
const CSF_GLOB_ENTRY = './parcel-csf-glob.js';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where does this come from?

Copy link
Copy Markdown
Member Author

@snowystinger snowystinger May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently from https://github.com/chromaui/chromatic-cli/blob/v17.0.1/node-src/lib/turbosnap/getDependentStoryFiles.ts#L175-L181
I'm having trouble following it through this chain, but this is what Claude claims.

With the CSF_GLOB_ENTRY:

  • ./parcel-csf-glob.js has reasons=[./storybook-stories.js] → classified as CSF glob ✓
  • ./TagGroup.stories.tsx has reasons=[./parcel-csf-glob.js] → does NOT match any candidate prefix → NOT a CSF glob
  • traceName('TagGroup.ts') → reasons include TagGroup.stories.tsx, which has a CSF-glob reason → TagGroup.stories.tsx added to affectedModuleIds ✓

Without CSF_GLOB_ENTRY, pointing story files directly at ./storybook-stories.js:

  • ./TagGroup.stories.tsx has reasons=[./storybook-stories.js] → matches candidate prefix → classified as CSF glob
  • L286 (https://github.com/chromaui/chromatic-cli/blob/v17.0.1/node-src/lib/turbosnap/getDependentStoryFiles.ts#L286): traceName returns early when name is a CSF
    glob, so TagGroup.stories.tsx is never added to affectedModuleIds
  • Instead TagGroup.ts ends up in affectedModuleIds (its reasons include a CSF glob). chromatic-cli's storyIndex is keyed by story-file paths, not source paths →
    no match → 0 stories affected (which is exactly the symptom you'd see)

Comment thread packages/dev/parcel-reporter-turbosnap-stats/helpers.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants