React + Webpack + SWC + TypeScript + tailwindCSS
- 마이그레이션을 하며 거치는 과정을 배우는 것이 목표 (새로운 CRA로 ts 구성하지 않음)
- 목표하는 프로젝트는 create-react-app으로 구성되지 않고 직접 package.json으로 의존성 구현.
- react-dom, react-router-dom, swc, webpack과 같은 패키지를 yarn으로 설치했음
- 타입스크립트는 기본적으로 개발단에서 쓰이는 것이기 때문에 항상 devDependencies에 설치되도록 yarn add -D 또는 npm install --save-dev 명령어로 설치한다.
- PostCSS 플러그인을 사용해 TailwindCSS 스타일링을 Webpack에 세팅
1. 기존의 프리셋 프로젝트에서 Typescript 설치
- 기존 프리셋 프로젝트의 package.json, .swcrc, webpack.config.js
// package.json
{
"name": "react-webpack-swc",
"author": "Joon Park",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.19.0"
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.27",
"@types/react": "^18.2.38",
"@types/react-dom": "^18.2.16",
"@types/react-router-dom": "^5.3.3",
"html-webpack-plugin": "^5.5.0",
"swc-loader": "^0.2.3",
"typescript": "^5.3.2",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
{
"jsc":{
"parser": {
"syntax": "ecmascript",
"jsx": true
},
"transform": {
"react":{
"runtime": "automatic"
}
},
}
}
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.jsx',
output: {
path: path.join(__dirname, '/dist'),
filename: 'index_bundle.js'
},
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 3000,
},
resolve: {
extensions: ['.jsx', '.js', '.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /(node_modules)/,
use: {
loader: "swc-loader"
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: "./index.html",
template: path.join(__dirname, 'public/index.html')
})
]
}
- 아래 명령어를 터미널에서 입력해서 프로젝트에 타입스크립트와 바벨을 설치해준다
⚙ **`yarn add -D typescript fork-ts-checker-webpack-plugin HTMLWebpackPlugin @types/react @types/react-dom @types/react-router-dom`**
2. 타입스크립트 세팅 및 webpack 설정 변경
- tsconfig.json 파일 생성 및 세팅
- .swcrc 파일에 타입스크립트용 세팅 변경
- webpack.config.js 파일 세팅 변경
// tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"incremental": true,
"baseUrl": "src"
},
"include": [
"src"
]
}
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false,
"dynamicImport": false
},
"transform": {
"react": {
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"runtime": "automatic",
"throwIfNamespace": true,
"development": false,
"useBuiltins": false
},
"optimizer": {
"globals": {
"vars": {
"__DEBUG__": "true"
}
}
}
}
}
}
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/index.tsx',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'build'),
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new HTMLWebpackPlugin({
template: './public/index.html',
}),
],
devServer: {
static: path.resolve(__dirname, 'public'),
historyApiFallback: true,
hot: true,
open: true,
port: 3000,
},
resolve: {
extensions: ['.jsx', '.js', '.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
loader: 'swc-loader',
}
],
},
};
3. Tailwind 설치 및 세팅, webpack 설정 변경
⚙ `**yarn add -D tailwindcss postcss autoprefixer style-loader css-loader postcss-loader postcss-preset-env**`
- tailwind.config.js 파일 생성 후 테일윈드 세팅
- postcss.config.js 파일 세팅 변경
module.exports = {
content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
module.exports = {
...
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
loader: 'swc-loader',
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
],
},
};
4. 실행 확인 및 리포지토리 최신화
시행착오
- 기존 babel js 리액트 프로젝트에서 typescript로 마이그레이션 해 본 경험이 있어서 ts마이그레이션은 쉬웠지만 오히려 Tailwind 설치와 세팅에서 애를 먹었다
- css-loader가 없는 상황에서 TailwindCSS를 위해 설치하는 패키지만 해도 무려 7개…
- 막상 설치 후에 webpack 설정은 sass 세팅과 비슷해서 쉽게 진행되었다.
연구 포인트