๐Ÿฟ/JS

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

๋‚˜๋‚˜ (nykim) 2022. 3. 16. 15:03
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