자바스크립트 환경 웹팩과 바벨
WebPack
웹팩은 자바스크립트 애플리케이션을 위한 정적 모듈 번들러라고 소개하고 있다.
그렇다면 번들러란 무었일까? 번들러는 의존성이 있는 모듈들을 하나의 파일로 통합시켜주는 도구이다. 그렇다면 왜 번들러를 사용할까?
번들러는 무엇일까?
JS, CSS, 이미지 등의 파일을 묶어주는 작업을 '번들링(Bundling)'이라고 하고, 작업의 결과물은 '번들(Bundle)'이라고 한다. 웹팩 자체는 묶어주는 역할을 하기 때문에 '번들러(Bundler)'라고 한다,
번들링 과정이 끝나면 기존 스크립트에서 import/export가 사라지기 때문에 type="module"이 필요 없어진다. 따라서 번들링 과정을 거친 스크립트는 일반 스크립트처럼 취급한다.
웹팩은 왜 쓰는 걸까?
우선, 웹팩을 여러 개의 파일을 하나로 번들링하기 때문에 HTTP 요청 횟수를 줄일 수 있다. 이는 빠른 서비스 제공에 도움이 된다.
(브라우저마다 HTTP요청 횟수에 제한을 두고 있기도 하다.) 또한, 자바스크립트 외의 리소스 포맷의 모듈도 사용할 수 있게 해 준다.
CSS든, 이미지든 사용하려는 곳에 해당 리소스를 import 해주기만 하면 웹팩이 알아서 빌드해준다! 웹팩이 알아서 자동화해주는 덕분에, 코드를 수정했을 때 다시 빌드하고 새로고침 하지 않아도 바로바로 빌드 결과를 확인할 수 있다.
모듈 단위로 개발할수 있어 이후에 유지보수성을 높일 수 도 있다,
웹팩설치하기
npm i -D webpack webpack-cli
npm i -D react-refresh @pmmmwh/react-refresh-webpack-plugin
npm i -D webpack-dev-server
- webpack: 웹팩 모듈
- webpack-cli: 터미널에서 웹팩 명령어를 사용할 수 있게 도와줌
- 리액트 리프레쉬 사용방법
- react-refresh @pmmmwh/react-refresh-webpack-plugin
- webpack-dev-server: nodemon과 같이 웹팩 환경에서 개발서버를 생성
webpack 속성들
- mode : 모드에 따라 번들링 최적화를 진행한다. (development/production)
- entry : 웹팩에서 웹 자원을 변환하는 데 필요한 진입점이자 자바스크립트 파일 경로. 번들링 시작점.
- module : 웹팩에서 사용하는 모듈에 대한 설정/ 웹팩 로더 설정. rules 로 loader를 설정한다.
- ouput : 웹팩을 돌리고 난 결과물의 파일 경로. 번들링 결과물 경로 및 이름을 지정한다.
- plugins : 기본적인 동작에 추가적인 기능을 제공한다. 확장 프로그램 같은 것.
- target : 웹팩에서 번들링 결과를 어떤 목표로하는지 설정한다. (web, webworker, es5, es2020, node0
- devtool : 소스맵 생성 관련 설정(source-map, inline-source-map 등)
전체적인 과정으로 entry에 있는 파일에 module적용하고 추가적으로 plugins사용해 output으로 출력한다.
const path = require("path");
const ReFreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module.exports = {
name: "",
mode: "development", // 실서비스:production
devtool: "eval",
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client"],
}, //입력
module: {
rules: [
{
test: /\.jsx?/,
// 리엑트 자동 컴파일
plugins: ["react-refresh", "@babel/plugin-proposal-class-properties"], // "react-refresh/babel", "@babel/plugin-proposal-class-properties"
},
},
],
},
plugins: [new ReFreshWebpackPlugin()],
output: {
filename: "app.js",
path: path.join(__dirname, "dist"),
publicPath: "/dist/",
}, //출력
devServer: {
publicPath: "/dist/",
hot: true,
},
};
바벨이란?
바벨(Babel)은 코드 변환기다. 세상 사람들은 정말 다양한 종류의 버전의 브라우저를 사용하고 있다. 모든 사람들이 최신의 브라우저로 업데이트 하지 않는다. 하지만 그 사람들은 놓고 서비스 개발을 진행 할수없기 떄문에 최대한 모든 사람들이 불편없이 사용하도록 개발해야 한다. 이러한 이유로 개발자들은 최신의 코드를 쓰면서 최대한 많은 사람들의 불편함을 없게 만들어 주는게 바벨이다. 바벨은 최신 자바스크립트 문법을 구형 브라우저에도 돌아갈수있게 코드를 변환시켜주는 역활을 한다.
바벨 설치하기
npm i -D @babel/core
npm i -D @babel/preset-env
npm i -D babel-loader
npm i -D @babel/plugin-proposal-class-properties
npm i -D @babel/preset-react
- babel-core: 웹팩용 바벨(?)이다. 터미널에서 쓸 때 babel-cli를 썼는데 이걸 웹팩에서 사용하는 용도다.
- babel-preset-env: 바벨은 babel-preset-es2017과 같이 여러 버전이 있다. 딴거 말고 이거 깔면 알아서 해준다.
- babel-loader: 웹팩에서 바벨을 로드할 때 이 로더를 쓴다.
- @babel/plugin-proposal-class-properties : 클래스의 프로퍼티를 사용할 수 있게 도와주는 바벨 플러그인
- babel-preset-react: 바벨을 리액트에서 사용하게 해준다. 우리는 리액트를 쓸거니까 이게 필요하다. 달리 말하면 바벨과 리액트는별개 프로젝트다.
webpack.config.js
{
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: ["> 5% in KR"], //browerslist
},
debug: true,
},
],
"@babel/preset-react",
],
// 리엑트 자동 컴파일
plugins: ["react-refresh/babel", "@babel/plugin-proposal-class-properties"],
},
}
바벨과 웹펙 한번에 작성
const path = require("path");
const ReFreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module.exports = {
name: "",
mode: "development",
devtool: "eval",
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client"],
}, //입력
module: {
rules: [
{
test: /\.jsx?/,
// 바벨 설정
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: ["> 5% in KR"], //browerslist
},
debug: true,
},
],
"@babel/preset-react",
],
// 리엑트 자동 컴파일/바벨
plugins: ["react-refresh/babel", "@babel/plugin-proposal-class-properties"],
},
},
],
},
plugins: [new ReFreshWebpackPlugin()],
output: {
filename: "app.js",
path: path.join(__dirname, "dist"),
publicPath: "/dist/",
}, //출력
devServer: {
publicPath: "/dist/",
hot: true,
},
};
//pakage.json에서 명령어 변경
"scripts": {
"dev" : "webpack serve --env development"
},
npm run dev로 실행가능