티스토리 뷰
storybook + ts+ emotion + storybook 설정 - SassError: SassError: expected "{".
hello-world 2022. 9. 14. 20:32storybook + ts+ emotion + storybook 설정 - SassError: SassError: expected "{".
storybook 설정하는데 있어서 엄청 삽질을 해서 기록해 두려한다.
--------------
설치된 환경
- 기타 다른 패키지도 많이 설치 되었지만 필수적으로 필요한 것만 나열했다.
@craco/craco ( Create-React-App Configuration Override ) - CRA에 config 설정 덮어쓰기 위한 패키지 craco-alias ( 경로 축약을 위한 즉 alias 설정 ../ 를 @ 같은 것으로~) craco-sass-resources-loader ( craco 패키지에 scss 파일 로드를 위한 로더 ) @emotion/react @emotion/styled @emotion/babel-plugin ( className 에 커스텀 라벨링 ) @emotion/babel-preset-css-prop ( /** @jsxImportSource @emotion/react */ 를 매번 로드 안해도 되게끔 해줌 ) typescript storybook |
처음 부터 에러가 났던것은 아니였다. Storybook 에서 전역으로 SCSS 를 지정하려고 했는데 일어난 에러였다.
우선 에러 내용이 SassError: SassError: expected "{". 라고 나오는 것이 일단 먼가 webpack 에서 sass-loader 설정을 별도로 해야 하는 건가?? 라는 물음으로 파보기 시작했다.
문제제기한 부분은 stackoverflow 에서 검색해 보니 딱히 해결된 답변은 없는 듯 해보였다.
https://stackoverflow.com/questions/67140412/storybook-react-sasserror-expected
Storybook React SassError: expected "{"
Trying to setup a Storybook using .scss file. Following the doc > // .storybook/main.js const path = require('path'); // Export a function. Accept the base config as the only param. module.exp...
stackoverflow.com
스토리북 git issue 게시판에서도 깔끔히 해결된 부분은 보이질 않았다.
https://github.com/storybookjs/storybook/issues?q=sassError
GitHub - storybookjs/storybook: 📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, E
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more! - GitHub - storybookjs/storybook: 📓 The UI component explorer. Develop, doc...
github.com
그러나 google 검색 중 아래 URL 을 보고 힌트를 얻었다.
https://dev.to/mdrahiem/add-less-scss-global-styles-in-storybook-1k50
Add .less/.scss global styles in storybook
I am trying to integrate storybook tool with my react app. My app is using .less styles and I've a si...
dev.to
대충 내용은 storybook 의 main.js에서 webpack 설정을 좀 손보고 preview.js 에다 전역 scss 파일을 import 시킨다는 것이였다. 결론부터 말하자면 똑같이 진행해 봤으나 안되는 ㅠㅠ
아무튼 코드는 아래와 같은 순서로 진행했다.
mini-css-extract-plugin 플러그인은 필요가 없어서 해당부분은 제거하고 style-loader, css-loader, sass-loader 설치했다.
npm i -D style-loader css-loader sass-loader
main.js
//const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
......중략............... ,
"addons": [
......중략...............
'@storybook/preset-scss'
],
"webpackFinal": async (config, { configType }) => {
config.module.rules.push({
// this is for both less and scss
test: /.*\.(?:c|sa|sc)ss$/,
loaders: [
'style-loader',
'css-loader',
'sass-loader'
]
});
/* mini-css-extract-plugin 필요없어서 제거
config.plugins.push(new MiniCssExtractPlugin({
......중략...............
}));
*/
return config;
},
}
preview.js
import '!style-loader!css-loader!sass-loader!../src/assets/scss/styles.scss';
export const parameters = {
..... 중략 ........
}
일단 웹팩을 5 버전에 맞는 문법은 아니라서 더 그랬던 거 같다. rules.loaders 는 use 로 대체 되었기 때문에 해당 부분을 바꿔서 해봤다.역시나 한번에 되질 않는 ㅠㅠ
에러 내용은 아래와 같았다.
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
SyntaxError
모듈 빌드가 안되는 먼가 Syntax의 문제인 듯 했지만 먼지를 잘 모르겠는.... 근데 가만히 생각해보니 preview.js 에서 import '!style-loader!css-loader!sass-loader!../src/assets/scss/styles.scss'; 라고 이미 선언했는데 굳이 webpack 에서 재설정할 필요가 있을까라는 의구심이 들어 main.js 에서 webpackFinal 설정한 부분을 전부 지우고 실행해 봤는데 오오 잘된다!!!!!! 코드는 아래와 같다.
main.js
const path = require("path");
// const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/preset-create-react-app",
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
},
"webpackFinal":async (config, { configType }) => {
//storybook 에 알리어스 추가
config.resolve.alias["@"] = path.resolve(__dirname, "../src/");
return {
...config
}
}
}
여기까지 대충 일단락은 된 셈이다. 이렇게 하면 끝일 거 같은데 또 또 찝찝한 기분이....ㅠㅠ
-----------------
그냥 webpackFinal 설정만으로 끝내버릴 순 없을까 라는 고민 끝에 여러 삽질을 통해 아래 URL 를 보고 참고하여 해결하였다.
즉 storybook 에 있는 main.js 에서 webpackFinal 설정만으로 전역 scss 로드하는 법이다.
https://webpack.kr/loaders/sass-loader/#additionaldata
sass-loader | 웹팩
웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.
webpack.kr
아래는 해결한 코드 부분이다.
preview.js ( 기존에 import 한 부분은 주석처리한다. )
// main.js 에서 설정하기에 아래 import 코드는 제거
// import '!style-loader!css-loader!sass-loader!../src/assets/scss/styles.scss';
export const parameters = {
..... 중략 ........
}
main.js
const path = require("path");
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/preset-create-react-app",
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
},
"webpackFinal":async (config, { configType }) => {
// sass-loader 설정추가 - webpackFinal 만으로 전역 scss 추가
config.module.rules.push({
test: /.*\.(?:c|sc|sa)ss$/,
use: [
//"style-loader",
//"css-loader",
{
loader: 'sass-loader',
options: {
additionalData: `
@import "./src/assets/scss/styles.scss";
`
}
}
]
});
//storybook 에 알리어스 추가
config.resolve.alias["@"] = path.resolve(__dirname, "../src/");
return {
...config
}
}
}
추가로 부연설명하자면 style-loader 와 css-loader 로 인해 문법 문제가 좀 발생해서 그냥 주석처리 해버리고 대신 정규표현식 test 하는 부분에 css, sass, scss 를 체크하게끔 해두고 sass-loader 만 설정하였더니 해결되었다.
-----------------------------
이것 외에도 찾아보니 storybook tutorials 홈페이지에서도 해당 부분에 대한 설명이 있었는데 조금 수정해 보니 잘 되어서 기재해 본다.
https://storybook.js.org/tutorials/design-systems-for-developers/react/ko/build/
Storybook Tutorials
Learn how to develop UIs with components and design systems. Our in-depth frontend guides are created by Storybook maintainers and peer-reviewed by the open source community.
storybook.js.org
아래는 해당 페이지에서 전역 스타일 추가 부분만 발췌했다.
import { createGlobalStyle, css } from 'styled-components';
import { color, typography } from './styles';
+ export const fontUrl = 'https://fonts.googleapis.com/css?family=Nunito+Sans:400,700,800,900';
export const bodyStyles = css`
/* Same as before */
`;
export const GlobalStyle = createGlobalStyle`
body {
${bodyStyles}
}`;
스토리북의 GlobalStyle 컴포넌트를 사용하기 위해 컴포넌트 래퍼(wrapper)인 데코레이터(decorator)를 활용할 수 있습니다. 하나의 앱 안이라면 그 컴포넌트를 앱 레이아웃 최상단에 놓겠지만 스토리북에서는 프리뷰 설정 파일을 사용해서 모든 스토리를 그 컴포넌트 안에 넣고 감싸도록 합니다. .storybook/preview.js
+ import React from 'react';
+ import { GlobalStyle } from '../src/shared/global';
/*
* Global decorator to apply the styles to all stories
* Read more about them at:
* https://storybook.js.org/docs/react/writing-stories/decorators#global-decorators
*/
+ export const decorators = [
+ Story => (
+ <>
+ <GlobalStyle />
+ <Story />
+ </>
+ ),
+ ];
/*
* Read more about global parameters at:
* https://storybook.js.org/docs/react/writing-stories/parameters#global-parameters
*/
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
};
라고 한다.
해서 우선 내가 설치한 환경에 맞게 전역 스타일을 선언할 .tsx 를 먼저 추가했다.
파일이름만 변경했다.
src/shared/globalStyle.tsx( 위 소스에선 src/shared/global.js )
import React from 'react';
import { Global, css } from '@emotion/react';
import * as rootStyle from '@/assets/scss/styles.scss';
export const GlobalStyle = ()=>{
return <Global styles={css`${rootStyle}`}/>;
}
.storybook/preview.js( 튜토리얼에 있는 decorators 부분만 추가했다. )
import {GlobalStyle} from '../src/shared/globalStyle';
export const decorators = [
(Story) => (
<>
<GlobalStyle />
<Story />
</>
),
];
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
.storybook/main.js
const path = require("path");
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/preset-create-react-app",
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
},
"webpackFinal":async (config, { configType }) => {
// sass-loader 설정추가
config.module.rules.push({
test: /.*\.(?:c|sc|sa)ss$/,
use: ['sass-loader']
});
//storybook 에 알리어스 추가
config.resolve.alias["@"] = path.resolve(__dirname, "../src/");
return {
...config
}
}
}
main.js 에서 기존에 scss 파일을 로드해 두었었는데 preview.js 에서 로드 되고 있기에 해당 부분은 제거 하였고 sass-loader 를 쓴다고 선언만 시켜놨다. 먼가 좀더 심플한거 같기도 하고 ..... 암튼 튜토리얼페이지에서 제공하는 정보이니 저게 좀 더 신뢰가 가는 듯 하다.
아래 URL 에서 storybook-addon-next 애드온을 설치해서 해결했다고는 하는데 해보지는 않았다. 더 이상 소스를 뒤집고 삽질하기에는 너무 지쳐버림 ㅠㅠ
https://lightrun.com/answers/storybookjs-storybook-react--storybook--scss-modules-not-working
React + Storybook + SCSS modules not working
Lightrun Answers. Where developers land when they google for errors and exceptions
lightrun.com
이 정도 선에서 storybook 설정으로 가기 위한 준비는 끝난 것 같다. 이제부터 스토리북에 컴포넌트 추가를 ㅠㅠ
'Programming language > Reactjs' 카테고리의 다른 글
- Total
- Today
- Yesterday
- 태그
- cordova
- CSS
- vue-router
- svg모션
- svg icon font
- for of 구문
- IntrinsicElements
- 앵귤러
- React.StrictMode
- Intrinsic
- git
- svg 폰트
- 내장요소
- 코도바
- react-router-dom
- interceptors
- Angular
- react
- 리프래시토큰
- icon font
- Vue3
- anime.js
- JsDoc
- 자바스크립트
- git checkout -b
- RefreshToken
- Aptana
- 반복문
- 아이콘 폰트 만들기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |