개발
Next.js, Vanilla extract 프로젝트에서 storybook 설정하기
배우겠습니다
2024. 3. 30. 18:38
개요
- RSC에서 css in js를 사용하려면 결국 build time css in js를 활용해야한다.
- 이중 vanilla extract가 대안이 될 수 있다.
- vite와 달리 storybook 설정에 여러가지가 필요하다.
- typescript next14 storybook8을 사용중인 프로젝트를 가정한다.
storybook
- 번들링은 webpack기반이다.
- addon 설정뿐만아니라 직접 webpack 설정을 만져줘야한다.
- 프로젝트 내에서 vanilla extract를 이미 사용중이고, nextjs 기본 storybook 설정을 했다고 가정한다.
패키지 설치
- dev dep에 해당 패키지들을 사용해야한다.
@storybook/addon-styling-webpack @vanilla-extract/webpack-plugin mini-css-extract-plugin
- 이중 "@storybook/addon-styling-webpack" 애드온을 추가해주자.
storybook webpack 설정
- config: StorybookConfig의 webpackFinal 프로퍼티에서 storybook webpack 설정을 할 수 있다.
- webpackFinal은
(config: Configuration, options: Options)
를 받아Configuration | Promise<Configuration>) | undefined
를 리턴하는 콜백함수를 넣어준다. - vanilla extract 문서에서 제공해준 웹팩 설정에 맞게 webpackFinal을 작성해줄 것이다.
// refer: <https://vanilla-extract.style/documentation/integrations/webpack/>
// webpack.config.js
const {
VanillaExtractPlugin
} = require('@vanilla-extract/webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new VanillaExtractPlugin(),
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\\.vanilla\\.css$/i, // Targets only CSS files generated by vanilla-extract
use: [
MiniCssExtractPlugin.loader,
{
loader: require.resolve('css-loader'),
options: {
url: false // Required as image imports should be handled via JS/TS import statements
}
}
]
}
]
}
};
- 따라서 webpackFinal의 결과물은 이렇게 나온다.
import { VanillaExtractPlugin } from "@vanilla-extract/webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
webpackFinal: (config) => {
// ...other webpackFinal code
config.plugins?.push(
new VanillaExtractPlugin(),
new MiniCssExtractPlugin()
);
config.module?.rules?.forEach((rule: any) => {
if (
typeof rule !== "string" &&
rule?.test instanceof RegExp &&
rule?.test?.test("test.css")
) {
rule.exclude = /\\.vanilla\\.css$/i;
}
});
config.module?.rules?.push({
test: /\\.vanilla\\.css$/i, // Targets only CSS files generated by vanilla-extract
use: [
MiniCssExtractPlugin.loader,
{
loader: require.resolve("css-loader"),
options: {
url: false,
},
},
],
});
return config;
},
- 의문이 드는 점은 중간에 rule.exclude를 하는 부분이다.
- 해당 부분은 웹팩에서 일반적인 css 파일 처리에서 vanilla extract를 제외하기 위한 코드라고 한다.
테마 적용
- preview: Preview에서 decortors 프로퍼티를 설정해줘야한다.
- 전역적으로 스토리북 스토리를 감싸거나 provide할 데이터가 있을 때 설정한다.
decorators: [ (Story) => ( <div className={`${createTheme로 만든 클래스네임}`}> <Story /> </div> ), ],
어차피 해야할 것
- webpackFinal에서 프로젝트내의 tsconfig설정을 적용해줘야한다.
import * as path from "path"; import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin"; if (config.resolve) { config.resolve.plugins = config.resolve.plugins || []; // for alias @ config.resolve.plugins.push( new TsconfigPathsPlugin({ configFile: path.resolve(__dirname, "../tsconfig.json"), }) ); }
- 이로서 path alias도 스토리북에 적용 가능하다.