프로그래밍 관점에서 특정 기능을 가지는 작은 코드 단위
→ 비슷한 기능들을 하나의 의미있는 파일로 관리하는 것이 모듈!
웹 어플리케이션을 구성하는 모든 자원을 의미
→ HTML, CSS, JavaScript, Image, Font 등의 파일 하나하나가 모두 모듈
웹 어플리케이션을 구성하는 수많은 자원들을 하나의 파일로 병합 및 압축해주는 동작
빌드 = 번들링 = 변환
<!-- index.html -->
<html>
<head>
<script src="./src/hello.js"></script>
<script src="./src/world.js"></script>
</head>
<body>
<h1>WEBPACK</h1>
<div id="root"></div>
<script>
document.querySelector("#root").innerHTML = word;
</script>
</body>
</html>
/* src/hello.js */
var word = "hello";
/* src/world.js */
var word = "world";
hello.js
와 world.js
에서 word 변수를 중복으로 선언하는 경우 덮어쓰이는 현상 발생
→ 파일 단위로 변수를 관리하고자하는 욕구
ex. AMD
, Common.js
ex. Grunt
, Gulp
대부분의 사용자들은 5초 이내로 웹 사이트가 표시되지 않으면 집중력을 잃음
→ 로딩 속도를 높이기 위해 브러우저에서 서버로 요청하는 파일 숫자를 줄이기
Require.js
와 같은 라이브러리를 쓰지 않으면 동적으로 모듈을 로딩할 수 없음웹팩에서 웹 자원을 변환하기 위해 필요한 최초 진입점이자 자바스크립트 파일 경로
entry
속성에 지정된 파일에는 웹 애플리케이션의 전반적인 구조와 내용이 담겨져 있어야 함entry
로 지정된 파일을 가지고 웹 애플리케이션에서 사용되는 모듈들 간의 관계를 이해하고 분석 (의존관계의 파일들까지 해석)entry: {
login: './src/LoginView.js',
main: './src/MainView.js'
}
여러 개의 entry
도 가능 (MPA에 적합)
웹팩을 돌리고 난 결과물의 파일 경로 (객체 형식으로 지정해야 함)
var path = require('path');
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
일반적으로 filename
, path
정의
path.resolve()
는 인자로 넘어온 경로들을 조합하여 유효한 파일 경로를 만들어주는 Nodejs API
filename
의 속성은 대괄호를 사용해서 엔트리 이름, 모듈 아이디, 해시 값 등을 넣을 수 있음
module.exports = {
output: {
filename: '[name].bundle.js'
}
};
웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, css, image, 폰트 등)을 변환할 수 있도록 도와줌
loader
를 추가하지 않으면 해당 파일들을 해석하기 위한 loader를 추가하라는 오류 발생npm 명령어로 css-loader 설치 후 정의 가능
module.exports = {
entry: './app.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css/,
use: ['css-loader']
}
]
}
}
test
: 로더를 적용할 파일 유형 (정규식)use
: 해당 파일에 적용할 로더의 이름Sass Loader, TS Loader, Babel Loader, File Loader 등이 자주 사용
Loader 적용 순서
오른쪽에서 왼쪽!
module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
Sass 로더로 전처리(scss 파일을 css 파일로 변환) → 웹팩에서 css 파일을 인식 → css 파일이 웹 애플리케이션에 인라인 스타일 태그로 추가
plugin-transform-runtime
: es6+
의 문법들을 자체 구현한 함수로 트랜스파일core-js@3
.babelrc vs babel.config.json
.babelrc
: 서브셋 디렉토리 또는 파일에서 특정한 플러그인을 변형 할때 유용babel.config.json
: 여러 패키지 디렉토리를 가진 프로젝트에서 하나의 바벨 설정을 가져갈 때 유용웹팩의 기본적인 동작에 추가적인 기능을 제공 (해당 결과물의 형태를 바꾸는 역할)
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin(),
new webpack.ProgressPlugin()
]
}
특징
웹팩 데브 서버로 빌드하는 경우 빌드한 결과물이 메모리에 저장되고 파일은 생성하지 않기 때문에 빌드한 결과물이 파일 탐색기에 보이지 않음
→ 개발할 때만 사용하다가 개발이 완료되면 명령어를 사용해 결과물을 파일로 생성해야 함
프록시 설정
프록시 쓰지 않은 경우 웹팩 데브 서버와 API 서버 통신 시 CORS 에러 발생
// webpack.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'domain.com',
changeOrigin: true
}
}
}
};
프록시 서버를 사용하면 API 서버에서는 같은 도메인에서 온 요청으로 인식해 CORS 에러가 나지 않음
// webpack.config.js
module.exports = {
devServer: {
hot: true
}
}
// webpack.config.js
module.exports = {
devtool: 'cheap-eval-source-map'
}
// webpack.config.js
module.exports = {
mode: 'none',
entry: '',
// ...
}
none
: 모드 설정 안함 - production 모드로 자동 설정development
: 개발 모드 - 개발자들이 보기 편하게 로그나 결과물production
: 배포 모드 - 성능 최적화를 위해 파일 압축 등 빌드 과정 추가실행 모드에 따라 다른 웹팩 설정
개발할 때 사용할 웹팩 설정, 배포할 때 사용할 웹팩 설정 구분 필요
// webpack.config.js
module.exports = (env) => {
let entryPath = env.mode === 'production'
? './public/index.js'
: './src/index.js';
return {
entry: entryPath,
output: {},
// ...
}
}
// package.json
{
"build": "webpack",
"development": "npm run build -- --env.mode=development",
"production": "npm run build -- --env.mode=production"
}
import { sum } from '../utilFile';
"presets": [
[
"@babel/preset-env",
{ "modules": false }
],
],
{
"name": "...",
"sideEffects": false,
}
module.exports = {
mode: "production",
...
}
// webpack.common.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js'
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin(),
],
}
entry, output, plugins과 같이 실행 모드에 관계없는 코드
// webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: { contentBase: './dist' }
});
개발자 도구나 웹팩 데브 서버 설정 추가
// webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production'
});
배포하기 전 웹 리소스 최적화를 위한 설정