From 92b7ff401deeaa027937359d266296ab98f8856b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 6 Sep 2025 19:40:02 +0000 Subject: [PATCH 1/2] Configure Storybook to use Next.js config and resolve SCSS imports Co-authored-by: ryanclementshax --- .storybook/main.ts | 44 ++++++++++++++++++++++++++++++++++++++++++-- next.config.mjs | 5 +++++ package.json | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index c4ee902..006e9a8 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,9 @@ import type { StorybookConfig } from '@storybook/nextjs' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require('path') module.exports = { - stories: ['../!(node_modules)/**/*.stories.@(js|jsx|ts|tsx)'], + stories: ['../**/*.stories.@(js|jsx|ts|tsx)'], staticDirs: ['../public'], addons: [ '@storybook/addon-links', @@ -11,9 +13,47 @@ module.exports = { ], framework: { name: '@storybook/nextjs', - options: {} + options: { + // Ensure Storybook uses Next.js config (sassOptions, images, etc.) + nextConfigPath: path.resolve(__dirname, '../next.config.mjs') + } }, async webpackFinal(config) { + // Resolve SCSS imports like `@use 'styles/utils'` + config.resolve = config.resolve || {} + config.resolve.alias = { + ...(config.resolve.alias || {}), + styles: path.resolve(__dirname, '../styles') + } + + // Ensure Sass @use 'styles/..' resolves like in Next.js + const includePaths = [path.resolve(__dirname, '..'), process.cwd()] + const applySassIncludePaths = (rule: any) => { + if (!rule) return + if (Array.isArray(rule)) { + rule.forEach(applySassIncludePaths) + return + } + if (rule.use) { + const uses = Array.isArray(rule.use) ? rule.use : [rule.use] + uses.forEach((use: any) => { + const loader: string | undefined = use && (use.loader || use?.loader?.loader) + if (loader && loader.includes('sass-loader')) { + use.options = { + ...(use.options || {}), + sassOptions: { + ...((use.options && use.options.sassOptions) || {}), + includePaths + } + } + } + }) + } + if (rule.oneOf) applySassIncludePaths(rule.oneOf) + if (rule.rules) applySassIncludePaths(rule.rules) + } + applySassIncludePaths(config.module?.rules) + config.module?.rules?.push({ test: /\.md$/, loader: require.resolve('./loaders/dist/postLoader'), diff --git a/next.config.mjs b/next.config.mjs index 1743cd1..80f5eae 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,5 @@ import withBundleAnalyzer from '@next/bundle-analyzer' +import path from 'node:path' /** * @type {import('next').NextConfig} @@ -8,6 +9,10 @@ const config = { // https://nextjs.org/docs/basic-features/eslint#linting-custom-directories-and-files dirs: ['.'] }, + sassOptions: { + // Allow Sass imports like `@use 'styles/utils'` from project root + includePaths: [process.cwd()] + }, typescript: { ignoreBuildErrors: true }, diff --git a/package.json b/package.json index 2f531db..93cdf79 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "analyze": "ANALYZE=true npm run build", "export": "next export", "start": "next start", - "sb": "npm run sb:prepare && storybook dev -p 6006", + "sb": "npm run sb:prepare && storybook dev -p 6006 --no-open", "sb:prepare": "node .storybook/loaders/build.js", "sb:build": "npm run sb:prepare && storybook build", "sb:serve": "npx serve storybook-static", From d8e388f363409f546a1ae8a7d77425f9f593d683 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 6 Sep 2025 20:08:43 +0000 Subject: [PATCH 2/2] Refactor Sass include paths and Storybook config Co-authored-by: ryanclementshax --- .storybook/main.ts | 29 +---------------------------- next.config.mjs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index 006e9a8..456a131 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -26,34 +26,7 @@ module.exports = { styles: path.resolve(__dirname, '../styles') } - // Ensure Sass @use 'styles/..' resolves like in Next.js - const includePaths = [path.resolve(__dirname, '..'), process.cwd()] - const applySassIncludePaths = (rule: any) => { - if (!rule) return - if (Array.isArray(rule)) { - rule.forEach(applySassIncludePaths) - return - } - if (rule.use) { - const uses = Array.isArray(rule.use) ? rule.use : [rule.use] - uses.forEach((use: any) => { - const loader: string | undefined = use && (use.loader || use?.loader?.loader) - if (loader && loader.includes('sass-loader')) { - use.options = { - ...(use.options || {}), - sassOptions: { - ...((use.options && use.options.sassOptions) || {}), - includePaths - } - } - } - }) - } - if (rule.oneOf) applySassIncludePaths(rule.oneOf) - if (rule.rules) applySassIncludePaths(rule.rules) - } - applySassIncludePaths(config.module?.rules) - + // Keep the custom .md loader used by content stories config.module?.rules?.push({ test: /\.md$/, loader: require.resolve('./loaders/dist/postLoader'), diff --git a/next.config.mjs b/next.config.mjs index 80f5eae..4c5d0b9 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -10,8 +10,8 @@ const config = { dirs: ['.'] }, sassOptions: { - // Allow Sass imports like `@use 'styles/utils'` from project root - includePaths: [process.cwd()] + // Allow Sass imports like `@use 'utils'` from the styles directory + includePaths: [path.join(process.cwd(), 'styles')] }, typescript: { ignoreBuildErrors: true @@ -26,10 +26,9 @@ const config = { } } -// eslint-disable-next-line import/no-anonymous-default-export -export default () => - [ - withBundleAnalyzer({ - enabled: process.env.ANALYZE === 'true' - }) - ].reduce((acc, next) => next(acc), config) +// Compose Next.js plugins and export the final config object +export default [ + withBundleAnalyzer({ + enabled: process.env.ANALYZE === 'true' + }) +].reduce((acc, next) => next(acc), config)