like 치토스 번들...
번들링 사용되기 전 문제점
- 서로다른 두 개 파일에서 같은 변수/함수 사용 시, 충돌 발생
- 네트워크 부하
한번 불러오는 프레임워크 코드가 8MB라, 인터넷 속도가 느린 국가의 사용자가 불편함- import / export가 구형 웹브라우저에서 동작 안함
- 배포 코드가 읽기 쉬운 경우, 사용자가 프론트엔드 애플리케이션을 임의로 조작하는 피해가 발생
기능별로 모듈화한 JS파일들을 묶어준다는 뜻.
: 파일들을 묶어주는 도구
여러 개 파일(html,css,js,jpg,pnp 등)을 하나로 묶는 모듈 번들러
웹 앱의 빠른 로딩 속도, 높은 성능
웹팩으로 같은 타입의 파일들을 한 대 묶어서 요청/응답 받으므로 네트워크 코스트 절감
Webpack loader를 사용하면 ES6의 문법들을 ES5로 번환해주는 babel-loader를 사용할 수 있음.
Vue의 경우 vue-loader를,
scss 경우는 css 파일로 변환해주는 scss-loader 등의 loader도 사용할 수 있기에 각자가 선택해 개발할 수 있음
Webpack4 버전 이상부터 Develoment, Production 두 가지 모드를 지원.
Production 모드의 경우, 코드 난독화, 압축, 최적화(Tree Shaking) 작업 지원
개발 완료된 앱을 배포하기 위해 하나의 폴더로 구성하는 작업
module.exports = {
target: ["web", "es5"],
entry: "./src/script.js",
output: {
path: path.resolve(__dirname, "docs"),
filename: "app.bundle.js",
clean: true
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
}),
new MiniCssExtractPlugin(),
],
optimization: {
minimizer: [
new CssMinimizerPlugin(),
]
}
};
: 다양한 환경 컴파일 가능하게 함.
web
: 시작점.
./src/index.js
//기본 값
entry: "./src/index.js",
//지정 값
entry: "./src/script.js",
번들 내보낼 위치path
, 번들 파일명filename
지정방법을 웹팩에 알려줌
./dist/main.js
./dist 폴더
path
속성 사용 시 path 모듈을 사용해야만 함const path = require('path');
module.exports = {
...
output: {
path: path.resolve(__dirname, "docs"), // 절대 경로로 설정 해야 한다.
filename: "app.bundle.js",
clean: true // 번들링할때마다 dist폴더 정리하기
},
};
: JavaScript, JSON이 아닌 파일을 불러오는 역할
웹팩은 기본적으로 JS, JSON파일만 이해한다.
그러나 Loaders 사용 시, 웹팩이 다른 유형 파일을 처리하거나, 유효한 모듈로 변환해 앱에 사용하거나 dependency 그래프에 추가할 수 있음
test
(필수) : 변환이 필요한 파일들을 식별하기 위한 속성 use
(필수) : 변환을 수행하는데 사용되는 로더를 가리키는 속성exclude
: 바벨로 컴파일 안할 파일/폴더를 지정.module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
exclude: /node_modules/,
},
],
},
};
번들 최적화, 에셋 관리, 환경변수 주입 등 광범위한 작업 수행 가능
require()
로 플러그인 먼저 요청plugins
배열에 사용하고자 하는 플러그인을 추가new 연산자
를 사용해 호출하여 플러그인의 인스턴스 생성html-webpack-plugin
mini-css-extract-plugin
const webpack = require('webpack');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
}),
new MiniCssExtractPlugin(),
],
};
웹팩 버전4부터 선택항목에 따른 최적화 가능
minimize
: TerserPlugin
또는 optimization.minimize
에 명시된 plugins로 bundle 파일을 최소화(=압축)시키는 작업 여부를 결정minimizer
: defualt minimizer
을 커스텀된 TerserPlugin
인스턴스를 제공해서 재정의할 수 있다.module.exports = {
...
optimization: {
minimizer: [
new CssMinimizerPlugin(),
]
}
};
cd ~/Desktop
mkdir fe-sprint-webpack-tutorial
cd fe-sprint-webpack-tutorial
-> package.json파일 생성됨
npm init -y
//package.json
{
"name": "fe-sprint-webpack-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": ""
}
src/index.js
파일 생성하고,// src/index.js
const shout = (...sentences) => console.log(...sentences);
webpack은 프로젝트를 번들링하기 위한 라이브러리이긴 하지만,
실제 프로젝트에 사용하지 않으므로 devDependency 옵션 설정
npm install -D webpack webpack-cli
최근 webpack은 설정파일 없이도 작동되게 업데이트됐지만,
webpack 설정을 다룰 줄 알아야 다양한 외부 리소스를 사용하기 편하다.
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"), // './dist'의 절대 경로를 리턴합니다.
filename: "app.bundle.js",
},
};
npx webpack
-> dist 폴더 안 app.bundel.js에 최소화된 코드로 생성되어 있음
//package.json
{
"name": "fe-sprint-webpack-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack", // 추가
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0"
}
}
Node.js에서만 작동할 법한 코드를 모든 브라우저에서 잘 작동할 수 있도록 번들링을 해주었기 때문에 잘 작동했던 것이죠. index.html 파일을 dist 디렉터리로 옮겨서 번들 파일과 연결
css-loader : CSS를 JS파일 내에서 불러올 수 있다,
style-loader : 불러온 CSS를 style 요소 내에 담아준다.
css-loader
, style-loader
설치npm i -D css-loader style-loader
npm run build
// webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.bundle.js",
},
// 여기부터 추가
module: {
rules: [
{
// 파일명이 .css로 끝나는 모든 파일에 적용
test: /\.css$/,
// 배열 마지막 요소부터 오른쪽에서 왼쪽 순으로 적용
// 먼저 css-loader가 적용되고, styled-loader가 적용되어야 한다.
// 순서 주의!
use: ["style-loader", "css-loader"],
// loader가 node_modules 안의 있는 내용도 처리하기 때문에
// node_modules는 제외해야 합니다
exclude: /node_modules/,
},
],
},
};
npm i -D html-webpack-plugin
npm run build
-> 하면 dist에 index.html 파일 생성됨
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin') // 추가
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.bundle.js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
exclude: /node_modules/,
},
],
},
// 여기부터 추가
plugins: [new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})]
};
<script defer="defer" src="app.bundle.js"></script>
스크립트 요소를 추가해줌npm install gh-pages --save-dev
// package.json
"build": "webpack --mode=production",
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
// 자동으로 script가 삽입되도록 하기위해서 설정
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
// 진입점 생성 => 진입점은 app.js
entry: './src/app.js',
// 출력되는 파일이름은 bundle.js 경로는 path.resolve(__dirname, 'dist')
output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') },
// module은 style-loader와 css-loader를 적용한다.
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
devServer: {
contentBase: __dirname + '/dist/',
host: 'localhost',
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
],
};
github 홈페이지 -> 현재 작업중인 레포지토리 settings -> options -> github pages를 클릭
배포할때는 npm run deploy
// ex) production 모드로 설정
"build": "webpack --config webpack.config.prod.js",
npm install webpack-merge
webpack.config.dev.js 생성후 작성
//webpack.config.dev.js
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
module.exports = merge(baseConfig, {
mode: 'development',
devServer: {
port: 3001
}
})
webpack.config.prod.js 생성후 작성
//webpack.config.prod.js
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
module.exports = merge(baseConfig, {
mode: 'production'
})
var config = {
entry: './app.js',
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};
clean: true,
: 번들링 할 때 마다 dist 디렉터리를 정리하기 (참고)output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true, // 추가
},
"[name].bundle.js",
: 번들파일명이 지정명이 아니라, 늘 동적으로 변하도록 생성하기 (참고)filename: "[name].bundle.js",
mini-css-extract-plugin
:css-minimizer-webpack-plugin
: CSS 압축시켜논 것. 인스턴스 제공해서 재정의할 수 있음npm install --save-dev mini-css-extract-plugin
npm install css-minimizer-webpack-plugin --save-dev
//webpack.config.base.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 추가
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 추가
module.exports = {
target: ["web", "es5"],
entry: "./src/script.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.bundle.js",
clean: true
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"], // 수정
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
}),
new MiniCssExtractPlugin(), // 추가
],
optimization: { // 여기부터 끝까지 추가
minimizer: [
new CssMinimizerPlugin(),
],
},
};
webpack-dev-server : 빠른 실시간 리로드 기능을 갖춘 개발 서버 (라이브 서버와 비슷)
npm install --save-dev webpack-dev-server
//package.json
"dev": "webpack-dev-server --open --config webpack.config.dev.js"
// webpack.config.dev.js
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
module.exports = merge(baseConfig, {
mode: 'development',
devServer: { // 추가
port: 3001
}
})
ES6를 지원하지 않는 브라우저에서 실행 가능하게 target 속성을 활용합니다.
module.exports = {
// ...
target: ['web', 'es6'],
};
npm install --save-dev babel-loader @babel/core @babel/cli @babel/preset-env
babel-loader
설치module: {
rules: [
{
test : /\.js$/,
exclude: /node_modules/,
use : "babel-loader" // 추가
},
{
test : /\.css$/,
use : ["style-loader", "css-loader"]
}
],
},
@babel/core
: babel의 핵심기능을 포함해서 반드시 설치해야 함@babel/cli
: 터미널에서 바벨명령어 사용가능하도록 CLI 제공@babel/preset-react
: 리액트(JSX)를 js로 인식가능@babel/preset-env
: es6, es7 버전을 지정안해도 babel이 자동 탐지. 바벨프리셋이라고도 부름. 설정도 해줘야 함babel.config.js
/ babel.config.json
파일생성해 설정하는 방법(바벨 7버전부터 생김){
"presets": [
"@babel/preset-env",
"@babel/preset-react", // 설치 시 추가
]
}
.babelrc
파일과 package.json
에 babel key를 넣어서 설정하는 방법[VSCode] 웹팩(webpack)과 바벨(babel) 설정하기(3) - 바벨 기본 설정
Webpack | PoiemaWeb