main.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import type { StorybookConfig } from "@storybook/react-webpack5";
  2. const config: StorybookConfig = {
  3. stories: ["../../../libs/**/*.@(mdx|stories.@(js|jsx|ts|tsx))", "../../../apps/**/*.@(mdx|stories.@(js|jsx|ts|tsx))"],
  4. staticDirs: ["../public"],
  5. addons: ["@nx/react/plugins/storybook", "@storybook/addon-docs", "../addons/theme-toggle/register"],
  6. webpackFinal(config) {
  7. const css_prefix = "ls-";
  8. const rules = config.module?.rules ?? [];
  9. for (const rule of rules) {
  10. if (!rule || typeof rule === "string") continue;
  11. const testString = rule.test?.toString() ?? "";
  12. const isCss = testString.includes("\\.css");
  13. const isScss = testString.includes("scss") || testString.includes("sass");
  14. if (isCss) {
  15. rule.exclude = /tailwind\.css/;
  16. }
  17. // Apply BEM class prefixing to non-module SCSS files
  18. if (isScss && rule.oneOf) {
  19. const scssRules = rule.oneOf.filter((r: any) => {
  20. if (!r.use) return false;
  21. const testString = r.test?.toString() ?? "";
  22. // Skip CSS modules and node_modules
  23. if (testString.match(/module/) || r.exclude?.toString().includes("node_modules")) return false;
  24. // Target rules with css-loader
  25. return (
  26. testString.match(/scss|sass/) &&
  27. Array.isArray(r.use) &&
  28. r.use.some((u: any) => u.loader && u.loader.includes("css-loader"))
  29. );
  30. });
  31. scssRules.forEach((r: any) => {
  32. const cssLoader = r.use.find((use: any) => use.loader && use.loader.includes("css-loader"));
  33. if (cssLoader && cssLoader.options) {
  34. cssLoader.options.modules = {
  35. localIdentName: `${css_prefix}[local]`,
  36. getLocalIdent(ctx: any, _ident: any, className: string) {
  37. // Skip prefixing for Storybook preview styles (targets Storybook DOM classes)
  38. if (ctx.resourcePath?.includes("preview.scss")) return className;
  39. if (className.includes("ant")) return className;
  40. },
  41. };
  42. }
  43. });
  44. }
  45. }
  46. return {
  47. ...config,
  48. module: {
  49. ...(config.module ?? {}),
  50. rules: [
  51. {
  52. test: /tailwind\.css/,
  53. exclude: /node_modules/,
  54. use: [
  55. "style-loader",
  56. {
  57. loader: "css-loader",
  58. options: {
  59. importLoaders: 1,
  60. },
  61. },
  62. "postcss-loader",
  63. ],
  64. },
  65. ...(config.module?.rules ?? []),
  66. ],
  67. },
  68. };
  69. },
  70. framework: "@storybook/react-webpack5",
  71. typescript: {
  72. reactDocgen: "react-docgen",
  73. },
  74. };
  75. export default config;
  76. // To customize your webpack configuration you can use the webpackFinal field.
  77. // Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
  78. // and https://nx.dev/recipes/storybook/custom-builder-configs