• CRA(create-react-app) ํ™˜๊ฒฝ์—์„œ ์ ˆ๋Œ€๊ฒฝ๋กœ / ์ „์—ญ Sass ์‚ฌ์šฉํ•˜๊ธฐ

    2022. 3. 16.

    by. ๋‚˜๋‚˜ (nykim)

    320x100

     

     

    CRA
    - ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋š๋”ฑ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•๋Š” ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ* (*์ž์ฃผ ์“ฐ๋Š” ์ˆ˜์‹, ๋ช…๋ น์–ด ๋“ฑ์„ ๋ฏธ๋ฆฌ ์ž…๋ ฅํ•ด ๋†“๋Š” ๊ฒƒ)
    - ๊ทธ๋ž˜์„œ ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ Babel, ESLint, Webpack ๋“ฑ์„ ๋”ฐ๋กœ ์„ค์น˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค

     

     

    CRA(create-react-app)์—์„œ config ๊ฑด๋“œ๋ฆฌ๊ธฐ

     

    ์ ˆ๋Œ€๊ฒฝ๋กœ ์„ค์ •(alias)์„ ํ•˜๋ ค๋ฉด Webpack์˜ config๋ฅผ ๊ฑด๋“œ๋ ค์•ผ ํ•˜์ง€๋งŒ, CRA๋กœ ์ƒ์„ฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ config ํŒŒ์ผ์„ ๋ณผ ์ˆ˜ ์—†๋‹ค.

    eject ํ•˜๋ฉด ์ˆจ๊ฒจ์ ธ ์žˆ๋˜ config ํŒŒ์ผ์„ ๋ฐ–์œผ๋กœ ๊บผ๋‚ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๊ฑฐ ํ•œ ๋ฒˆ ํ•˜๋ฉด ๋ชป ๋Œ๋ฆฌ๋Š” ์˜ต์…˜์ธ๋ฐ.... ์›นํŒฉ์ด๋ž‘ ์•ˆ ์นœํ•œ๋ฐ.... ๐Ÿฅบ

     

    ์ด๋Ÿด ๋• CRACO(Create React App Configuration Override) ๋ฅผ ์‚ฌ์šฉํ•˜์ž! eject ์—†์ด ์„ค์ •์„ ๊ฑด๋“œ๋ฆด ์ˆ˜ ์žˆ๋‹ค ๐Ÿ™Œ

     

    $ yarn add @craco/craco
    $ yarn add -D craco-sass-resources-loader

     

     

    ์„ค์น˜ํ•œ ํ›„ config ํŒŒ์ผ๋“ค์„ ์Šฅ์Šฅ ๋งŒ์ ธ์ค€๋‹ค.

     

     

    1. craco๊ฐ€ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ๋ฐ”๊พธ๊ธฐ

     

    /* package.json ์ˆ˜์ • */
    
    {
    	...
    	"scripts": {
    		"start": "craco start",
    		"build": "craco build",
    		"test": "craco test",
    	},
        ...
    }
    

     

     

    2. craco.config.js ํŒŒ์ผ ์„ค์ •

    - ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์ด์—ฌ์„œ plugins.options.source ๋ฅผ tsconfig ๋กœ ์„ค์ •ํ–ˆ๋‹ค. (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์ด๋ผ๋ฉด jsconfig)

     

    /* craco.config.js ์ƒ์„ฑ */
    
    const CracoAlias = require('craco-alias');
    
    module.exports = {
      plugins: [
        {
          plugin: CracoAlias,
          options: {
            source: 'tsconfig',
            tsConfigPath: 'tsconfig.paths.json'
          }
        }
      ]
    };

     

     

    3.  tsconfig.paths.json ์ƒ์„ฑ ํ›„ ๊ฒฝ๋กœ ์„ค์ •

    - ๋ณ„๋„ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์ง€ ์•Š๊ณ  config.js ๋‚ด์— ์ง์ ‘ ์ž…๋ ฅํ•ด๋„ ๋ฌด๊ด€!

     

    /* tsconfig.paths.json ์ƒ์„ฑ */
    
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
          // ๋˜๋Š” "@components/*": ["src/components/*"] ์ฒ˜๋Ÿผ ์ง€์ • ๊ฐ€๋Šฅ
        }
      }
    }

     

     

    4. tsconfig.json ์ˆ˜์ •

    - ์ปดํŒŒ์ผํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ฃจํŠธ ํŒŒ์ผ๊ณผ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์„ ์ง€์ •ํ•˜๋Š” ํŒŒ์ผ

      - extends: ๋‹ค๋ฅธ ํŒŒ์ผ์˜ ์„ค์ •์„ ์ƒ์†

      - include: ์ปดํŒŒ์ผ ํ• ๋•Œ ํฌํ•จํ•  ํด๋”๋‚˜ ํŒŒ์ผ

     

    /* tsconfig.json ์ˆ˜์ • */
    
    {
      "extends": "./tsconfig.paths.json",
      "compilerOptions": {
        //...
      },
      "include": ["src", "tsconfig.paths.json"]
    }
    

     

     

    ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด @/components/button ๋˜๋Š” @/styles/_mixin.scss ์™€ ๊ฐ™์ด ๋ถˆ๋Ÿฌ์™€ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

    ์ด์ œ craco.config.js ์—์„œ ๊ธ€๋กœ๋ฒŒ๋กœ ์ ์šฉํ•  ์Šคํƒ€์ผ์„ @/styles/๋กœ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

     

    const CracoAlias = require('craco-alias');
    
    module.exports = {
      style: {
        sass: {
          loaderOptions: {
            additionalData: `
              @import "@/styles/_variable.scss";
              @import "@/styles/_mixin.scss";
            `
          }
        }
      },
      plugins: [
        {
          plugin: CracoAlias,
          options: {
            source: 'tsconfig',
            tsConfigPath: 'tsconfig.paths.json'
          }
        }
      ]
    };

     

     

     

     

    ๋ง1) CRA ๊ธฐ๋ฐ˜ Storybook์—์„œ ์ „์—ญ ๋ณ€์ˆ˜ ์ดํ•ดํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ

     

    ์™€... ์–ด๋งˆ๋ฌด์‹œํ•œ ์‚ฝ์งˆ!!

    ์ด๋ ‡๊ฒŒ๋งŒ ํ–ˆ๋”๋‹ˆ ์Šคํ† ๋ฆฌ๋ถ์—์„œ๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ด์„œ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฉด์œผ๋กœ ํƒ€์ผ๋Ÿฌ๋ณด๋‹ค๊ฐ€ (์™œ ์ดํ•ดํ•˜์งˆ ๋ชปํ•˜๋‹ˆใ… ใ… !!)

    ์Šคํ† ๋ฆฌ๋ถ์˜ main.js ์—์„œ sass-loader ์— additionalData ๋„ฃ๋Š” ๊ฑธ๋กœ ํ•ด๊ฒฐ.

     

    /* .storybook/main.js */
    
    module.exports = {
      //...
      webpackFinal: async (config, { configType }) => {
        config.module.rules.push({
          test: /\.scss$/,
          use: [
            {
              loader: 'sass-loader',
              options: {
                additionalData: `
                @import "./src/styles/_variable.scss";
                @import "./src/styles/_mixin.scss";
    		  `	
              }
            }
          ]
        });
        return config;
      }
    };

     

    ์ด์œ ๋Š” ๋ชจ๋ฅด๊ฒ ์œผ๋‚˜ sass-loader ์™ธ์— style-loader ๋‚˜ css-loader๋„ ๊ฐ™์ด ์ง€์ •ํ•˜๊ฒŒ ๋˜๋ฉด,

    "import API from "!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";" ์—๋Ÿฌ๊ฐ€ ๋ถ๋ถ์ณŒ.

    ์•„๋ฌด๋ž˜๋„ ๊ธฐ๋ณธ ์„ค์ •์ด๋ž‘ ์–ด๋”˜๊ฐ€์—์„œ ์ถฉ๋Œ์ด ๋‚˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ์ง€๊ธˆ์œผ๋กœ์„  ์•Œ ์ˆ˜ ์—†๋‹ค... ๐Ÿ˜ญ

    (์ฐธ๊ณ ) (์ฐธ๊ณ ) (์ฐธ๊ณ )

     

     

     

     

     

    ๋ง2) Vite ํ™˜๊ฒฝ์—์„œ ์„ค์ •ํ•˜๊ธฐ

     

    CRACO ์—†์ด tsconfig.json, vite.config.js ํŒŒ์ผ์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

    ๊ตณ์ด paths.json ์œผ๋กœ ๋นผ์ง€ ์•Š๊ณ  tsconfig.json ์— ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๊ณ , vite.config.ts์— alias๋ฅผ ์ง€์ •ํ•ด ์ค€ ๋ชจ์Šต๐Ÿ‘‡

     

    /* tsconfig.json */
    
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        }
      }
    }
    
    /* vite.config.ts */
    
    import { defineConfig } from 'vite';
    import react from '@vitejs/plugin-react';
    import * as path from 'path';
    
    // <https://vitejs.dev/config/>
    export default defineConfig({
      plugins: [react()],
      resolve: {
        alias: {
          '@': path.resolve(__dirname, './src')
        }
      },
      css: {
        preprocessorOptions: {
          scss: {
            additionalData: `
              @import '@/styles/_variable.scss';
              @import '@/styles/_mixin.scss';
            `,
          },
        },
      },
    });

     

     

     

    ๋งˆ๋ฌด๋ฆฌ๋Š” ์—ญ์‹œ...

     

    ์•ผ..์–! โ’ธ LINE+

     

    728x90

    ๋Œ“๊ธ€

Designed by Nana