Sign inSign up
Setup
Interaction tests
Publish
Composition

Troubleshooting your TurboSnap setup

How to prepare your local Storybook for debugging
Debugging TurboSnap with the Chromatic Trace Utility

Why are no changes being detected?

If the build output shows no story files being detected by changes, there might be an issue matching the git changes with the files in your Storybook build. Use the --debug flag for more information about what Chromatic is doing.

Another reason that changes may be missed is if the changed files aren’t directly included in the webpack build; use the externals flag to tell Chromatic about this.

If you’re trying to figure out why certain stories are being re-tested, you can pass the --trace-changed flag, which will print a visual report of how changed files link to your story files:

npx chromatic --only-changed --trace-changed

Alternatively, using the trace utility, you can manually trace a set of files to a set of related story files based on a Webpack stats file. First, you need to generate a preview-stats.json like so (requires Storybook >=6.3):

# npm
npm run build-storybook -- --webpack-stats-json

# yarn
yarn build-storybook --webpack-stats-json

The preview-stats.json will end up in the build directory, typically storybook-static. If you want to inspect this file manually, you can trim it down to its bare essentials using this command:

npx chromatic trim-stats-file

Or, if you’re using a custom build directory:

npx chromatic trim-stats-file ./path/to/preview-stats.json

This will output a preview-stats.trimmed.json file which should be much more human-readable (sort of).

Now, to trace a set of changed file paths to their dependent story files, run the following:

npx chromatic trace [...changed file paths]

For example:

npx chromatic trace ./src/components/link.js ./src/pages/index.js

This prints the number of detected CSF globs, the total number of modules, and a map of Webpack module ID -> file path for each of the found story files (typically *.stories.js).

Example output:

Found 2 CSF globs
Found 218 user modules
{
  '114': './src/components/buildPassed.stories.js',
  '228': './src/components/buildHasChanges.stories.js',
  '229': './src/components/storybookPublished.stories.js',
  ...
}

In this example, it found 2 CSF globs, which are the stories configured in your Storybook’s main.js config file. From those globs, it detected a total of 218 modules (i.e., source files traceable from those globs via imports). What follows is a list of stories files, the IDs of which will get sent to Chromatic and used to limit the stories files to be tested.

If this list of files contains things you didn’t expect, look at any global decorators (e.g., theme providers, wrapper components). These are typically configured in Storybook’s preview.js file. You might have a decorator that’s imported from e.g. an index.js file, which itself imports a bunch of other files. This can lead to all stories depending on a big swath of seemingly unrelated files.

Why are changes not being detected correctly?

Teams frequently use an index file (barrel file) to simplify imports. This practice allows for easier importing, such as accessing a component from @component-library instead of specifying the full path like @component-library/elements/table. However, the usage of barrels impacts TurboSnap’s ability to detect changes.

When encountering a barrel file, TurboSnap relies on Webpack’s tree-shaking abilities to accurately identify changes. Otherwise, a modification in @component-library/elements/table would prompt changes in all files importing from the barrel file, meaning all files that import from @component-library.

Therefore, if you use barrel files, you’ll want to ensure that Webpack tree-shaking (dead-code-elimination) is working properly. Here are some tips:

  1. Use ES2015 module syntax (i.e., import and export)
  2. Build using production mode (NODE_ENV) to enable various optimizations including minification and tree-shaking.
  3. Make sure that compilers do not automatically convert your ES2015 module syntax into CommonJS modules. This is the default behavior of the popular Babel preset @babel/preset-env. See the documentation for more details.

Why are full rebuilds required?

Full rebuilds can be required for various reasons (see the list in how it works). Another scenario where a full rebuild will also be required is due to a change to a package.json or lock file for a subproject that doesn’t affect the Storybook (we need to be very conservative as we cannot tell if a change to a lock file could affect node_modules imported by Storybook).

If you run into this situation frequently, upvote the open issue in the Chromatic CLI’s issue tracker to opt-out of this behavior for specific directories in your repository.

Why is my build failing with an Out of memory error?

If you have a large dependency tree, the build process may fail due to an out of memory error. Re-run Chromatic’s CLI with the NODE_OPTIONS=--max_old_space_size=4096 (or higher) environment variable to increase the amount of available memory. Your CI provider may require additional configuration to allow more memory usage.

Why do merge commits test more changes than I expect?

Ordinarily, TurboSnap uses git to find all files that have changed since the ancestor build to determine which components/stories to snapshot. The changed file behavior is more complex with merge commits because there are two “ancestor builds”.

When you have a merge commit, Chromatic considers any file that has changed since either ancestor’s commit to decide if a story needs to be re-snapshotted. In other words, the union of the git changes.

The reason for this behavior relates to what Chromatic does when it chooses not to re-snapshot a story. In such case, it “copies” the snapshot for the story from the ancestor build, knowing (due to the git check) that the story cannot have changed in the meantime.

In the case of merge commits, Chromatic does not know ahead of time which side of the merge the snapshot might be copied from because that involves running the complete baseline selection process, so it needs to be conservative and allow for changes on either branch.

Does TurboSnap work with squash/rebase merge?

TurboSnap is compatible with squash and merge rebasing as of version 6.6+. Please update your package to get support.