[Web]Webpack을 알아보자

3 minute read

WebPack

웹은 페이지가 복잡해질수록 소스관리가 점점 어려워짐에 따라 많은 css, js 파일들은 관리하기도 어렵고 컴파일도 오래걸리게 되었습니다.

때문에 등장한 것이 Webpack Bundler입니다.
Webpack은 아래 그림을 보면 한눈에 알 수 있습니다.

Image Alt 텍스트 이미지출처

Webpack을 아래 명령어를 통해 설치할 수 있습니다.

npm install –save webpack

하지만 Vue, React로 개발을 할 경우 vue cli에서 webpack을 제공하기 때문에 자동으로 webpack 프로젝트로 설정됩니다.

vue init webpack-simple project_name(프로젝트이름)

Webpack 소스

vue를 통해서 webpack을 설치하면 webpack.config.js 파일이 생성됩니다.

Vue를 통해 프로젝트를 생성하면 아래와 같습니다.

├── README.md
├── index.html
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   └── main.js
└── webpack.config.js

크게 webpack은 아래와 같이 4가지로 나누어져 있습니다.

module.exports = {
  entry: [...], //번들하기위한옵션을작성.
  output: [...], //번들링된 파일을 설정.
  module: [...], //번들링할 파일을 설정.
  plugins: [...] //번들링된결과파일의 성능을 향상시키는 부분.
}

아래 소스는 webpack.config.js 소스입니다.

webpack.config.js

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      { //css영역
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },
      { //scss 영역
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ],
      },
      { //sass 영역
        test: /\.sass$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader?indentedSyntax'
        ],
      },
      { //vue loader 영역
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': [
              'vue-style-loader',
              'css-loader',
              'sass-loader'
            ],
            'sass': [
              'vue-style-loader',
              'css-loader',
              'sass-loader?indentedSyntax'
            ]
          }
          // other vue-loader options go here
        }
      },
      {
        //js 파일 영역
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules\/(?!(MY-MODULE|ANOTHER-ONE)\/).*/
      },
      { //file loader 영역
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      },
      {  //글씨체 loader 영역
         test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
         use: [{
             loader: 'file-loader',
             options: {
                 name: '[name].[ext]',
                 outputPath: 'fonts/'
             }
         }]
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}
//production은 배포 development는 실행
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }), //bundle.js의 파일의 용량을 줄이는 역할을 합니다.
    new webpack.LoaderOptionsPlugin({
      minimize: true
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ])
}

Entry, Output

그럼 하나씩 파일의 소스들을 살펴봅시다.
Entry 는 webpack 라이브러리 간의 의존성을 표현하고 이를 설정합니다.
Output 은 entry로 부터 나온 output의 파일을 설정합니다.

제일 먼저 bundle된 파일의 경로를 지정하는 부분입니다. bundle.js 로 최종적으로 css,js,scss 등의 여러 파일들이 bundle된 결과파일입니다. 웹은 이 bundle.js 파일을 읽고 웹 페이지를 생성합니다.

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },

Module

Module 은 webpack을 통해 bundle할 때 처리해야되는 것들을 나타냅니다.

rule에 해당 정규식형태의 파일형식을 작성합니다.
css-loader, scss-loader, babel-loader 등 라이브러리나 css파일형식을 작성하는 부분입니다.

module: {
  rules: [
    test: /\.css$/,
    use: [
      'vue-style-loader',
      'css-loader'
    ],
  //....css,scss,sass,file 등..
],
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'

Plugin

Plugin 에는 Bundling된 파일의 크기를 줄여주고 성능을 향상시킵니다.

webpack의 plugin으로 DefinePlugin, UglifyJsPlugin, LoaderOptionsPlugin 3가지 플러그인지원합니다.

DefinePlugin은 컴파일할 코드에서 특정 문자열을 설정한 값으로 치환해주는 기능을 하고,
UglifyJsPlugin은 컴파일한 결과 코드의 용량을 줄이고 읽기 어렵게 만드는 역할을 한다.
IgnorePlugin은 번들링된 파일에서 무시할 파일을 설정한다.

  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }), //bundle.js의 파일의 용량을 줄이는 역할을 합니다.
    new webpack.LoaderOptionsPlugin({
      minimize: true
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ])

Tags:

Categories:

Updated: