webpack 소스코드빌드 도전 - 01

eunji hwang·2020년 2월 22일
0
post-thumbnail

webpack?

모듈번들러 웹팩. 프로젝트를 진행하며 js, css, sass, html, image file등 파일을 하나의 파일로 묶어주는 역할을 한다. 위에 보이는 사진이 웹팩을 이해하는 데 가장 쉬운 설명같지만 다시 글로 작성하자면~ 100개의 js파일을 1개의 js파일로 합쳐주는 것!..

굳이 왜? 파일을 합쳐주는가?
사이트 접속시 다운로드 받는 파일 수를 줄이고, 로딩속도를 향상시켜 유저이탈을 막는다.가 하나의 이유이고, 그 밖에도 웹팩을 사용하는 이유는 더 있는데 쉽게 설명해놓은 캡틴판교 웹팩 핸드북생활코딩-웹팩 동영상 강의를 볼 것을 권한다~ 물론 webpack 공홈은 꼭 방문해서 한번 훑기도 잊지말기!

프로젝트 초기화

npm init -y 초기화 명령을 통해 package.json 을 만들어보자.

초기 package.json의 모습
위에서 생성한 package.json의 모습이다.

package.json

주로 살펴볼 package.json의 내용은 아래 3가지이다

  • "scripts" : {"..."} 스크립트 명령어, 여기에 웹팩으로 빌드하기, 개발모드 서버 실행 등과 같은 명령어를 작성한다.
  • "devDependencies" & "dependencies" : 프로젝트에 설치한 모듈(라이브러리,플러그인~)이 작성된다.

폴더구조

웹팩 위주로 파일위치, 구조를 설명한다.

루트

  • package.json : node.js의 명령 기술
  • webpack.config.js : 웹팩 설정 기술

public폴더

  • 웹팩으로 번들링(압축,변환 다 같은 말) 한 최종 output 파일이 놓일 위치

src폴더

  • 개발단계에서 작성하는 모든 파일(css, js, html)들이 위치한다.
  • index.js : 소스코드 진입점(entry)

install

webpack 설치 명령어

일반형 : npm install --save-dev webpack webpack-cli
단축형 : npm i -D webpack webpack-cli

-D는 개발자 모드를 나타냄. 웹팩은 개발 단계에서만 필요하며, 서비스할때는 필요하지 않기 때문에 -D모드로 설치한다.

webpack 설치완료
웹팩 설치가 완료된 이후 폴더 구조를 확인하자. node_modules폴더, package-lock.json파일이 생성 되었고,
package.json의 내용에는 아래 내용이 추가 되었다.

"devDependencies": {
			"webpack": "^4.41.6",
			"webpack-cli": "^3.3.11"
		   }

webpack 설치완료 후 변화

script 작성

추가로 package.json에 script내용에 "webpack" : ... 내용을 추가 하였다.

"scripts": {
		"webpack": "webpack src/index.js --mode development --output public/bundle.js",
		"test": "echo \"Error: no test specified\" && exit 1"
	},

만약 --mode development--mode production으로 변경한다면 압축한 bundle.js를 생성하게 된다.
앞으로 터미널에서 npm run webpack을 통해 webpack을 실행, src/index.js를 public/bundle.js 출력하게 된다.
터미널에서 웹팩을 실행시켜 보자!

웹팩이 실행되자 우리가 package.json에 지정한 스크립트(webpack src/index.js --mode development --output public/bundle.js)가 출력 되었다. 명령실행이 완료 된 이후 public/bundle.js가 생성된 것을 확인할 수 있다. 아래는 bundle.js의 내용이다. ^^ 너무나 복잡시럽다.

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
.....
중략
.....
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\nconst text = '<p>hello world!</p>';\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (text);\n\n\n//# sourceURL=webpack:///./src/module.js?");

/***/ })

/******/ });

webpack.config.js

webpack 설정파일로 프로젝트 루트에 위치한다. package.json의 스크립트에 "webpack" 명령어 만 작성한다면 자동 webpack.config.js 을 실행 시켜 설정을 확인한다.

  • entry : 최상위 js파일 지정, 이 파일을 기반으로 js 파일을 합친다.
  • output : js 출력 위치 설정
  • loader : js, html 이회의 파일들을 합치기위해선 loader가 필요하다. 모듈을 다운받고 설정하자.
  • plugin : html을 합칠때, 그 밖에 기타 등등을 사용할때 작성하자.
  • devServer : 개발단계에서 서버열때 사용한다.
  • devtool : 개발이후 오류 디버깅시 사용한다. 오류난 파일과 위치를 알려준다.

entry & output

.js 파일을 병합하여 output에 지정한 위치, 파일을 만든다.

// webpack.config.js
const path = require('path'); // 경로 설정을위해 node.js API 불러옴

module.exports = {
  entry: {
      // entry가 여러개 일때 객체형으로 정하며 객체의 키는 filmename에서 [name]으로 치환된다
      index: './public/index.js' ,
      about: './public/about.js' ,
    }, // js 최상위 파일에서 사용한것들 압축할뀨
  output: {
      // 아웃풋 설정
      path: path.resolve(__dirname, 'public'), // 현재위치/public 경로에
      // [name]에는 entry의 객체명이 치환된다. 그박에 해쉬 청크해쉬등 많음 공홈보기
      filename: '[name]_bundle.js', // 파일 bundle.js 를 생성할꺼여
    },
}
  • __dirname : 현재 경로를 나타낸다
  • path.resolve : 2개 인자를 하나로 합쳐 준다. '경로/파일명.확장자'

loader

const path = require('path');

module.exports ={
    module: {
      rules: [
        {
          test: /\.css$/, //정규표현식 작성
          use: [
            // 로더는 하위 부터 시작. css-loader > style-loader
            'style-loader', // style을 입히는 로더, 인라인스타일에 필요하단다.
            'css-loader', // css파일 읽기용
          ],
        },
        {
          test:...,
          use : ['...']
        }
      ],
    },
};

loader는 import 없이 문자열로 등록해주면 설정이 완료된다.
loader는 modele > rules 안에 작성하게 된다. 확장자를 지정하고, 해당 확장자를 어떤 loader를 사용해 합칠지 규칙을 정해주자.
웹팩 공홈에서 loader 정보를 확인하자. 자주쓰는 로더가 잘 정리되어 있다.

  • files : raw-loader, url-loader, file-loader, ref-loader, val-loader
  • json : json-loader
  • transpiling : script--loader, babel-loader, ts-loader
  • templating : html-loader, pug-loader, markdown-loader, react-markdown-loader
  • styling : style-loader, css-loader, sass-loader, stylus-loader
  • linting & testing : eslint-loader
  • frameworks : vue-loader, angular2-template-loader

plugin

플러그인의 경우 Loader와 달리 사용하기 위해 임포트(require)해야 한다.

// 플로그인 임포트
const HtmlWebpackPlugin = require('html-webpack-plugin');

modules.exports = {
 plugins: [
      new HtmlWebpackPlugin({
        // htmlwebpackplugin은 html파일을 output 경로에 생성한다!
        template: './src/index.html', // 템플릿에 지정된 파일로 아웃풋 html을 만든다.
        filename: 'index.html', // public 안에 html파일이 생성된다.
        chunks: ['index'],
      }),
      new HtmlWebpackPlugin({
        template: './src/about.html', // 템플릿에 지정된 파일로 아웃풋 html을 만든다.
        filename: 'about.html', // public 안에 html파일이 생성된다.
        chunks: ['about'],
      }),
 ],
};

여러 html페이지를 pubilc폴더에 파일로 생성하기 위해서 2번 정의를 해줬다.
플러그인 또한 webpack 공홈에 잘 정리되어 있으니 한번 읽어보고 필요한 것 찾아 쓰도록 하자~

자주사용하는 플러그인

  • define-plugin : 환경(개발 or 실서비스)정보 재공(NODE_ENV 환경변수를 읽을 수 있다)
  • split-chunks-plugin
  • image-webpack-plugin
  • html-webpack-plugin : html파일을 후처리
  • clean-webpack-plugin : 이전 빌드 결과물을 제거 하는 플러그인
  • mini-css-extract-plugin : 스타일시트를 js에서 분리하여 파일을 작성한다.
// webpack.config.js 전체보기
// 공홈에서 configuration 내용 보고 참고
const path = require('path');

// 플로그인 임포트
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = (env) => {
  // env 변수는 package.json에서 env의 설정값을 넘겨받는다.
  // 실서비스 일때는 번들파일 사용, 그밖에 원본 index.js 사용
  let entryPathIndex =
    env.mode === 'production' ? './public/index.js' : './src/index.js';

  let entryPathAbout =
    env.mode === 'production' ? './public/about.js' : './src/about.js';

  return {
    // 개발자 모드일때
    // mode: 'development', // 모드에 따라 번들된 파일의 모습이 바끰. 압축 or 풀어해침~
    entry: {
      // entry가 여러개 일때 객체형으로 정하며 객체의 키는 filmename에서 [name]으로 치환된다
      index: entryPathIndex,
      about: entryPathAbout, // 직접 경로 입려해도 되지만, 위에서 상황에 따라 변수 지정되도록 함
    }, // js 최상위 파일에서 사용한것들 압축할뀨
    output: {
      // 아웃풋 설정
      path: path.resolve(__dirname, 'public'), // 현재위치/public 경로에
      // [name]에는 entry의 객체명이 치환된다. 그박에 해쉬 청크해쉬등 많음 공홈보기
      filename: '[name]_bundle.js', // 파일 bundle.js 를 생성할꺼여
    },
    devServer: {
      // webpack-dev-server 설치후 포트 지정 & 스크립트 작성하면 서버열수 있음~ 물론 자동 --watch중!
      port: 9000,
      hot: true, // HMR(Hot Module Replacement) 기능!
    },
    devtool: 'cheap-eval-source-map', // 빌드위 오류디버깅시 위치 파일 위치 찾기위한 개발자도구! 소스맵!
    module: {
      rules: [
        // 확장자나 규칙을 정하고 그에 따른 로더를 지정해준다.
        {
          test: /\.css$/, //정규표현식 작성
          use: [
            // 로더는 하위 부터 시작. css-loader > style-loader
            'style-loader', // style을 입히는 로더
            'css-loader', // css파일 확인 로더~?
          ], // .css 파일이 있으면 css-loader 쓸꺼야
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        // htmlwebpackplugin은 html파일을 output 경로에 생성한다!
        template: './src/index.html', // 템플릿에 지정된 파일로 아웃풋 html을 만든다.
        filename: 'index.html', // public 안에 html파일이 생성된다.
        chunks: ['index'],
      }),
      new HtmlWebpackPlugin({
        template: './src/about.html', // 템플릿에 지정된 파일로 아웃풋 html을 만든다.
        filename: 'about.html', // public 안에 html파일이 생성된다.
        chunks: ['about'],
      }),
    ],
  };
};
profile
TIL 기록 블로그 :: 문제가 있는 글엔 댓글 부탁드려요!

0개의 댓글