"생각보다
create-react-app
없이 리액트 프로젝트를 못 만드시는 분이 많더라구요 "
우리 팀 시니어분이 화상 회의에서 지나가는 말로 위와 같은 말을 하셨던 기억이 있다. 엥? 그거 전데요?
그래서 대학생 때 했었던 Booksbridge
프로젝트를 심심해서 리팩토링하는 프로젝트를 진행해보려는 김에 create-react-app
없이 바닥부터 개발 환경을 세팅해보기로 했다.
node 패키지를 관리하는 도구는 크게 npm
과 yarn
이 있다. yarn
이 조금 더 빠르고 안정적이라고 하는데, 여기서는 일단 npm을 사용했다.
새 디렉토리를 만들고 npm init
명령어로 해당 디렉토리를 node 프로젝트 패키지로 만들 수 있다.
npm init
을 실행하면 package name, version, git repo 등 해당 프로젝트의 여러 기본 정보를 설정할 수 있는데, 어차피 나중에라도 수정할 수 있으므로 자유롭게 기입한다.
만약 모두 기본값으로 설정하고 싶다면 npm init -y
를 사용하면 된다.
타입이 없는 언어는 근본이 없는 언어이다.
내가 늘 하는 소리이다 (아마도 농담임). typescript
는 근본 없는 javascript
에 근본을 부여한다. 프로젝트에 근본을 불어넣기 위해서, typescript 모듈을 설치하자.
npm install -D typescript
이제 package.json
의 devDependencies
에 타입스크립트가 추가되었다!
"devDependencies": {
"typescript": "^4.4.3"
}
해당 프로젝트 내에서 타입스크립트의 설정을 셋업하기 위해 tsconfig.json
파일을 만들어보자. 이 파일도 처음부터 만들 수 있지만, 그건 너무 귀찮으니 tsc --init
명령어로 tsconfig.json
을 자동으로 생성하자.
tsconfig.json
파일의 각 엔트리가 의미하는 바는 옛날에 내 레포에 정리해뒀으니 참고하면 되겠다.
webpack
의 주 목적은 js뿐만 아니라 css나 이미지 등 여러 자원(모듈)들을 번들링하여 브라우저에게 제공하는 것이다. 프로젝트에서 웹팩을 사용하기 위해 다음 명령어를 사용하자.
npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin ts-loader
웹팩을 제대로 실행하기 위해서 webpack.config.js
파일을 새로 만들어 설정해야 한다. 다음과 같이 설정하자.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
// src/index.tsx` 파일을 진입점으로 설정
entry: path.resolve(__dirname, 'src/index.tsx'),
resolve: {
alias: {
'@booksbridge': path.resolve(__dirname, 'src')
}
},
module: {
rules: [
{
// .ts, .tsx 파일들을 ts-loader를 이용해 컴파일하여 번들링
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
},
use: 'ts-loader',
}
]
},
devServer: {
historyApiFallback: true // SPA를 위한 설정
},
plugins: [
// index.html`에 번들링된 스크립트 파일과 스타일이 자동으로 연결
new HtmlWebpackPlugin({
template: 'index.html'
}),
]
};
resolve
에 alias
설정을 한 이유는, 파일에서 상대경로로 참조하지 않고 절대경로로 더 간편하게 참조하도록 하기 위해서이다.
상대경로 참조
import SomeComponent from '../../../components/SomeComponent'
절대경로 참조
import SomeComponent from '@booksbridge/components/SomeComponent'
웹팩 설정을 끝마쳤으므로, package.json
에서 스크립트 설정을 해줄 수 있게 되었다.
"scripts": {
"start": "webpack serve --port 3000",
"build": "webpack"
}
프로젝트 설정 완료 후 npm start
나 npm build
처럼 실행할 수 있을 것이다.
루트 디렉토리에 index.html
파일을 생성해주자. 아래 내용을 쓸 것이다.
<!DOCTYPE html>
<html>
<head lang="en">
<title>Booksbridge</title>
</html>
<body>
<div id="app-root"></div>
</body>
애초에 리액트 프로젝트를 하기로 했으니 리액트를 설치해야 한다.
npm install -S react react-dom
그런데 나는 이 프로젝트를 타입스크립트로 진행하기로 했다. 따라서 react
와 react-dom
의 타입 정보도 같이 가져와야 한다.
npm install -S @types/react @types/react-dom
위에서 src/index.tsx
와 index.html
에 대해 설정을 해주었으니, 당연히 이 경로에 파일들을 만들어주어야 한다.
아래와 같은 디렉토리 구조가 될 것이다.
/booksbridge
└src
└index.tsx
└index.html
└package-lock.json
└package.json
└tsconfig.json
└webpack.config.js
└.gitignore
└node_modules
css 파일을 번들링하여 최종 결과물에 포함시키기 위해서는 css loader도 설정해야 한다.
npm install style-loader css-loader
그런데 요즘 핫한 sass
도 쓰고 싶어졌다.
npm install sass sass-loader node-sass
css loader를 받았으니, webpack.config.js
에 설정값을 넣어주어야 한다. loader를 사용하기 위해 module.rules
에 다음과 같은 설정을 덧붙여주자.
module: {
rules: [
...({/*typescript loader 설정값*/}),
{
test: /\.s[ac]ss$/i, // .scss, .sass파일에 적용하는 규칙
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
]
}
이제 모든 것이 준비되었고, 프로젝트를 시작하면 된다. 가장 기초적인 리액트 컴포넌트를 로드하도록 설정하자.
src/
디렉토리 밑에 App.tsx
파일을 생성하자.
// src/App.tsx
import React, { FC } from 'react'
const App: FC = () => {
return (
<div>
{'Hello, World!'}
</div>
)
}
export default App
App
컴포넌트를 index.tsx
에서 불러와서 렌더해주자.
// src/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from '@booksbridge/App'
ReactDOM.render(
<App />,
document.getElementById('app-root')
)
이제 yarn start
명령어로 로컬서버를 띄우고 localhost:3000
으로 접속하면 Hello, World!
가 보일 것이다!
사람들이 하도 오타를 내서 npm install
을 npm isntall
로 써서인지, npm isntall
도 npm install
과 똑같이 동작하도록 되어있다. 정말 자비로우십니다 선생님.