<webpack> 설치 및 설정

김민석·2021년 1월 11일
1

YouTube clone

목록 보기
34/54

webpack은 모듈 번들러입니다. 우리가 작성한 소스코드나 리소스 이미지들을 한번에 묶어서 번들 단위로 사용자에게 제공할 수 있도록 도와줍니다. 우리가 작성한 소스코드를 압축하고 코드에 적힌 변수를 변환 하는 기능도 수행합니다.

최신의 es6나 scss 등을 사용해 작성한 파일들을 webpack에게 주면 webpack은 브라우저가 알아들을 수 있는 일반적인 js와 css로 변환시켜준다고 생각하면 됩니다.

설치

  • 설치 링크를 보고 CLI도 설치하시면 됩니다.
%npm install --save-dev webpack
%npm install --save-dev webpack-cli

project

youtube
  *|package.json
  +|webpack.config.js
  +|assets
    +|js
     +|main.js
    +|scss
     +|styles.scss

package.json

package.json 에서 아래와 같이 기존 start script명을 변경해주고 script를 추가해줍니다. 백엔드 부분과 프런트엔드 부분을 나눠준다고 생각할 수 있습니다. dev:assetsbuild:assets로 나눈것은 mode와 관련된 것인데요. 뒤에서 이유를 알 수 있습니다. dev:assets뒤에 -w는 watch를 의미하며 entry에 있는 파일들이 수정되는 걸 지켜본다는 뜻입니다. 재실행하지 않아도 실시간으로 수정해줍니다.

"scripts":{
  "dev:server": "nodemon --exec babel-node init.js --delay 2",
  "dev:assets": "WEBPACK_ENV=development webpack -w",
  "build:assets": "WEBPACK_ENV=production webpack"
}

webpack.config.js

webpack.config.js는 webpack이 호출되면 가장 먼저 확인하는 설정 파일입니다.

webpack.config.js에 관한 용어 설명

설명에 따르면 webpack 버전4부터 설정 파일이 필요없다고 하지만 우리는 만들어서 몇가지 설정을 해보겠습니다. webpack.config.js에서는 babel이 적용되지 않으므로(서버측과 분리하여 생각) es5의 문법을 사용합니다. 설정에 앞서 이해를 돕기 위해 몇가지 용어 설명 먼저 하겠습니다.

  • path
    path는 node.js에 기본적으로 포함된 패키지로 컴퓨터에서의 전체 경로를 반환해주는 패키지입니다. 아래는 path 사용과 관련된 용어입니다.
    • path.resolve
      string을 이어 붙여서 파일 경로를 반환
    • path.join
      string을 이어 붙여서 파일 경로를 반환 및 생성.//정확하지 않음.
    • __dirname
      현재 프로젝트의 경로를 담고 있는 전역변수
const path = require('path');

module.exports = {
  entry: path.resolve(__dirname, 'assets', 'js', 'main.js'),
  output: {
    filename: '[name].js',
    path: path.join(__dirname, 'static');
  },
};
  • entry
    변환 시킬 파일이 있는 경로
  • output
    변환된 파일이 저장될 경로(path) 및 파일 이름(filename)
  • loader
    기본적으로 webpack은 javascript와 json 파일만 이해합니다. loader를 추가해주어야 다른 유형의 파일도 다룰 수 있게됩니다. loader를 추가하기 위해선 module이라는 이름을 사용합니다.
    • test
      변환해야하는 파일을 표현하기 위해 보통 정규표현식 사용
    • use
      변환하는데 사용할 로더
    • 사용 예시
  	module: {
          rules: [
            { 
                test: /\.txt$/, 
                use: 'raw-loader' 
            }
          ]
  	}
  • 특정 파일 형식에 대해 여러개의 loader 사용 방법
    scss파일을 sass로더로 css파일로 변환한 뒤에 css로더를 적용하는 코드입니다. webpack 로더 적용 순서가 배열에서 뒤에서부터 앞으로 적용된다는 것을 알고 있어야 합니다. css-loader가 뒤에 있다면 scss파일을 다룰 수 없어서 오류가 나겠죠? 또 파일 형식마다 rules배열안에 여러 객체를 추가해주면 됩니다.

방법 1.

  module: {
    rules: [
      { 
        test: /\.scss$/, 
        use: ['css-loader', 'sass-loader'] 
      },
      {
        text: '',
        use: [],
      }
    ]
  }

방법 2.

module: {
  rules:[
      {
        test: /\.scss$/,
        use: [
          {loader: 'css-loader'},
          {loader: 'sass-loader'}
        ]
      }
    ]
}
  • mode
    • none
      아무 모드도 설정하지 않음
    • development
      개발 모드에서는 개발자가 보기 편하게 웹팩 로그나 결과물을 보여줌
    • production
      배포 모드에서는 성능 최적화를 위해 기본적인 파일 압축등의 빌드 과정이 추가됨
const MODE = process.env.WEBPACK_ENV; 
// .env파일이 아니라 package.json scripts에서 받아오는겁니다.
// scipts에서 설정한 이름과 동일해야합니다.
//.env파일을 사용하지 않는건 사용할 수 없어서 입니다.

module.exports = {
  mode: MODE
}
  • plugin
    plugin은 변환 결과의 형태를 결정하는 역할을 한다고 생각하면 됩니다. plugin을 사용하려면 require()후에 plugins 배열에 추가해야합니다. 배열에는 new 연산자로 호출하여 플러그인의 인스턴스를 만들어야합니다.
    • babel-loader
      최신 es6를 이해시키기 위한 로더입니다.
      설치: %npm install babel-loader
    • css-loader
      css 파일을 이해하기위한 로더입니다.
    • postcss-loader
      파일을 이해시키는 것을 넘어 브라우저 호환성에 필요한 로더입니다. plugin을 가지고 코드를 변환해줍니다.
      설치: %npm install postcss-loader
    • sass-laoder
      scss 파일을 이해하기위한 로더입니다.
      설치: %npm install sass-loader
    • mini-css-extract-plugin
      설치 : %npm install --save-dev mini-css-extract-plugin
      mini-css-extractg-plugin은 js파일에 포함된 css를 추출해서 새로운 파일로 만들어줍니다. 위에도 언급했듯이 로더는 뒤에서부터 적용되기 때문에 아래 코드에선 sass-loader, postcss-loader, css-loader, miniCssExtractPlugin.loader가 순서대로 적용된다고 생각하면 됩니다.
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    new MiniCssExtractPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.(scss)$/,
        use: [
          MiniCssExtractPlugin.loader, 
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ],
      },
    ],
  },
};

webpack.config.js(총 정리)

const path = require("path");
const autoprefixer = require("autoprefixer");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const mode = process.env.WEBPACK_ENV;

module.exports = {
  mode,
  entry: path.resolve(__dirname, "assets", 'js', 'main.js'),
  output: {
    filename: '[name].js',
    path: path.join(__dirname, 'static')
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        use: ['babel-loader']
      },
      {
        test: /\.(scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "autoprefixer",
                    {
                      //변환될 코드의 target을 의미합니다.
                      overrideBrowserslist:"cover 99.5%"
                    },
                  ],
                ],
              },
            },
          },
          'sass-loader'
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({filename: 'styles.css'}),
  ],
}

main.js

변환할 scss root 파일을 import 해줍니다. entry 파일로 config 해준건 main.js 뿐이기 때문에 scss파일을 import 해주지 않으면 sccs 파일을 변환하지 않습니다.

import '../scss/styles.scss';

styles.scss

변환할 scss 파일을 작성해주면 됩니다.

실행

npm run dev:assets
%npm run dev:assets 터미널에 입력하고 static 폴더 생성 및 폴더 안에 js파일과 css파일이 생성되면 webpack 설정 완료.

profile
누구나 실수 할 수 있다고 생각합니다. 다만 저는 같은 실수를 반복하는 사람이 되고 싶지 않습니다. 같은 실수를 반복하지 않기 위해 기록하여 기억합니다.🙃

2개의 댓글

comment-user-thumbnail
2021년 1월 13일

안녕하세요
설명해주신 그대로 했을때

asset main.js 5.74 KiB [compared for emit] (name: main)
runtime modules 931 bytes 4 modules
cacheable modules 68 bytes
./assets/js/main.js 29 bytes [built][code generated]
./assets/scss/styles.scss 39 bytes [built][code generated] [1 error]

ERROR in ./assets/scss/styles.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleError: Module Error (from ./node_modules/sass-loader/dist/cjs.js):
Cannot find module 'sass'
Require stack:

  • /Users/oseung-u/wetube/node_modules/sass-loader/dist/utils.js
  • /Users/oseung-u/wetube/node_modules/sass-loader/dist/index.js
  • /Users/oseung-u/wetube/node_modules/sass-loader/dist/cjs.js
  • /Users/oseung-u/wetube/node_modules/loader-runner/lib/loadLoader.js
  • /Users/oseung-u/wetube/node_modules/loader-runner/lib/LoaderRunner.js
  • /Users/oseung-u/wetube/node_modules/webpack/lib/NormalModule.js
  • /Users/oseung-u/wetube/node_modules/webpack/lib/NormalModuleFactory.js
  • /Users/oseung-u/wetube/node_modules/webpack/lib/Compiler.js
  • /Users/oseung-u/wetube/node_modules/webpack/lib/webpack.js
  • /Users/oseung-u/wetube/node_modules/webpack/lib/index.js
  • /Users/oseung-u/wetube/node_modules/webpack-cli/lib/webpack-cli.js
  • /Users/oseung-u/wetube/node_modules/webpack-cli/lib/bootstrap.js
  • /Users/oseung-u/wetube/node_modules/webpack-cli/bin/cli.js
  • /Users/oseung-u/wetube/node_modules/webpack/bin/webpack.js
    at Object.emitError (/Users/oseung-u/wetube/node_modules/webpack/lib/NormalModule.js:447:6)
    at getSassImplementation (/Users/oseung-u/wetube/node_modules/sass-loader/dist/utils.js:59:21)
    at Object.loader (/Users/oseung-u/wetube/node_modules/sass-loader/dist/index.js:35:59)
    @ ./assets/js/main.js 1:0-29

2 ERRORS in child compilations
webpack 5.13.0 compiled with 3 errors in 566 ms

라며 mian.js만 생성되고 style.scss는 생성이 안되는 오류가 발생하는데 혹시 어떤이유때문인지 알수 있을까요ㅠ

1개의 답글