1. React와 TypeScript 설치
먼저, React와 TypeScript를 설치하겠습니다. TypeScript 의존성은 .ts 파일을 컴파일하는 데 사용됩니다.
npm i react react-dom
npm i -D typescript
2. Webpack 설치
다음으로, Webpack을 설치합니다. Webpack은 모듈 번들러로, 개발 중과 빌드 과정에서 유용하게 사용됩니다.
npm install -D webpack webpack-cli webpack-dev-server
3. 로더 설치
CSS 스타일을 적용하기 위해 style-loader와 css-loader를 설치합니다. 또한, 빠른 번들링을 위해 esbuild-loader를 사용할 것입니다.
npm i -D style-loader css-loader esbuild-loader
각 로더의 역할은 다음과 같습니다:
- css-loader: CSS를 JavaScript 파일에서 import할 수 있게 해줍니다.
- style-loader: 스타일을 HTML 파일에 적용시키기 위한 로더입니다. CSS의 Hot Module Replacement(HMR)를 사용하기 위해 필요합니다.
- esbuild-loader: 빠른 번들링을 제공합니다. 이는 babel-loader, ts-loader보다 성능이 뛰어납니다.
4. Webpack Plugin 설치
추가적으로 필요한 Webpack Plugin을 설치합니다. html-webpack-plugin, fork-ts-checker-webpack-plugin, dotenv-webpack을 사용할 것입니다.
npm i -D html-webpack-plugin fork-ts-checker-webpack-plugin dotenv-webpack
각 플러그인의 역할은 다음과 같습니다:
- html-webpack-plugin: HTML 파일을 생성하고, 빌드된 자산을 해당 HTML 파일에 자동으로 포함시켜줍니다.
- fork-ts-checker-webpack-plugin: TypeScript 타입 검사 및 린팅 작업을 Webpack 빌드와 병렬로 수행합니다.
- dotenv-webpack: 빌드 과정에서 .env 파일의 환경 변수를 로드하여 함께 번들링합니다.
5. Webpack 설정 파일 작성
이제 Webpack 설정 파일을 작성해보겠습니다.
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const Dotenv = require('dotenv-webpack');
module.exports = {
entry: './src/main.tsx',
module: {
rules: [
// type: 'asset'을 지정해줌으로서, file-loader, url-loader, @svgr/webpack의 설치가 필요없어졌습니다.
// <https://webpack.kr/guides/asset-modules/#general-asset-type>
{
test: /\\.(png|svg|jpe?g|gif|webp)$/i,
type: 'asset',
parser: {
// maxSize의 용량값보다 작은 경우 인라인(Base64 형식으로 인코딩)으로, 그 이상일 경우 별도 파일로 분리합니다.
dataUrlCondition: {
maxSize: 4 * 1024, // 4KiB를 기준으로 합니다.
},
},
generator: {
filename: 'assets/images/[name]_[contenthash:8][ext]',
},
},
// esbuild-loader 세팅
{
test: /\\.(js|jsx|ts|tsx|mjs)$/,
exclude: /node_modules/,
loader: 'esbuild-loader',
options: {
target: 'es2020',
},
},
// 스타일 관련 loader 세팅
{
test: /\\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
// 절대 경로 세팅
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs'],
alias: {
'@': path.resolve(__dirname, 'src/'),
'@components': path.resolve(__dirname, 'src/components/'),
'@assets': path.resolve(__dirname, 'src/assets/'),
'styled-system': path.resolve(__dirname, 'src/styled-system/'),
},
},
// 번들링 세팅
output: {
filename: '[name]_[chunkhash:8].js',
path: path.resolve(__dirname, 'dist'),
clean: true, // webpack5의 기능으로, 빌드시마다 자동으로 dist의 파일을 삭제하고 새로 빌드합니다.
},
// 플러그인 세팅
plugins: [
// 번들링시 html 파일을 생성합니다.
new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
}),
// esbuild-loader는 ts-loader와 다르게 컴파일시 타입 체킹이 되지 않습니다. 따라서 아래 플러그인을 통해서 체킹해줍니다.
new ForkTsCheckerWebpackPlugin({
async: false,
typescript: {
configFile: path.resolve(__dirname, 'tsconfig.json'),
},
}),
// 빌드 과정에서 환경변수를 로드합니다.
new Dotenv(),
],
};
6. Webpack 설정 파일 분리
개발과 프로덕션 환경을 구분하여 설정 파일을 분리합니다.
package.json
{
//...
"scripts": {
"build": "webpack --config webpack.prod.js",
"dev": "webpack-dev-server --config webpack.dev.js --open --hot"
}
//...
}
webpack.dev.js
// webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.config.js');
module.exports = merge(common, {
mode: 'development',
// <https://webpack.kr/configuration/devtool/#root>
devtool: 'eval-source-map',
// webpack-dev-server 설정입니다.
devServer: {
/*
HTML5HistoryAPI를 사용하기 위해선 이 설정을 true로 하여야 합니다.
React와 같은 SPA의 경우, HTML5HistoryAPI를 사용하여 라우트를 구현합니다.
따라서 이 설정을 활성화 하지 않는 경우 라우트 에러가 나타날 수 있습니다.
*/
historyApiFallback: true,
port: 3000,
hot: true, // Hot Module Replacement를 사용합니다.
},
});
webpack.prod.js
// webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.config.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'hidden-source-map', // 에러 보고 목적으로 소스맵을 사용할 때 선택합니다.
});
이렇게 React와 TypeScript 환경을 구축하기 위한 모든 설정이 완료되었습니다. 이제 개발 환경과 프로덕션 환경 모두에서 효율적으로 작업을 진행할 수 있게 되었습니다!
반응형