본문 바로가기
JavaScript

Webpack

by ma_ro 2020. 3. 13.

webpack

  • module bundler
  • 의존 관계에 있는 모듈들을 하나의 JS파일로 번들링한다.
  • 의존 모듈이 하나의 파일로 번들링되므로 별도의 모듈 로더가 필요없어진다.
  • ES6+로 작성했을 경우, Babel을 로드하여 ES5 코드로 변경해야한다.
  • Sass를 사용했을 경우, Sass 트랜스파일링도 진행한다.

 

설치

npm install webpack webpack-cli
  • webpack : 파일에서 webpack을 사용 가능하게 해준다.
  • webpack-cli : 콘솔에서 webpack을 사용 가능하게 해준다.

 

설정

  • package.json에서 스크립트를 작성해 놓으면 쓰기 편하다.
"scripts":{
    "dev:server": "nodemon --exec babel-node init.js --delay 2",
    "dev:asset": "webpack -w"
}
  • 설정파일로 루트 디렉터리에 webpack.config.js 파일을 생성해준다.
  • 서버에서 읽는 파일이 아니기 때문에 babel-node를 사용하지 않는다. 때문에 ES5 코드를 사용해야 한다 .
  • Entry 경로와 Output 경로를 지정해주고, 모듈들이 어떻게 작동할지 설정해준다.

 

//webpack.config.js
const path = require("path"); // 전체 경로를 얻어오기 위해 path 사용
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const MODE = process.env.WEBPACK_ENV;
const ENTRY_FILE_JS = path.resolve(__dirname, "assets", "js", "main.js");
const ENTRY_FILE_CSS = path.resolve(__dirname, "assets", "scss", "styles.scss");
// resolve 메서드를 통해 절대 경로를 리턴받는다.
// __dirname은 프로젝트 디렉터리를 가르킨다.
const OUTPUT_DIR = path.join(__dirname, "static");
// 디렉터리를 사용하는 것이기에 join 메서드를 사용
const config = {
      entry: ["@babel/polyfill", ENTRY_FILE_JS, ENTRY_FILE_CSS],
    mode: MODE, 
// mode를 지정해주어야 한다. development와 production 모드
    module: {
// webpack에게 특정 파일을 만났을 때 어떻게 처리할지 지정
        rules: [
            {
                test: /\.(js)$/,
// .js를 만났을 때. 여기서는 정규표현식을 써주어야한다. 
                exclude: /(node_modules|bower_components)/,
                use: [
                    {
                        loader: "babel-loader",
                        options: {
                              presets: ["@babel/preset-env"]
                        }
// This package allows transpiling JavaScript files using Babel and webpack. 
                    }
                ]
            },
            {
                test: /\.(scss)$/, //.scss를 만났을 때
                use: [
                  MiniCssExtractPlugin.loader,
                  "css-loader", // translate CSS into CommonJS
                  "postcss-loader", //Parse CSS and add vendor prefixes
                  "sass-loader" // comfiles Sass to CSS, using Node Sass by default
                // 밑에서부터 처리하므로 처리 역순서로 코드를 입력해야한다. 
                ],
                exclude: /node_modules/
              }
        ]
    },
    output: {
        path: OUTPUT_DIR,
        filename: "[name].js"
// 트랜스파일 + 번들링된 js 파일이 저장될 경로와 파일 이름 지정
    },
  plugins: [new MiniCssExtractPlugin({ filename: "style.css" })]
// 플러그인을 불러온다. filename 옵션은 저장될 파일명이다.
};
// config 라는 설정 객체를 만듬
module.exports = config;
// exports default config;

 

dotenv 수동 설정

  • dotenv 설정시 .env 파일에 설정을 해놓고, process.env 로 가저와서 사용했었다.
    이걸 .env 파일에 설정하지 않고도 콘솔에서 수동으로 설정하여 사용할 수 있다.

 

WEBPACK_ENV=development webpack
  • 콘솔에서 이렇게 명령어를 입력하면 env에서 process에 development라는 값을 가지는 WEBPACK_ENV 객체를 올리게 된다.

 

  "scripts": {
    "dev:assets": "WEBPACK_ENV=development webpack",
    "build:assets": "WEBPACK_ENV=production webpack"
  }
  • 이런 식으로 스크립트에 지정해놓고 사용할 수 있다.

 

* 윈도우 환경

  • mac이나 linux의 경우, 터미널에서 변수 설정이 가능하나 윈도우는 문제가 생길 수 있다. 이런 경우, cross-env를 사용하면 윈도우에서도 콘솔에서 변수 설정이 가능하다.
  • cross-env
 

cross-env

Run scripts that set and use environment variables across platforms

www.npmjs.com

 

JS 트랜스파일

  • ES6+ 코드를 ES5로 변환하는 작업이 필요하다.
  • 서버에서는 babel/node가 그 역할을 하였지만, webpack에서는 babel-loader가 그 역할을 한다.

 

babel-loader

This package allows transpiling JavaScript files using Babel and webpack.

  • babel-loader doc
  • npm으로 설치한다.
  • 모듈로 webpack에서 설정해준다.

 

{
    test: /\.(js)$/,
// .js를 만났을 때. 여기서는 정규표현식을 써주어야한다. 
    exclude: /(node_modules|bower_components)/,
    use: [
        {
            loader: "babel-loader",
            options: {
                presets: ["@babel/preset-env"]
            }
// This package allows transpiling JavaScript files using Babel and webpack. 
        }
    ]
}

 

babel-polyfill

  • babel-polyfill doc
  • Babel로 트랜스파일링하여도 브라우저가 지원하지 않는 코드가 남아 있을 수 있다.
  • Promise, Object.assign 등 ES5 이하에서 대체 안되는 기능은 그대로 남아 있는다.
  • 이걸 보완해줄 수 있는 플러그인이 babel-polyfill이다.
  • ES5/6/7 polyfill인 core-js와 페북에서 만든 regenerator runtime을 주요 디펜던시로 가진다.
  • Babel 7.4.0을 기준으로 core-js와 regenerator runtime를 직접 import 하는 것을 더 선호해서, 이 플러그인은 deprecated 되었다.(?!!!) ( 실제 사용하지 않는 pollfill도 같이 추가가 되기 때문인듯.. )
  • Node / Webpack에서 사용 시 모든 코드와 require 보다 위에 사용해야 한다.
  • 그러면 pollyfill 필요여부를 확인하고, 전역 객체를 직접 수정한다.

 

// for webpack
module.exports = {
  entry: ["@babel/polyfill", "./app/js"],
};
  • webpack 세팅 시, useBuiltIns 옵션을 사용하지 않을 경우에는 webpack.config.js에 바로 설정해주면 된다.

 

Sass 트랜스파일

  • Sass는 브라우저에서 직접 구동이 안되므로, css로 트랜스파일 해야한다.
  • 트랜스파일한 css를 번들 파일에 포함시키는 방법과 별도의 css 파일로 분리하는 방법이 있다.
  • 분리는 MiniCssExtractPlugin을 사용한다.

 

MiniCssExtractPlugin

  • mini-css-extract-plugin

  • 번들에서 CSS를 추출하여 별도의 파일로 만든다.

  • extract-text-webpack-plugin의 개선 버전, webpack v4를 지원한다.

  • Async loading / No duplicate compilation / Easier to use / Specific to CSS 의 개선점을 갖는다.

 

설치

npm install --save-dev mini-css-extract-plugin
npm install css-loader postcss-loader sass-loader
  • css-loader와의 조합을 추천한다.
  • sass-loader : scss를 css로 트랜스파일. 실제 변환은 node-sass가 하므로 별도 설치가 필요하다.
  • postcss-loader : 브라우저 호환성 문제를 해결한다. 별도 설정과 autoprefix 플러그인 설치가 필요하다.
  • css-loader: @import 같은 css를 commonJS로 변환한다.

 

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
entry: ["@babel/polyfill", ENTRY_FILE_JS, ENTRY_FILE_CSS],
plugins: [new MiniCssExtractPlugin({ filename: "style.css" })],
{
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader", // translate CSS into CommonJS
          "postcss-loader", //Parse CSS and add vendor prefixes
          "sass-loader" // comfiles Sass to CSS, using Node Sass by default
        ],
        exclude: /node_modules/
      }
  • 따로 import 하고 제일 밖에 플러그인 설정을 한다.

  • 번들된 파일 자체를 건들기 때문인가????

  • scss 파일의 별도 entry 설정이 필요하다.

 

PostCSS

  • css 파일을 자동으로 호환성 있는 코드로 변경해주는 플러그인
  • autoprefixer 는 postcss의 플러그인 중 하나로 필요시 설치해서 사용한다.
  • autoprefixer의 옵션 설정. pakage.json에 키 값으로 browserslist를 넣는다.
  • postcss.config.js라는 별도 설정파일에서 설정한다.
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

'JavaScript' 카테고리의 다른 글

내 react-router-dom Link는 왜 작동하지 않는가?  (0) 2020.07.04
Google api client 라이브러리 node-js 삽질기  (0) 2020.07.01
JavaScript - Typed Array  (0) 2020.03.11
MongoDB 파일 다루기  (0) 2020.03.08
MongoDB with node.js  (0) 2020.03.03

댓글