2개월만에 이어서 작성하는 No CRA 개발환경 구축기 2편
5. Babel 설정
Babel이란?
- ES6+ 코드를 이전 JavaScript 엔진에서 실행할 수 있는 코드로 변환하는 트랜스컴파일러이다.
- 전세계의 모든 브라우저가 ES6를 지원하는 것은 아니기 때문에 JSX를 일반 자바스크립트 코드로 변환한다.
- 변환한 소스 코드를 번들링 도구인 Webpack에 전달한다.
관련 패키지 설치
npm i -D babel-loader @babel/core @babel/preset-env
- babel-loader : Webpack이 자바스크립트 파일을 처리할 때 Babel을 사용하도록 하기 위함
- @babel/core : Babel의 핵심 기능을 제공
- @babel/preset-env : 자바스크립트 코드를 변환할 때 필요한 Babel 플러그인을 자동으로 결정해주는 프리셋(=여러 플러그인의 집합)
npm i -D @babel/preset-react @babel/preset-typescript
- @babel/preset-react : React와 JSX 문법을 사용할 때 필요한 Babel 변환 설정을 제공하는 프리셋
- @babel/preset-typescript : TypeScript 코드를 일반 JavaScript 코드로 변환할 때 필요한 설정을 제공하는 프리셋
babel.config.js
module.exports = {
presets: [
"@babel/preset-react",
"@babel/preset-env",
"@babel/preset-typescript",
],
};
6. Webpack 설정
Webpack 이란?
- 웹에서 사용되는 모든 자원(assets)들을 번들링 해주는 도구 (*번들링 : 여러 개의 파일 중 종속성이 존재하는 파일을 하나의 파일로 묶어 패키징을 시키는 과정)
- ex) CSS가 아닌 Sass, 또는 JS 대신 TypeScript 사용 시 번들러가 컴파일 과정에서 필요한 플러그인을 추가하고 번들러를 실행해준다
- 파일이 하나로 합쳐지기 때문에 네트워크 요청 횟수가 줄어들고, 중복된 소스코드가 최소화되는 장점이 있지만 웹팩만 단독 사용시 패키징만 해주기 때문에 다른 트랜스파일러인 babel과 주로 함께 사용됨
관련 패키지 설치
npm i -D webpack webpack-cli webpack-dev-server webpack-merge
- webpack-cli: Webpack을 커맨드 라인에서 사용할 수 있게 해주는 도구. 빌드를 시작하거나, Webpack 설정 파일을 사용하는 등의 작업을 할 수 있다
- webpack-dev-server: 내장된 웹 서버를 제공하여 localhost의 특정 포트에서 웹 애플리케이션을 서빙, 개발 과정에서 실시간으로 변경사항을 확인하는 라이브 리로딩 가능
- webpack.config.js에서 ‘devServer’ 옵션을 설정하여 포트번호 지정
module.exports = { devServer: { contentBase: './dist', port: 3000 } };
- webpack-merge: Webpack 설정 파일을 쉽게 병합할 수 있게 해주는 유틸리티. 보통 모든 환경에서 공통적으로 사용되는 설정은 webpack.common.js에 유지하고, 개발, 테스트, 프로덕션 등 환경별 특화 설정은 별도의 파일(예: webpack.prod.js, webpack.dev.js)에 관리한다.
npm i -D ts-loader file-loader clean-webpack-plugin html-webpack-plugin
- ts-loader: Webpack 자체는 기본적으로 JavaScript와 JSON 파일만 이해할 수 있기 때문에, 다양한 유형의 파일을 이해하고 처리할 수 있도록 로더가 필요하다. ts-loader는 TypeScript 파일을 JavaScript로 변환해주는 역할을 함.
- Q. 앞서 babel-loader와 @babel/preset-typescript를 설치했는데 ts-loader도 설치할 필요가 있을까? 🤔
이미 두 조합으로도 TS → JS로 변환하는데 충분하지만 프로젝트에서 타입 검사를 자동화하기 위해 ts-loader를 별도로 설치했다. (설치하지 않으면 Babel에서 타입 검사를 하기 위해선 명령줄에서 tsc 명령어를 사용하거나 IDE의 내장 기능을 사용해야 한다)
- Q. 앞서 babel-loader와 @babel/preset-typescript를 설치했는데 ts-loader도 설치할 필요가 있을까? 🤔
- ts-loader: Webpack 자체는 기본적으로 JavaScript와 JSON 파일만 이해할 수 있기 때문에, 다양한 유형의 파일을 이해하고 처리할 수 있도록 로더가 필요하다. ts-loader는 TypeScript 파일을 JavaScript로 변환해주는 역할을 함.
-
- file-loader : 이미지, 폰트, 3D 모델 파일 등과 같은 정적 파일들 사용시 설치
- clean-webpack-plugin: Webpack이 빌드를 할 때마다 이전에 생성된 빌드 파일들을 삭제하여 불필요한 파일이나 오래된 파일들이 축적되는 것을 방지
- html-webpack-plugin: 빌드시 Webpack이 생성하는 번들(JavaScript, CSS 파일 등)을 HTML 파일에 자동으로 삽입해주는 플러그인 (아래는 예시)
// 빌드 완료시, dist 폴더 내에 index.html 파일과 bundle.js 파일이 생성된다.
// index.html 파일 내에 bundle.js 스크립트 태그를 자동으로 삽입하는 것을 확인
<!DOCTYPE html>
<html>
<head>
<title>Webpack 예시</title>
</head>
<body>
<h1>아래에 자동으로 스크립트가 추가된다</h1>
<script src="bundle.js"></script>
</body>
</html>
- (+) 당시 프로젝트 기술로 CSS-in-JS 라이브러리인 스타일드 컴포넌트를 사용했기 때문에 별도로 style-loader, css-loader, postcss-loader, sass-loader와 같은 CSS 처리 로더는 설치하지 않았다.
webpack.common.js
웹팩 설정 파일
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
entry: './src/index.tsx', // Webpack이 빌드를 시작하는 진입점
resolve: { // 모듈 해석 방법을 정의
extensions: ['.js', '.jsx', '.ts', '.tsx'], // Webpack이 해석할 파일 확장자들
alias: {
'@': path.resolve(__dirname, 'src'), // src 디렉토리를 '@'로 별칭 지정
},
},
module: {
rules: [ // 파일을 처리하는 방법에 대한 규칙 정의
{
test: /\.tsx?$/,
use: ['babel-loader', 'ts-loader'],
},
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: 'file-loader',
},
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.(glb|gltf)$/, // 3D 모델 애셋 파일 관련
use: [
{
loader: 'file-loader',
options: {
outputPath: 'assets/models/',
},
},
],
},
],
},
output: { // 생성한 번들의 출력 위치와 파일 이름 정의
path: path.join(__dirname, '/dist'),
filename: 'bundle.js',
},
plugins: [
// ./public/index.html을 템플릿으로 사용하여 HTML 파일을 생성하고,
// 생성된 번들을 자동으로 삽입
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new CleanWebpackPlugin(), // 빌드 시 output.path의 이전 빌드 파일 삭제
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env),
}),
],
};
webpack.dev.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
// webpack.common.js에서 작성했던 공통 설정과 개발 환경 특화 설정을 결합
module.exports = merge(common, {
mode: "development", // 개발 환경에 최적화된 빌드를 수행
devtool: "eval", // 빌드 속도가 빠르나 디버깅에 최적화된 소스 맵은 생성하지 않음
devServer: {
historyApiFallback: true, // SPA 라우팅에 필요한 설정
port: 3000,
hot: true, // 코드 변경 시 전체 페이지 새로고침 없이 해당 모듈만 교체
},
});
webpack.prod.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
// webpack.common.js에서 작성했던 공통 설정과 프로덕션 환경 특화 설정을 결합
module.exports = merge(common, {
mode: "production",
devtool: "hidden-source-map",
});
- production mode : 코드 압축, 트리 쉐이킹(사용되지 않는 코드 제거), 번들 사이즈 축소, 성능 향상 등의 최적화를 수행
- hidden-source-map : 에러가 발생했을 때 원본 코드의 위치를 알 수 있도록 소스 맵을 생성하지만, 최종 사용자에게는 코드 구조를 숨기기 위해 개발자 도구에서는 보이지 않게 한다.
package.json
//package.json
...
"scripts": {
"dev": "webpack-dev-server --config webpack.dev.js --open --hot",
"build": "webpack --config webpack.prod.js",
"start": "webpack --config webpack.dev.js"
},
...
→ Node.js 프로젝트에서 Webpack을 실행하기 위해 실행하는 npm 스크립트를 정의한다.
npm run dev
: 주로 개발 중에 사용되며, dev server를 시작하고, 코드 변경 시 자동으로 리로드.- --config webpack.dev.js : webpack.dev.js 파일을 Webpack 설정으로 사용
- --open : 서버가 시작될 때 브라우저를 자동으로 열기
- --hot : 핫 모듈 교체(Hot Module Replacement, HMR)를 활성화 (= 코드를 변경 및 저장할 때 전체 페이지를 새로고침 하지 않고 변경사항을 반영)
npm run build
: 배포 전에 실행하는 스크립트로, 프로덕션 환경을 위해 애플리케이션을 빌드- --config webpack.prod.js : webpack.dev.js 파일을 Webpack 설정으로 사용
npm start
: 개발 환경의 Webpack 빌드를 실행. 브라우저를 열어 코드의 변경사항이 어떻게 적용되는지 확인하는 용도보다는, 브랜치에 병합될 때 빌드를 실행하여 결과물을 검증하는 데 사용한다.
>>>
그동안 npm run dev... npm start를 수없이 사용했는데도 이런 설정 덕에 가능했단걸 이제서야 알게 되었다 !
바벨과 웹팩 설정을 하나씩 뜯어보면서 빌드 및 개발 과정이 어떤 설정에 의해 어떻게 영향을 받는지 알 수 있었다 :->
마지막으로, prettier & eslint 설정과 vscode의 settings.json 설정까지 알아보고 개발 환경 세팅에 관한 글을 마무리 지어야겠다 - !
'React' 카테고리의 다른 글
CRA 없이 React + TypeScript 개발환경 구축하기 (3/3) - ESLint, Prettier 설정 (0) | 2024.01.23 |
---|---|
CRA 없이 React + TypeScript 개발환경 구축하기 (1/3) (0) | 2023.11.05 |
React | TIL | 지난 프로젝트의 index.tsx 되짚어보기 (0) | 2023.08.30 |