Webpack_생할코딩을 보고 정리한 내용입니다.
1. Webpack
➡️ 여러개의 리소스 파일을 하나의 js파일로 묶어주는 도구. static module bundler
Webpack의 장점
1. 여러개의 파일을 하나로 묶어주기 때문에 네트워크 접속의 부담을 줄일 수 있다. (더 빠른 서비스 제공)
2. 여러개의 서로 다른 패키지들이 서로 같은 이름의 전역 변수를 사용하면 프로그램은 오동작을 하게 된다. 이런 문제를 극복하기 위해서 등장한 것이 모듈이다. 웹팩은 아직 최신 기술이라서 적용하기가 애매한 기술인 모듈을 오래된 브라우저에서도 사용할 수 있게 도와준다.
3. 웹팩에는 매우 많은 플러그인들이 존재한다. 이런 플러그인을 이용하면 웹 개발시에 필요한 다양한 작업을 자동화 할 수 있다.
2. Webpack이전의 세계와 모듈의 개념
◾️ 모듈을 사용하기 전
index.html
<html>
<head>
<script src="./src/hello.js"></script>
<script src="./src/world.js"></script>
</head>
<body>
<h1>Hello, Webpack</h1>
<div id="root"></div>
<script>
document.querySelector('#root').innerHTML = word;
</script>
</body>
</html>
src/hello.js
var word = 'Hello';
src/word.js
var word = 'World';
📝 result
▫️ 똑같은 변수명 word를 사용하고 있기 때문에 변수 이름이 충돌되어 나중에 불러온 스크립트로 덮어 씌어진다.
💡 수백개의 스크립트 파일중에서 이름의 중복을 피하기 위해 모듈이라는 개념을 도입
◾️ 모듈을 사용했을 때
▫️ script type을 module로 설정해준다.
▫️ 각각의 스크립트 파일을 export를 이용해 내보낸다.
▫️ index.html파일에서 스크립트 파일을 import를 이용해 불러온다.
index.html
<html>
<head>
</head>
<body>
<h1>Hello, Webpack</h1>
<div id="root"></div>
<script type="module">
import hello_word from './src/hello.js';
import world_word from './src/world.js';
document.querySelector('#root').innerHTML = hello_word + ' ' + world_word;
</script>
</body>
</html>
src/hello.js
var word = 'Hello';
export default word;
src/word.js
var word = 'World';
export default word;
📝 result
💡 웹에서도 모듈의 개념을 사용하고, 여러개의 파일을 하나로 묶어서 제공하고 싶어 번들러를 만들었다.
3. webpack의 도입
◾️ webpack을 적용했을 때 효과
▫️ 리팩토링 : 구동되는 바업은 그대로 유지하면서 내부의 코드를 효율적으로 바꾼다.
▫️ 구형 브라우저에서도 사용할 수 있고 여러개의 파일을 번들링 할 수 있다.
◾️ webpack을 적용 순서
0️⃣ node.js를 설치한다.
1️⃣ npm init → node.js 프로젝트로 선언
2️⃣ package.json 파일이 생성된다.
package.json
{
"name": "webpack-study",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"http-server": "^0.12.3"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "suyeon",
"license": "ISC",
"description": ""
}
3️⃣ webpack을 설치한다. → npm install -D webpack webpack-cli
package.json
"devDependencies": {
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},
⚠️ 프로젝트 name이 webpack일 경우 에러가 발생한다.
Refusing to install package with name "webpack" under a package also called "webpack".
Did you name your project the same as the dependency you're installing?
4️⃣ entry파일을 만들어 준다. → index.js
index.js
import hello_word from './src/hello.js';
import world_word from './src/world.js';
document.querySelector('#root').innerHTML = hello_word + ' ' + world_word; // Hello, Webpack
5️⃣ bundling
▫️ index.js에서 import된 hello, world의 js 파일까지 하나로 번들링 한다.
▫️ src/index.js 파일을 public/index_bundles.js파일에 번들링 해준다.
→ npx webpack --entry ./src/index.js --output ./public/index_bundle.js
6️⃣ index.html에 번들링된 자바스크립트 파일을 추가해준다.
index.js
<html>
<head>
</head>
<body>
<h1>Hello, Webpack</h1>
<div id="root"></div>
<script src="./public/index_bundle.js"></script>
</body>
</html>
▫️ webpack을 사용하지 않았을 때와 결과물은 똑같지만 다운받아야할 파일은 2개 뿐이다.
4. config
◾️ 설정파일을 만들면 웹팩은 자동으로 설정파일을 이용하여 사용자가 원하는 output을 만들어낸다.
1. webpack.config.js파일을 만든다.
◾️ entry
▫️ 어플리케이션 번들링 과정의 시작파일을 설정한다.
▫️ entry를 통해 필요한 모듈을 로딩하고 하나의 파일로 묶는다.
▫️ entry파일은 꼭 하나가 아닐 수도 있다.
◾️ output
▫️ 번들링된 결과물에 대한 설정을 한다.
▫️ path: output의 경로 설정
▫️ path.resolve([...paths]) : 주어진 인자의 오른쪽부터 절대경로를 합쳐 나간다.
▫️ dirname : webpack.config.js파일이 위치하고 있는 경로를 알려주는 약속된 node.js의 변수
▫️ filename: 결과물의 파일 이름을 설정
webpack.config.js
const path = require('path');
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "public"),
filename: 'index_bundle.js',
}
}
2. Webpack 실행 → npx webpack —config webpack.config.js
ℹ️ 약속된 파일명 webpack.config.js 이면 npx webpack만 입력해도 실행된다.
5. mode
◾️ 개발모드(development)와 프로덕션 모드(production)가 있다.
◾️ 두 모드를 구분해서 사용하는 방법
1. webpack.confg.prod.js 프로덕션용 설정 파일을 따로 만든다.
2. 시스템의 환경 변수를 이용한다.
3. webpack.config.js 파일 내에서 분기처리에 의해 따로 처리한다. (객체 대신 함수를 export 해야한다.)
wepback.config.js
var config = {
entry: './app.js'
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};
6. loader
◾️ webpack은 오직 javascript와 JSON만 이해할 수 있다.
◾️ 다른 형식의 파일을 webpack이 이해하고 처리 가능한 module로 변환(가공) 시킨다.
◾️ CSS 파일을 추가했을 때
▫️ CSS파일을 자바스크립트 모듈안에 import하기 위해서는 style-loader와 css-loader가 필요하다.
▫️ style-loader : CSS를 DOM에 주입
▫️ css-loader : import된 css파일을 해석하여 webpack으로 가져온다.
→ npm install --save-dev style-loader css-loader
wepback.config.js
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "public"),
filename: 'index_bundle.js',
},
module: {
rules: [
{
test: /\.css$/, // 확장자가 css인 파일
use: [
'style-loader',
'css-loader',
],
},
],
},
};
⚠️ loader의 순서
loader는 css-loader → style-loader순으로 실행되어야 한다. (그렇지 않으면 error 발생)
그렇기 때문에 기입 순서는
style-loader
css-loader
📝 result
▫️ CSS파일이 index_bundle.js 파일로 번들링 되었다.
7. output
◾️ output을 따로 처리하고 싶은 경우
1. entry 파일을 따로 설정해준다.
2. output의 filename을 따로 설정해준다.
webpack.config.js
module.exports = {
mode: "development",
entry: {
index: "./src/index.js",
about: "./src/about.js"
},
output: {
path: path.resolve(__dirname, "public"),
filename: '[name]_bundle.js',
},
module: {
rules: [
{
test: /\.css$/, // 확장자가 css인 파일
use: [
'style-loader',
'css-loader',
],
},
],
},
};
📝 result
▫️ 설정한 대로 각각 번들링된 output이 생성되었다.
8. 플러그인
◾️ plugin은 번들된 결과물을 처리한다.
◾️ 복합적이고 더 자유로운 일들을 처리할 수 있따.
◾️ plugin마다 사용방법이 다르다.
HtmlWebpackPlugin
◾️ 번들된 파일을 <script>로 로드한 html파일을 자동으로 생성해준다.
◾️ 기본 사용 방법
1. 플러그인 설치 → npm install --save-dev html-webpack-plugin
2. webpack 설정 파일에 플러그인 추가
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: "development",
entry: {
index: "./src/index.js",
about: "./src/about.js"
},
output: {
path: path.resolve(__dirname, "public"),
filename: '[name]_bundle.js',
},
module: {
rules: [
{
test: /\.css$/, // 확장자가 css인 파일
use: [
'style-loader',
'css-loader',
],
},
],
},
plugins: [
new HtmlWebpackPlugin()
]
};
📝 result
public/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
<script src="index_bundle.js"></script>
<script src="about_bundle.js"></script>
</body>
</html>
▫️ index.html파일이 생성된다.
▫️ index.html파일내에 번들링된 자바스크립트 파일까지 자동으로 생성된다.
💡 각 html에서 필요로하는 js파일을 추가할 때 webpack 설정
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: './index.html',
chunks: ['index']
}),
new HtmlWebpackPlugin({
template: './src/about.html',
filename: './about.html',
chunks: ['about']
}),
]
📝 result
public/index.js
<html>
<head>
</head>
<body>
<h1>Hello, Index</h1>
<div id="root"></div>
<a href="./about.html">about</a>
<script src="index_bundle.js"></script>
</body>
</html>
public/about.js
<html>
<head>
</head>
<body>
<h1>Hello, About</h1>
<div id="root"></div>
<a href="./index.html">index</a>
<script src="about_bundle.js"></script>
</body>
</html>
▫️ index.html파일에는 번들링된 index_bundle.js파일이 추가됨
▫️ about.html파일에는 번들링된 about_bundle.js파일이 추가됨
ℹ️ webpack 감시 옵션→ npx webpack --watch
명령어를 실행시키지 않고도 자동으로 변경 내용을 감시해서 적용시켜준다.
9. 더 알아보기
◾️ DevServer
▫️ live reload: 저장하면 자동으로 reload
▫️ hot module replacement : 모듈을 수정했을 때 수정된 부분만 적용된다.
◾️ Code splitting : 필요에 따라 번들 파일을 여러개의 파일로 분리
◾️ Lazy loading : 분리된 파일들을 필요할 때마다 로딩
👏👏👏