[webpack] 환경변수 접근하기 (feat.mini-css-extract-plugin)

Chloe K·2023년 5월 23일
0

Webpack

목록 보기
4/5
post-thumbnail

Problem

mini-css-extract-plugin 작동 ❌

// webpack.config.ts

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isProd = process.env.REACT_APP_NODE_ENV === 'production';

module.exports = {
    mode: isProd ? 'production' : 'development',
    entry: './src/index.tsx',
    resolve: {
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    }, 
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
      publicPath: '/',
    },
    module: {
      rules: [
        {
          test: /\.(ts|tsx)$/,
          use: ['babel-loader', 'ts-loader'],
          exclude: /node_modules/,
        },
        {
          test: /\.css$/i,
          sideEffects: true,
          use: [
            isProd ? MiniCssExtractPlugin.loader : 'style-loader',
            'css-loader',
          ],
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './public/index.html',
      }),
      new CleanWebpackPlugin(),
      new webpack.HotModuleReplacementPlugin(),
      new MiniCssExtractPlugin({ filename: 'app.css' }),
    ],
    devServer: {
      historyApiFallback: true,
      port: 8080,
      hot: true,
    },
};

isProd 라는 변수에 환경변수를 할당해서 production 모드일 때 mini-css-extract-plugin을 실행해서 번들파일에 css 파일 따로 추출하려고 했다. 하지만 번들파일에 css 파일이 생성되지 않았고, 구글링해보니 isProd가 계속해서 false 값을 반환해서 플러그인이 실행되지 않았던 것이다.

Solution

Webpack에서 환경변수 접근하기

공식문서에 따르면 module.exports를 함수로 변환해야한다.

// 예시

const path = require('path');

module.exports = (env) => {
  // 여기에서 env.<변수> 를 사용하세요.
  console.log('Goal: ', env.goal); // 'local'
  console.log('Production: ', env.production); // true

  return {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
  };
};

// webpack.config.ts 수정 후

module.exports = (env: any) => {
  const isProd = env.production === true;
  // console.log(env)

  return {
    mode: isProd ? 'production' : 'development',
    entry: './src/index.tsx',
    resolve: {
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    }, // 확장자나 경로를 알아서 처리할 수 있도록 설정
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
      publicPath: '/',
    },
    module: {
      rules: [
        {
          test: /\.(ts|tsx)$/,
          use: ['babel-loader', 'ts-loader'],
          exclude: /node_modules/,
        },
        {
          test: /\.css$/i,
          sideEffects: true,
          use: [
            isProd ? MiniCssExtractPlugin.loader : 'style-loader',
            'css-loader',
          ],
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './public/index.html',
      }),
      new CleanWebpackPlugin(),
      new webpack.HotModuleReplacementPlugin(),
      new MiniCssExtractPlugin({ filename: 'app.css' }),
    ],
    devServer: {
      historyApiFallback: true,
      port: 8080,
      hot: true,
    },
  };
};

webpack.config.ts를 수정하고 커맨드라인(package.json)을 수정한다.

  "scripts": {
    "dev": "webpack serve --open --mode development",
    "start": "webpack --env development --mode development",
    "build": "webpack --env production --mode production"
  },

development mode

$ npm start

production mode

$ npm run build

env를 콘솔에 출력해보면 { WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, development: true } or { WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, production: true } 을 확인할 수 있다.

profile
Frontend Developer

0개의 댓글