https://velog.io/@hih0327/Webpack-%EA%B8%B0%EC%B4%88
Webpack 기초
개발환경을 구축하면서 배우는 Webpack 기초를 보고 실습하면서 작성한 글입니다. 처음 공부하고 있어서 부족하거나 잘못된 정보가 있을 수 있습니다. (2019.10.30 수) 조금 더 자세히 알게 되거나 수
velog.io
펌글 입니다.
웹팩에 대한 개념을 잡기 위해서는 우선 모듈 번들러(Module Bundler)가 무엇인지 알아야 한다.
실습을 위한 디렉터리(react-webpack)를 만든 후 아래 명령어를 통해 초기화
npm init -y
npm install -save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader clean-webpack-plugin css-loader html-loader html-webpack-plugin mini-css-extract-plugin node-sass react react-dom sass-loader style-loader webpack webpack-cli webpack-dev-server
// ./src/test.js
console.log("webpack test");
// ./webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/test.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none"
};
- entry
웹팩이 빌드할 파일을 알려주는 역할
여기서는 src/test.js 파일 기준으로 import 되어 있는 모든 파일들을 찾아 하나의 파일로 합치게 된다.
- output
웹팩에서 빌드를 완료하면 output에 명시되어 있는 정보를 통해 빌드 파일을 생성
- mode : 웹팩 빌드 옵션
- production : 최적화되어 빌드 되어지는 특징
- development : 빠르게 빌드하는 특징
- none : 아무 기능 없이 웹팩으로 빌드
"scripts": {
"build": "webpack"
},
webpack 명령어가 실행되면 디폴트로 실행할 파일은 같은 경로에 있는 webpack.config.js에 내용을 가지고 빌드 된다.
npm run-script build
정상적으로 실행이 되었다면 build 폴더와 bundle.js 파일이 생성된다.
웹팩은 자바스크립트 파일뿐만 아니라 다른 파일들도 모듈로 관리 할 수 있는데 Loader 기능이 자바스크립트 이외의 파일을 웹팩이 이해할 수 있게 해준다.
- 로더 사용법
module : { rules: { test: '가지고올 파일 정규식', use: [ { loader: '사용할 로더 이름', options: { 사용할 로더 옵션 } } ] } }
<!-- ./public/index.html -->
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="utf-8" />
<title>WEBPACK4-REACT</title>
</head>
<body>
<noscript>스크립트가 작동되지 않습니다!</noscript>
<div id="root"></div>
</body>
</html>
// ./webpack.config.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/test.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none",
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
})
]
};
HtmlWebPackPlugin 은 웹팩이 html 파일을 읽어서 html 파일을 빌드할 수 있게 해준다.
loader 는 html 파일을 읽었을 때 html-loader를 실행하여 웹팩이 이해할 수 있게 하고 options 로는 minimize라는 코드 최적화 옵션을 사용하고 있다.
npm run-script build
정상적으로 실행이 되었다면 ./build/index.html 파일이 생성된다.
minimize 옵션이 켜져 있어서 파일 내용이 한줄로 되어 있다.
minimize 옵션을 끈다면 줄바꿈된 형태로 나온다.
HtmlWebPackPlugin 은 웹팩 빌드시 output에 있는 bundle.js를 자동으로 import 한다.
import React from "react";
import ReactDOM from "react-dom";
import Root from "./Root";
ReactDOM.render(<Root />, document.getElementById("root"));
import React from 'react';
const Root = () => {
return (
<h3>Hello, React</h3>
);
};
export default Root;
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
바벨(Babel)은 ES6에서 ES5로 자바스크립트를 변환해주는 역할을 한다.
위 코드는 바벨이 ES6와 리액트를 ES5로 변환할 수 있게 해주는 내용이다.
// ./webpack.config.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
})
]
};
npm run-script build
build 후 index.html 파일을 열면 Hello, React 가 보인다.
/*./src/style.css */
.title {
color: #2196f3;
font-size: 52px;
text-align: center;
}
// ./src/Root.js
import React from 'react';
import './style.css';
const Root = () => {
return (
<h3 className="title">Hello, React</h3>
);
};
export default Root;
이후 npm run-script build 를 하면 다음과 같이 에러가 발생한다.
CSS를 읽게 하기 위해 css-loader를 적용해야 한다.
css-loader를 추가
// ./webpack.config.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: ['css-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
})
]
};
npm run-script build
정상적으로 build가 되지만 ./build/index.html을 웹으로 열면 css 적용이 되지 않았다.
이유는 웹팩에서 css 파일을 읽은 후 어딘가에 저장을 해야하기 때문이다.
이럴 때 css를 index.html에 합치는 방법도 있지만 파일을 추출해 보도록 한다.
webpack.config.js에 css를 추출해서 파일로 저장하는 플러그인을 적용
// ./webpack.config.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
}),
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
};
추가한 코드 중 use: [MiniCssExtractPlugin.loader, 'css-loader'] 부분의 작동 순서는 오른쪽에서 왼쪽 순서로 실행 된다.
의미는 css-loader 로 css 파일을 읽고 MiniCssExtractPlugin.loader 로 읽은 css를 파일로 추출
npm run-script build
성공적으로 build 했다면 ./build/style.css 파일이 생성이 된다.
./build/index.html 파일을 웹브라우저로 열면 css가 적용된 것을 확인할 수 있다.
SCSS 가 뭔지 몰라서 아래 링크의 글을 참고했다.
// ./src/style.scss
$fontColor: #2196f3;
$fontSize: 52px;
.title {
color: $fontColor;
font-size: $fontSize;
text-align: center;
}
import React from 'react';
import './style.scss'; // 수정한 부분
const Root = () => {
return (
<h3 className="title">Hello, React</h3>
);
};
export default Root;
이 상태에서 npm run-script build 를 수행하면 에러가 발생한다.
이는 웹팩이 scss 파일을 읽을 수 없어서 나오는 에러이므로 웹팩이 scss 파일을 읽을 수 있게 loader를 설정해 주어야 한다.
// ./webpack.config.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
mode: "none",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
}),
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
};
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
css 때 와 같이 오른쪽에서 왼쪽으로 작동을 한다.
먼저 sass-loader로 scss 파일을 읽고 css로 변환한 후 css-loader로 css 읽는다. 그 후 MiniCssExtractPlugin으로 읽은 CSS를 파일로 추출
npm run-script build
성공적으로 SCSS가 적용이 된 것을 확인할 수 있다.
지금까지는 소스코드를 수정할 때마다 웹팩으로 직접 빌드를 했으나 매번 하기에는 번거롭다.
이런 불편함을 해결하기 위해 소스코드를 수정할 때마다 자동으로 웹팩이 빌드해주는 webpack-dev-server 를 적용하려 한다.
devServer 를 추가
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname + "/build")
},
devServer: {
contentBase: path.resolve("./build"),
index: "index.html",
port: 9000
},
mode: "none",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html', // public/index.html 파일을 읽는다.
filename: 'index.html' // output으로 출력할 파일은 index.html 이다.
}),
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
};
scripts 부분에 내용 추가
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --hot"
}
이후 터미널에서 npm start 를 실행하고 로컬호스트에 접속한다.
./src/Root.js 에 출력될 문자를 아무거나 바꾸고 저장하면 자동으로 빌드가 된다.
이번에는 build 디렉터리를 clean-webpack-plugin 을 통해서 빌드될 때마다 안 쓰는 파일들을 삭제할 수 있도록 해본다.
plugins의 MiniCssExtractPlugin에 filename을 style-test.css로 변경
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
filename: 'index.html'
}),
new MiniCssExtractPlugin({
filename: 'style-test.css' // 수정한 부분
})
]
이후 npm run-script build 를 한 후 build 디렉터리를 보면 사용하지 않는 style.css 가 존재하는 걸 볼 수 있다.
clean-webpack-plugin 을 추가하고 plugins 에 적용
// const CleanWebpackPlugin = require("clean-webpack-plugin"); // 추가 코드
const {CleanWebpackPlugin} = require("clean-webpack-plugin"); // 추가 코드
module.exports = {
...,
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
filename: 'index.html'
}),
new MiniCssExtractPlugin({
filename: 'style-test.css'
}),
new CleanWebpackPlugin() // 추가 코드
]
};
19.10.30 현재 위 상태로 코드를 수정한 뒤 빌드를 하면 아래와 같이 에러가 발생한다.
TypeError: CleanWebpackPlugin is not a constructor 이 곳을 참고하여
const CleanWebpackPlugin ==> const {CleanWebpackPlugin} 로 변경하니 정상적으로 동작하였다.
npm run-script build
사용 안 하는 style.css 가 삭제된 것을 확인할 수 있다.
웹팩은 빌드 모드가 Development 와 Production 에 따라 차이가 있다.
파일을 두 가지로 나누어 적용해 보기로 한다.
19.10.30 위와 같은 오류가 발생하여
const CleanWebpackPlugin ==> const {CleanWebpackPlugin} 로 변경
// ./config/webpack.config.dev.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "../build")
},
mode: "development",
devServer: {
contentBase: path.resolve(__dirname, "../build"),
index: "index.html",
port: 9000
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ["babel-loader"]
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "index.html"
}),
new MiniCssExtractPlugin({
filename: "style.css"
}),
new CleanWebpackPlugin()
]
};
19.10.30 위와 같은 오류가 발생하여
const CleanWebpackPlugin ==> const {CleanWebpackPlugin} 로 변경
// ./config/webpack.config.prod.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.[contenthash].js",
path: path.resolve(__dirname, "../build")
},
mode: "production",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: ["babel-loader"]
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "index.html"
}),
new MiniCssExtractPlugin({
filename: "style.css"
}),
new CleanWebpackPlugin()
]
};
"scripts": {
"start": "webpack-dev-server --config ./config/webpack.config.dev --hot",
"build": "webpack --config ./config/webpack.config.prod"
},
기존 webpack.config.js 와 다른점은 mode를 development 로 했냐 production 으로 했냐의 차이이다.
지금은 큰 차이가 없지만 development 와 production 에 맞는 플러그인들을 적용하면서 붙여 나가기 시작하면 mode에 따라 강점이 생길 것 이다.
npm start 와 npm run-script build 가 정상 작동하는지 확인해 본다.
React를 시작한 지 얼마 되지 않아 모르는 개념들이 너무 많았고 배워야 할 것들이 많다는 것을
다시 한번 느꼈다. 코드들이 어떻게 작동되는지 차근차근 되짚어 봐야겠다.
맥OS M1 실리콘에서 node 설치시 에러 대응법 (0) | 2021.10.21 |
---|---|
NVM으로 Node.js 설치 및 버전 변경 관리 (0) | 2021.10.11 |
자바스크립트 개발자라면 알아야하는 핵심 33개 이론 | #1. Call Stack (0) | 2021.10.11 |
javascript 변수의 주요 특성들. (0) | 2021.08.16 |
댓글 영역