1. Webpack
- Weppack은 모던 JavaScript 애플리케이션을 위한 모듈 번들러이다.
* 모듈 번들러란 웹 애플리케이션을 구성하는 자원을 모두 각각의 모듈로 보고 이들을 조합해서 하나의 결과물로 만드는 툴이다.
- 브라우저의 성능이 높아지고 자바스크립트 애플리케이션이 점점 고도화되면서 유지보수의 난이도가 높아졌다.
- 이를 해결하기 위해 자바스크립트를 기능 단위로 분리하여 사용하는 모듈화가 필요해졌다.
- 자바스크립트 모듈시스템이 등장하기 전에 모듈 패턴으로 사용했고, 정식 지원하는 모듈 시스템이 생겨났지만, IE 브라우저에서는 지원하지 않았기 때문에 모든 브라우저 환경에서 모듈 시스템을 사용할 수 있도록 만들어진 게 webpack이다.
Webpack 공식홈페이지: https://webpack.js.org/
2. Weppack 핵심 개념
- Entry: 모듈의 시작점, 모든 의존 객체들이 모인 웹팩의 시작점을 정의한다.
- Output: 모든 모듈을 하나로 함쳐서 저장하는 경로를 설정한다.
- Loaders: 모듈의 소스 코드에 변경 사항을 적용하는 역할을 한다. 자바스크립트뿐만 아나리 다른 포맷의 파일도 처리할 수 있다. 다양한 파일 확장자를 다를 수 있도록 도와주는 서드파티 확장 프로그램이다. js가 아닌 파일들을 모듈로 바꾸어준다.
- Plugins: 로더가 수행할 수 없는 다양한 기능을 수행한다. 동작 방식을 바꿔주는 서드파티 확장 프로그램이다.
3. Weppack 설정하기
1) webpack 을 사용하기 위하여 npm을 초기화시켜준다.
npm init -y
- 설정 없이 자동으로 package.json을 만들어준다.
2) webpack과 webpack webpack-cli 설치하기
npm install -D webpack webpack-cli
- 개발용 환경을 구성해주기 위하여 -D를 입력해준다. -D 옵션을 사용하여 설치된 패키지들은 devDepndencies에 기록된다.
3) entry, ouput, mode 세 가지 옵션을 설정한다.
원하는 경로에 app.js파일을 만들고 다음과 같이 입력, 예시에는 src/app.js 경로에 파일 생성
npx webpack --mode development --entry ./src/app.js -o ./dist
- `entry value`: 모듈의 시작점을 설정한다. webpack이 내부의 디펜던서 그래프를 생성하기 위해 사용해야 하는 모듈이다.
- 엔트리 포인트가 직간접적으로 의존하는 다른 모듈과 라이브러리를 찾아낸다.
Dependecy Graph 참고자료:
https://webpack.kr/concepts/dependency-graph/
- `-o, --output-path value` : 웹팩으로 생성되는 파일의 경로를 설정한다.
- `--mode`: 번들링 모드를 결정한다. development 모드와 production 모드가 있으며 production 모드의 경우 코드를 최적화하여 용량을 줄인다.
- production모드 코드 최적화 예시
4) 위의 방식을 보다 간단하게 packge.json을 수정하고 webpack.config.js을 추가해주는 방식으로 편하게 build 할 수 있다.
- 우선 예시로 모듈화 할 파일과 결과를 보여줄 html 파일들을 src 폴더를 생성하여 그 안에 만들어 준다.
- qpp.js 파일
import { minus } from "./minus.js";
console.log(minus(4, 2));
- minus.js 파일
export function minus(a, b) {
return a - b;
}
- index.html 파일
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="../dist/main.js"></script>
</body>
</html>
- package.json파일 script 부분에 다음과 build를 추가 입력한다.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
- webpack.config.js 파일을 생성 후 다음과 같이 입력한다.
const path = require("path"); // 노드 모듈 중 path 모듈을 가져와서 절대 경로를 전달
module.exports = {
mode: "development",
//entry: 모듈의 시작점을 알려준다.
entry: {
main: path.resolve("./src/app.js"),
},
//output: 여러개의 모듈을 하나로 만들어서 저장시킬 위치
output: {
path: path.resolve("./dist"), //dist 폴더에 저장해라(resolve: 절대경로)
filename: "[name].js", //[네임값이 드어온다].js인 파일 생성해준다.
// 위의 entry에 설정한 키값인 main이 들어와서 dist폴더에 main.js가 생성된다.
},
};
- 그 후 터미널 창에 npm run build를 입력하면 여러 개의 js파일들을 하나로 모아둔 dist폴더의 main.js 파일이 생성된다. 이때 run을 입력하는 이유는 scrpt에 우리가 임의로 원하는 명령어로 만들어주었기 때문이다.
npm run build
- 예시로 만든 코드에 따라 console창을 확인해보면 minus.js가 제대로 작동되어 2를 출력한다.
4. Webpack 기능 사용하기: Loader
- Loader는 웹펙이 JavaScript 뿐만 아니라 css, html, 이미지 리소스 등 모든 것을 모듈처럼 다룰 수 있게 해주는 기능이다.
1) Loader로 사용할 예시 파일을 만들어준다.
// 로더가 읽을 파일이 item으로 전달됩니다. item은 리소스 파일의 콘텐츠를 담고 있는 문자열입니다.
module.exports = function myLoader(item) {
console.log('hello myLoader!');
// 반환하는 리소스를 replace 문법을 통해 가공합니다.
return item.replace('console.log(', 'alert(');
}
2) webpack.config.js에 module이라는 키 이름으로 로더를 등록한다. (module.exports = { } 안에 다음과 같이 입력, 경로 주의: 예시에서는 src 밖에 생성)
module: {
rules: [
{
// 로더가 처리해야할 파일의 패턴(정규표현식)입니다.
// 여기서 \는 .을 정규표현식 문법이 아닌 특수문자로, .js$ 는 .js 로 끝나는 모든 파일을 의미합니다.
test: /\.js$/,
use: [
// 위와 일치하는 패턴의 파일이 전달될 로더를 설정합니다.
path.resolve('./myLoader.js')
]
},
]
}
5. Loader로 CSS파일 가져와보기
1) 우선 css파일을 모듈로 사용할 수 있게 만들어주는 css-loader를 설치한다.
npm install css-loader
2) HTML이 CSS를 인식해서 CSSDOM으로 바꾸도록 도와주기 위해 style-loader를 설치한다.
npm install style-loader
3) 적용시킬 스타일을 위한 style.css파일을 생성해주고 app.js에 import 한다.
- style 파일
body {
background-color: lightsalmon;
}
- app.js 에 style.css import
import { minus } from "./minus.js";
import "./style.css";
console.log(minus(4, 2));
- webpack.config.js에 module.exports 내부 module키 안에 스타일 로더 추가
module: {
rules: [
// 여기서 로더를 추가할 수 있습니다.
{
// 로더가 처리해야할 파일의 패턴(정규표현식)입니다.
// 여기서 \는 .을 정규표현식 문법이 아닌 특수문자로, .js$ 는 .js 로 끝나는 모든 파일을 의미합니다.
test: /\.js$/,
use: [
// 위와 일치하는 패턴의 파일이 전달될 로더를 설정합니다.
path.resolve("./myLoader.js"),
],
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
- /\.css/ : .css로 끝나는 모든 파일
- 이때 로더는 위에서 아래로 순차적으로 진행되기 때문에 순서에 주의하여야 하며, 위의 예시에서는 style-loader를 먼저 입력해야 한다.
(html이 css를 먼저 인식하여 dom을 형성하고 js로 모듈화 하는 순서이기 때문이다.)
6. 이미지 파일 로드하기
1) 원하는 이미지 파일을 src 폴더에 저장하고 style.css에 background 이미지로 추가해주고 빌드를 진행한다.
(css를 사용하기 때문에 5. loader로 css 파일 가져와보기를 선행하여야 한다.)
body {
background-color: lightsalmon;
background-image: url(./img1.png);
}
npm run build
- 빌드를 진행한 후 지정해주었던 dist 폴더에 이미지의 이름이 해시 값으로 바뀌어 들어가 있는 것을 확인할 수 있다. 이는 이미지가 갱신되었을 때 파일명이 기존과 동일할 경우 브라우저가 여전히 이전 이미지를 보여주는 경우를 막기 위해서이다.
- 캐시 값이 기존의 이미지를 저장하고 다시 부르게 되는 경우에 이미지가 업데이트되지 않도록 함을 방지한다.
6.1 Base64 포맷으로 이미지 불러오기
- 간단한 이미지의 경우 다운로드하지 않고 asset/inline로더를 추가하여 문자열로 그려내는 방법이 있다.
* Asset Moules
- 로더를 추가로 구성하지 않더라도 에셋 파일을 사용할 수 있도록 해주는 모듈이다.
∙ asset/resorce : 별도의 파일을 내보내고 URL을 추출한다.
∙ asset/inline: asset의 data URL를 내보낸다.
∙ asset/source: 에셋의 소스코드를 내보낸다.
∙ asset: data URL과 별도의 파일 중 자동으로 선택하여 내보낸다.
참고사이트: https://webpack.kr/guides/asset-modules/
1) webpack.config.js에 asset/inline 로더를 추가한다.
module: {
rules: [
{
test: /\.svg|png|jpg|gif$/,
type: "asset/inline",
},
]
}
`/\.svg | png | jpg | gif$/` : svg, png, jpg, gif 파일을 모두 처리한다.
type: "asset/inline" : 모든 asset들을 dataURL로 번들에 삽입된다.
2) 원하는 이미지를 src 폴더에 넣고 이를 HTML 화면에 띄워 놓기 위하여 다음과 같이 입력한다.
import img2 from "./img2.png";
document.addEventListener("DOMContentLoaded", () => {
document.body.innerHTML = `<img src="${img2}">`;
});
npm run build
- 빌드하면 이미지가 dist 폴더에 다운로드되지 않고 문자열로 로딩된다.
- 문자열로 로딩되는 이미지는 다운로드되는 게 아니기 때문에 로딩 속도가 빠르다. 하지만 이미지가 너무 복잡하다면 코드가 길어져 로딩이 느려 줄 수 있음으로 주의하여야 하며, 간단한 이미지를 사용할 때 효과적이다.
* 아래와 같은 방법으로 이미지의 크기를 제한할 수도 있다.
type: "asset/inline",
parser: {
dataUrlCondition: {
maxSize: 20 * 1024 // 1kb가 1024byte 이기 때문에 20kb를 원한다면 1024에 20을 곱합니다.
}
},
'프로그래밍 > HTML, CSS, JavaScript' 카테고리의 다른 글
[Three.js] THREE.MATH.randFloatSpread() 오류 (0) | 2022.10.24 |
---|---|
Webpack 개발 환경 설정 및 주요 Plugin 사용하는 법 (0) | 2022.07.02 |
[JavaScript] null과 undefined의 차이점 (0) | 2022.06.27 |
[JavaScript] async와 await 개념과 Fetch (0) | 2022.06.08 |
[JavaScript] 비동기 처리 방식 (callback, setTimeout, promise) (0) | 2022.05.24 |