React

[React] cross-env 를 이용하여 환경변수 관리하기(1) - 떽떽대는 개발공부

떽이 2021. 3. 10. 10:32

 

 

 

오늘은 cross-env 를 이용하여 환경변수를 용이하게 관리할 수 있도록 해보자.

npm install cross-env

cross-env 를 install 하고 package.json 의 scripts 아래와 같이 start, debug 부분 수정 해주었다.

package.json

  ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "cross-env PHASE=local webpack-dev-server --config ./configs/webpack.config.js --mode development",
    "debug": "cross-env PHASE=debug webpack-dev-server --config ./configs/webpack.config.js"
  },
  ...

콘솔창에 npm run start, 혹은 npm run debug 라는 명령을 입력하면 수행할 부분을 설정 해주는 것인데, 이 부분에서 cross-env 를 이용하여 PHASE 를 local 혹은 debug 라고 설정 해주었다.

이 작업을 하면서 최상위 디렉토리에 있었던 webpack.config.js 파일을 configs 라는 디렉토리를 새로 생성하여 이동 시켜 주었어서 ./configs/webpack.config.js 라고 기재 해주었다.

폴더 구성은 아래와 같다.

콘솔창에 명령어를 실행 하여 가장 먼저 작업이 시작될 webpack.configs.js 에는 아래와 같이 코드를 삽입, 수정해 주었다.

configs/webpack.config.js

const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require('webpack');

const PROJECT_ROOT = path.resolve(__dirname, '../');
const APP_ENTRY = path.join(PROJECT_ROOT, 'src');
const PHASE_CONFIG = require('./phase_config');

const NODE_ENV = process.env.NODE_ENV || 'development';
const PHASE = process.env.PHASE || 'local';

console.log('PHASE :: ', PHASE)

const getConfigByAppPhase = () => {
  return Object.keys(PHASE_CONFIG).reduce((result, key) => {
    const value = PHASE_CONFIG[key] && PHASE_CONFIG[key][PHASE] ? PHASE_CONFIG[key][PHASE] : '';
    result[key] = JSON.stringify(value);
    return result;
  }, {});
};

console.log(PHASE)

module.exports = {
  entry: `${APP_ENTRY}/index.js`,
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname + "../build"),
    publicPath: '/'
  },
  devServer: {
    contentBase: path.resolve("./build"),
    index: "index.html",
    port: 3000
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: "/node_modules",
        use: ['babel-loader'],
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
            options: { minimize: true }
          }
        ]
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      }
    ]
  },
  plugins: [
    new webpack.DefinePlugin(
      Object.assign(
        {
          'process.env': {
            NODE_ENV: JSON.stringify(NODE_ENV),
            PHASE: JSON.stringify(PHASE)
          },
        },
        getConfigByAppPhase(),
      )
    ),
    new HtmlWebPackPlugin({
      template: `${APP_ENTRY}/index.html`,
      PHASE_CONFIG: getConfigByAppPhase(),
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin({})
  ],
  resolve: {
    extensions: ['.js', '.jsx', '.json', 'css'],
    alias: {
      '@src': path.resolve(PROJECT_ROOT + "/src"),
      '@components': path.resolve(PROJECT_ROOT + "/src/components"),
      '@css': path.resolve(PROJECT_ROOT + "/public/css"),
      '@i18n': path.resolve(PROJECT_ROOT + "/src/i18n")
    }
  }
};

 

webpack 에서 수정된 부분은 최상단 부분과 getConfigByAppPhase 함수를 추가하여 plugins 에 new webpack.DefinePlugin 으로 export 해준 것이다.

이렇게만 하면 하위 파일에서 process.env를 이용하여 코드 관리를 할 수 있다.

이제 configs 디렉토리에 phase_configs.js 파일을 간단히 작성 해준다.

configs/phase_config.js

module.exports = {
    TEST_SERVER: {
      local: 'local 입니다.',
      debug: 'debug 입니다.',
    }
  }
  

 

위의 phase 된 내용을 이용하여 환경 별로 코드를 분기할 수 있다.

아래와 같이 local 혹은 debug 별로 render 될 컴포넌트를 관리할 수 있다.

src/index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "@components/App";
import App2 from "@components/App2";

window.onload = () =>{
    if(process.env.PHASE === 'debug'){
    	// debug 모드일 경우 App2 컴포넌트 render
        render2()
    } else {
    	// local 모드일 경우 App 컴포넌트 render
        render()
    }
}

function render(){
    ReactDOM.render(
        <App />
    , document.getElementById("app"));
}

function render2(){
    ReactDOM.render(
        <App2 />
    , document.getElementById("app"));
}

 

각각 렌더될 컴포넌트에서는 아래와 같이 작성한다.

src/components/App.js

import React from 'react';

function App () {
  return (
    <div className="App">
      <h3>This is App</h3>
      // phase_config.js 에서 작성한 내용을 받아올 수도 있다.
      <p>{`${TEST_SERVER}`}</p>
    </div>
  )
}

export default App;

 

src/components/App2.js

import React from 'react';

function App2 () {
  return (
    <div className="App">
      <h3>This is App2 components</h3>
      <p>{`${TEST_SERVER}`}</p>
    </div>
  )
}

export default App2;

 

위와 같이 적용한다면 아래와 같은 값을 얻을 수 있다.

  • console 명령어 : npm run start

console 명령어 : npm run debug

 

2021.03.11 - [React] - [React] cross-env 를 이용하여 환경변수 관리하기(2) - 떽떽대는 개발공부

 

[React] cross-env 를 이용하여 환경변수 관리하기(2) - 떽떽대는 개발공부

2021.03.10 - [React] - [React] cross-env 를 이용하여 환경변수 관리하기(1) - 떽떽대는 개발공부 [React] cross-env 를 이용하여 환경변수 관리하기(1) - 떽떽대는 개발공부 오늘은 cross-env 를 이용하여 환경..

ddeck.tistory.com