We are developing a new application, and as part of this, we want to enforce some new standards in our CI pipeline etc.
One of these standards is that new components cannot be created without corresponding Storybook stories, ensuring everything is listed in the storybook.
is there a linter or process we can run that will check every component that is covered has what is needed?
You can achieve this by dependency-cruiser. It's a library that allows you to build custom rules for checking if the dependencies on your application follow certain patterns.
I've reached two alternative rules for how to ensure every file has a story. (I don't think we can make sure each component in a file with multiple components has a story with this approach)
The first approach ensures that every file is imported directly or indirectly by a story:
// .dependency-cruiser.js
module.exports = {
forbidden: [
{
name: "react-component-without-story",
comment: "This component does not have a story",
severity: "error",
from: {
"path": "^src/./.\\.stories\\.(ts|tsx)$"
},
to: {
"path": "^src/./.\\.tsx$",
"pathNot": [
"\\.(test|stories)\\.tsx?$|\\.d\\.ts$",
],
"reachable": false
}
}
]
}
This might be what you want, if you don't need an individual story for each component. Files will pass in this rule if they are indirectly used in stories components, no matter how many levels deep.
I went with the second approach that requires each file to have at least one stories file that directly imports it:
// .dependency-cruiser.js
module.exports = {
forbidden: [
{
name: "react-component-without-story",
comment: "This component does not have a story",
severity: "error",
from: {
path: "^src/.*\\.stories\\.(ts|tsx)$"
},
module: {
path: "^src/.*\\.tsx$",
pathNot: [
"\\.(test|stories)\\.tsx$|\\.d\\.ts$",
],
numberOfDependentsLessThan: 1,
}
}
]
}
Notice I did this for React, you might need to adapt the paths for Vue.js.