const tsxRegex = /\.(ts|tsx)$/;
extensions: ['*', '.ts', '.tsx', '.js', '.jsx']
{
test: tsxRegex,
exclude: /node_modules/,
include: path.resolve(__dirname, './src'),
use: [
{
loader: "ts-loader",
}
]
},
{
test: tsxRegex,
exclude: /node_modules/,
include: path.resolve(__dirname, './src'),
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/env', '@babel/react', '@babel/typescript'],
plugins: [
["@babel/transform-runtime", {
regenerator: true
}], ...plugin
],
},
},
]
},
{
"compilerOptions": {
/* Language and Environment */
"target": "es5",
"jsx": "react",
/* Modules */
"module": "commonjs",
"rootDir": "./src",
"moduleResolution": "node",
"baseUrl": "./src",
"paths": {
"@common/*": [ "common/*" ],
"@scss/*": [ "scss/*" ],
"@store/*": [ "store/*" ],
"@interfaces/*": [ "interfaces/*" ],
"@network/*": [ "network/*" ],
"@pages/*": [ "components/pages/*" ],
"@hooks/*": [ "components/hooks/*" ],
"@helper/*": [ "components/helper/*" ],
},
/* JavaScript Support */
"allowJs": true,
/* Emit */
"sourceMap": true,
"outDir": "./build",
/* Interop Constraints */
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
/* Type Checking */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": false,
/* Completeness */
"skipLibCheck": true,
},
"exclude": ["node_modules"],
"typeRoots": ["node_modules/@types"],
"include": [
"./src/**/*"
]
}
기존 javascript로 된 코드를 포팅할때 Type Checking 항목옵션에 따라서 까다로운 이슈가 많이 생길수 있습니다.
특히 strictNullChecks: true인 경우가 그런데 일단 기존 코드를 크게 건드리지 않는 선에서의 포팅이 목적이므로 해당 항목을 false로 설정 하기를 권장 합니다.
컴포넌트나 모듈등을 import할때 path를 간략히 설정해서 간결하게 쓸수 있게 하는 alias설정이 ts에서는 기존 js용 설정과는 다르게 추가해 줄 것이 1가지가 있습니다.
js에서는 webpack에서만 추가해주면 되지만 ts에서는 tsconfig.json에도 설정 추가가 필요 합니다.
"baseUrl": "./src",
"paths": {
"@common/*": [ "common/*" ],
"@scss/*": [ "scss/*" ],
"@store/*": [ "store/*" ],
"@interfaces/*": [ "interfaces/*" ],
"@network/*": [ "network/*" ],
"@pages/*": [ "components/pages/*" ],
"@hooks/*": [ "components/hooks/*" ],
"@helper/*": [ "components/helper/*" ],
},
.tsx(ts)에서 기존 처럼 동일하게 alias 사용이 가능해 집니다.
import MetaDoors from "@pages/main/MetaDoors";
일반적인 Basic type들은 point: number, typeValue: number | string 등과 같이 타입만 추가해주면 됩니다.
props
// props interface 선언
interface IProps {
mobileFooter: boolean
}
usage:
const MetaDoors: React.FC<IProps> = ({mobileFooter}) => {
or
const MetaDoors: ({mobileFooter}: IProps) => {
or
const MetaDoors: ({props}: IProps) => {
interface IProps {
settingMenu: number,
setSettingMenu: React.Dispatch<React.SetStateAction<number>>,
detail: string,
handleAction: Function ( or ()=>void )
}
useState타입은 any로 선언해도 되지만 타입을 명확히 해줄려면 위와같이 선언 해줍니다.
const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value;
console.log(inputValue);
}
// e.target을 파라미터로 넘기는 경우
const handleInput = (target: HTMLInputElement) => {
const isChecked = target.checked;
console.log(isChecked);
}
// textarea 는 HTMLTextAreaElement
<span className="btn-del" onClick={(e)=>handleTagCancel(e)}></span>
// 사용 하는 element의 타입을 적용해서 사용
e: React.MouseEvent<HTMLSpanElement, MouseEvent>
usage:
// RefObject (dom element)
const searchInput: React.RefObject<HTMLInputElement> = useRef(null)
const searchInput = useRef<HTMLInputElement>(null)
const myToolRef: React.RefObject<HTMLDivElement> = useRef(null)
const audioRef: React.LegacyRef<HTMLAudioElement> = useRef(null)
// MutableRefObject
const isMounted: React.MutableRefObject<boolean> = useRef()
isMounted.current = true or false
// MarqueeJs.jsx
import React from 'react';
import * as Util from "@common/UtilTs";
const Marquee = ({upperLimits,hideHeader}) => {
return (
<marquee className={hideHeader ? "top-rolling rolling-hidden" : "top-rolling"}>
{upperLimits.length > 0 && upperLimits.map((val,idx) =>{
return (
<span key={idx}>{`${val.userInfo.name} ${val.nftSerialNo} ${val?.title}`}
<em className="up">{Util.addComma(val.price)} $</em>
</span>
)
})}
</marquee>
)
}
export default Marquee;
기존 레거시 프로젝트는 빠르게 포팅하는게 목적이므로 상황에 따라서 이와같이 호환성 이슈를 비켜갈수도 있다는 용도로 봐주시면 되겠습니다.
createStore가 deprecated 되었고 configureStore를 사용하라는 툴팁이 뜹니다.
//import { createStore } from 'redux';
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './store/modules';
//const store = createStore(rootReducer);// deprecated
const store = configureStore({reducer: rootReducer});
ps. 추가되는 내용이 있을때마다 업데이트 예정입니다.
from Jerry