1.프로젝트 폴더 생성 및 초기화
mkdir my-typescript
cd ./my-typescript
npm init -y
결과 : my-typescript 폴더 안에 package.json 파일 생성
2. 리액트 설치
npm install react react-dom
or
yarn add react react-dom
react : 리액트 라이브러리
react-dom : 리액트 엘리멘트 렌더링 라이브러리
3. 타입스크립트 설치
npm i -D typescript @types/react @types/react-dom
typescript : 타입스크립트 라이브러리
@types/react : 리액트를 위한 타입 정의 파일
@types/resct-dom : 리엑트 돔을 위한 타입 정의 파일
4. 웹팩 설치
npm install -D webpack webpack-cli webpack-dev-server
webpack : 개발자의 코드와 소스를 하나로 합쳐주는 번들러
webpack-cli : 웹팩의 커맨드를 이용해 빌드나 실행을 하기 위함
webpack-dev-server : 핫로딩 사용하기 위해 설치
5. 웹팩 로더와 플러그인 설치
npm install -D css-loader sass-loader style-loader url-loader ts-loader
로더 : 모듈(js, css, png 등)을 자바스크립트 코드 안으로 가져온다.
css-loader : css 확장자 파일을 찾으면 안의 내용을 처리해서 자바스크립트 코드 안으로 가져옴
sass-loader : sass,scss 확장자 파일 안의 내용을 css로 변환
style-loader : css를 html의 style태그를 생성해 넣음
url-loader: 파일 내용을 모듈에 문자열 형태로 추가
ts-loader : .ts 나 .tsx 로 끝나는 파일들을 처리하여 번들링
npm install -D html-webpack-plugin mini-css-extract-plugin
html-webpack-plugin : html 파일에 번들된 js 파일을 자동 연결해서 생성
mini-css-extract-plugin : css 파일을 별도의 파일로 추출
6. 웹팩 설정 webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
index: path.resolve('./index.tsx');
},
output: {
path: path.resolve('./build'),
filename: '[name].[contentshash].js',
publicPath: '/',
clean: true,
assetModuleFilename: '[name][ext]'
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src/components'),
},
extensions: [".ts", ".tsx", ".js", ".jsx"]
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader"
}
]
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
{
test: /\.(scss|css)/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(ico|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|otf)(\?v=[0-9]\.[0-9])?$/,
use: [
{
loader: "url-loader",
options: {
name: "[hash].[ext]",
limit: 10000
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
templateParameters: {
env: process.env.NODE_ENV === "development" ? "(개발용) " : ""
}
}),
new webpack.BannerPlugin({
banner: `Build Time: ${new Date().toLocaleString()}`
})
],
devServer: {
static: {
directory: path.resolve(__dirname, 'build')
},
open: true,
hot: true,
compress: true,
port: 5500,
historyApiFallback: true
}
}
entry : 웹팩이 번들링을 하기 위해 진입하는 입구, 객체로 할 경우 key 가 output 의 [name].js 의 name에 들어감
contentshash: 번들링 결과물에 고유 해시를 부여해서 브라우저가 해당 파일을 새로 불러올 수 있게 함
output : 번들링 결과물의 경로와 파일명 지정
output.publicPath : 번들링 과정에서 내부에서 사용된 url들의 prefix 역할, webpack-dev-server가 hdd가 아닌 ram에 있는 번들된 소스를 브라우저에게 주게 하는 역할
output.clean: 기존 파일을 삭제해 정리한 후, 다시 번들링 결과물을 경로에 넣는 옵션
output.assetModuleFilename: asset용 번들링된 결과물의 파일명 지정
resolve : module을 해석하는 방식 설정
alias : 특정 모듈의 별칭을 정할 수 있음
extentions : 확장자를 순서대로 해석. 여러 파일에서 이름이 동일하지만 다른 확장자를 가진 경우, webpack은 배열의 앞에서부터 파일을 해석하고 남은 것은 해석하지 않음.
module : loader를 넣을 객체
rule : loader를 객체로 가진 배열
test : 어떤 파일을 loader로 적용할 지 정규식으로 결정
exclude : loader에서 제외할 파일이나 폴더
use : 사용할 loader의 이름과 옵션
devtool : 번들링된 결과물에서 에러가 났을 때, 원본 소스코드에서 해당 부분을 찾을 수 있게 연결해주는 역할
plugin : 번들링 결과물에 추가하고 싶은 일이 있을 때 사용
htmlWebpackPlugin 의 template : 빌드 결과물에 사용할 index.html 의 템플릿 경로
htmlWebpackPlugin 의 templateParameters : index.html에서 사용할 변수
BannerPlugin : 빌드결과물에 배너를 생성
devServer.static.directory: 데브 서버가 호스팅할 파일의 경로
devServer.open : 서버가 올라가면, 브라우저를 열지 여부
devServer.hot: 파일 내 변경이 생기면 자동으로 빌드해 리로드할지 여부
devServer.compress: gzip 으로 압축 여부
devServer.port : 사용할 포트
devServer.historyApiFallBack : 404대신 index.html을 보여줄지 여부
7. 타입스크립트 설정 tsconfig.js
{
"compilerOptions": {
"target": "ES2016",
"module": "CommonJS",
"noImplicitAny": true,
"jsx": "react"
}
}
tsconfig.js : 프로젝트의 최상위 루트에 존재하며, 프로젝트를 컴파일하는데 필요한 옵션을 제공하는 파일
target : typescript 파일을 원하는 target 버전의 javascript로 변경해줌
module : javascript 파일 간의 import 구문을 해석할 모듈 언어 설정.
noImplicitAny : any 타입이 개발자 의도와 다르게 발생했을 때 경고
jsx : jsx 파일을 어떻게 컴파일할 것인지 결정
8. 최상위 인덱스 파일 index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { Hello } from './src/Hello';
const container = document.getElementById('example')! as HTMLElement;
const root = ReactDOM.createRoot(container);
root.render(<Hello compiler='TypsScript' framework='React' />);
9. hello world 를 보기 위해 파일 하나 더 추가 src/Hello.tsx
import * as React from "react";
export interface HelloProps { compiler: string; framework: string; }
export const Hello = (props: HelloProps) => <h1>Hello from {props.compiler} and {props.framework}!</h1>;
10. 실행하기 위해 스크립트 추가 package.json
"scripts": {
"start": "NODE_ENV=development webpack-dev-server --mode development",
"build": "webpack --mode production"
},
11. 정적 파일 추가 public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.templatePramaeters.env =></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
끝