모듈번들러 웹팩. 프로젝트를 진행하며 js, css, sass, html, image file등 파일을 하나의 파일로 묶어주는 역할을 한다. 위에 보이는 사진이 웹팩을 이해하는 데 가장 쉬운 설명같지만 다시 글로 작성하자면~ 100개의 js파일을 1개의 js파일로 합쳐주는 것!..
굳이 왜? 파일을 합쳐주는가?
사이트 접속시 다운로드 받는 파일 수를 줄이고, 로딩속도를 향상시켜 유저이탈을 막는다.가 하나의 이유이고, 그 밖에도 웹팩을 사용하는 이유는 더 있는데 쉽게 설명해놓은 캡틴판교 웹팩 핸드북과 생활코딩-웹팩 동영상 강의를 볼 것을 권한다~ 물론 webpack 공홈은 꼭 방문해서 한번 훑기도 잊지말기!
npm init -y
초기화 명령을 통해 package.json
을 만들어보자.
위에서 생성한 package.json의 모습이다.
주로 살펴볼 package.json의 내용은 아래 3가지이다
"scripts" : {"..."}
스크립트 명령어, 여기에 웹팩으로 빌드하기, 개발모드 서버 실행 등과 같은 명령어를 작성한다."devDependencies"
& "dependencies"
: 프로젝트에 설치한 모듈(라이브러리,플러그인~)이 작성된다.웹팩 위주로 파일위치, 구조를 설명한다.
webpack 설치 명령어
일반형 :
npm install --save-dev webpack webpack-cli
단축형 :npm i -D webpack webpack-cli
-D는 개발자 모드를 나타냄. 웹팩은 개발 단계에서만 필요하며, 서비스할때는 필요하지 않기 때문에 -D모드로 설치한다.
웹팩 설치가 완료된 이후 폴더 구조를 확인하자. node_modules
폴더, package-lock.json
파일이 생성 되었고,
package.json
의 내용에는 아래 내용이 추가 되었다.
"devDependencies": {
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11"
}
추가로 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 설정파일로 프로젝트 루트에 위치한다. package.json
의 스크립트에 "webpack"
명령어 만 작성한다면 자동 webpack.config.js
을 실행 시켜 설정을 확인한다.
- entry : 최상위 js파일 지정, 이 파일을 기반으로 js 파일을 합친다.
- output : js 출력 위치 설정
- loader : js, html 이회의 파일들을 합치기위해선 loader가 필요하다. 모듈을 다운받고 설정하자.
- plugin : html을 합칠때, 그 밖에 기타 등등을 사용할때 작성하자.
- devServer : 개발단계에서 서버열때 사용한다.
- devtool : 개발이후 오류 디버깅시 사용한다. 오류난 파일과 위치를 알려준다.
.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개 인자를 하나로 합쳐 준다. '경로/파일명.확장자'
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
플러그인의 경우 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'],
}),
],
};
};