Well, the title says it all. I spent hours and hours searching how to make this possible and I can't count how many variations of this very title I had searched but could not find a resource that could lead me to the solution. Or I was too stupid to see it. Or I just needed more coffee.
Regardless, here's what happened...
Background
I was working on the task to create a monorepo that has our UI components library which other projects in the same monorepo can use later.
Challenge
The challenge was shipping the component libraries with tailwind css. Now, one way would be to ship the components with the tailwind css styles compiled to inline-styles on the HTML elements. This is so that if the consumer app uses tailwind css or not, they still get all the component styles. This requires a significant amount of configuration and Webpack magic. And the other way (which I chose) was to style the library with tailwind styles, but leaving the tailwind configuration for consumer apps (including storybook being one of the consumers). For example, I created a file storybook.scss
inside the .storybook
folder created by NX inside my library having the following code:
@tailwind base;
@tailwind components;
@tailwind utilities;
With this approach, the consumers can install Tailwind CSS and can include the @tailwind
directives while the components will come with the styles automagically. And so can my storybook.
The main challenge
The actual challenge though, was making the styles work with storybook. Now, on the internet, you either find that you should load the .scss
(global styles) file inside the .storybook/preview.ts
file. But that requires special configuration and extending the Webpack configuration (which I tried and failed at).
For example:
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/angular';
const config: StorybookConfig = {
stories: ['../**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
{
name: '@storybook/addon-styling-webpack', // 👈🏽 This part
options: {
rules: [
{
test: /^globals\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: { implementation: require.resolve('postcss') },
},
],
},
],
},
},
],
framework: {
name: '@storybook/angular',
options: {},
},
};
export default config;
// To customize your webpack configuration you can use the webpackFinal field.
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
// and https://nx.dev/recipes/storybook/custom-builder-configs
And it didn't work, of course. I not only tried this, but a bunch of variations such as finding the existing .scss
rules in the webpack configuration programmatically on run-time and adding a rule appropriately but it would always mess something else up.
Another suggested solution on Stack Overflow included working with angular.json
, which in my case was project.json
inside the NX monorepo. However, using a similar configuration object only made it worse. Because I'm not dealing with an app here that would require browserTarget
etc, I'm working with an Angular library which needs to work with storybook. And that storybook needs the global styles for parsing the @tailwind
directives.
Anyhow, nothing worked so far.
Solution
Thanks to the NX Console extension for VSCode, I was able to play around the different targets I had in the monorepo and see the default configuration of the storybook. As there was no configuration in my project.json
for the library, I was super confused as what do I need to configure. But more than that... "where the heck is storybook configured for this library???". Because there's nothing in the project.json
as mylib:storybook
. And the extension helped there.
And then thought, Aha! Can I add some configuration to it? And then I tried a few things, but all I needed to do, was to add the following in my-lib/project.json
file:
/* project.json */
{
...,
"targets" {
"build": {
...
},
"storybook": {
"options": {
"styles": [
"libs/my-lib/.storybook/styles.scss"
]
}
}
}
}
Yeah, that! That tiny little configuration object that extends the NX default configurations for storybook and just adds one little style.scss
file there, which is using the @tailwind
directives.
Note: My library does not ship tailwind styles to storybook. Storybook includes the tailwind styles in the preprocessors and thus my components come alive!
Thank me later
If you found this helpful at all, give this a reaction and follow me on socials.
Top comments (1)
Thanks for the article, but it doesn't work for me.
I have a storybook configuration in my project.json and a tailwind.css file in my .storybook folder with the content. But it has no effect.