-
자바스크립트 프로젝트에 타입스크립트 도입하기React.js & Next.js 2022. 8. 24. 22:14
타입스크립트 설정하기
현재 우리 리액트 버전에 맞춘 17로 타입스크립트 설치를 가정하겠습니다. 프로젝트 내의 현재 버전에 맞춰 진행해주세요.
1. 타입스크립트 전역 설치
$ yarn global add typescript / npm install -g typescript
2. 타입스크립트 설정파일 생성하기
먼저 config 파일을 왜 설정해야 하는지에 대한 의문점이 있을 수 있기 때문에 이에대한 레퍼런스 블로그를 링크로 달아놓겠습니다.
config 파일이란 무엇인가요? (jsconfig.json / tsconfig.json)
1) tsc 사용하기
$ npx tsc --init
$ npx tsc --init 를 명령어를 실행하면서 tsconfig.json 설정을 추가할 수 있습니다. 로컬에서 tsc 를 실행하면 tsconfig.json 가 정의한 가장 가까운 프로젝트를 컴파일하고, 원하는 파일 glob을 전달하여 TypeScript 파일 집합을 컴파일할 수 있습니다.
2) tsc —init 기본 설정
{ "compilerOptions": { /* Visit <https://aka.ms/tsconfig> to read more about this file */ /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ } }
3) 속성 설명
target 컴파일된 코드가 어떤 환경에서 실행될 지 정의합니다. 예를들어서 화살표 함수를 사용하고 target 을 es5 로 한다면 일반 function 키워드를 사용하는 함수로 변환을 해줍니다. 하지만 이를 es6 로 설정한다면 화살표 함수를 그대로 유지해줍니다.
프로퍼티 명 설명 module 컴파일된 코드가 어던 모듈 시스템을 사용할지 정의합니다. 예를 들어서 이 값을 common 으로 하면 export default Sample 을 하게 됐을 때 컴파일 된 코드에서는 exports.default = helloWorld 로 변환해주지만 이 값을 es2015 로 하면 export default Sample 을 그대로 유지하게 됩니다. strict 모든 타입 체킹 옵션을 활성화한다는 것을 의미합니다. esModuleInterop commonjs 모듈 형태로 이루어진 파일을 es2015 모듈 형태로 불러올 수 있게 해줍니다. { "compilerOptions": { "target": "es5", // 'es3', 'es5', 'es2015', 'es2016', 'es2017','es2018', 'esnext' 가능 "module": "commonjs", //무슨 import 문법 쓸건지 'commonjs', 'amd', 'es2015', 'esnext' "allowJs": true, // js 파일들 ts에서 import해서 쓸 수 있는지 "checkJs": true, // 일반 js 파일에서도 에러체크 여부 "jsx": "preserve", // tsx 파일을 jsx로 어떻게 컴파일할 것인지 'preserve', 'react-native', 'react' "declaration": true, //컴파일시 .d.ts 파일도 자동으로 함께생성 (현재쓰는 모든 타입이 정의된 파일) "outFile": "./", //모든 ts파일을 js파일 하나로 컴파일해줌 (module이 none, amd, system일 때만 가능) "outDir": "./", //js파일 아웃풋 경로바꾸기 "rootDir": "./", //루트경로 바꾸기 (js 파일 아웃풋 경로에 영향줌) "removeComments": true, //컴파일시 주석제거 "strict": true, //strict 관련, noimplicit 어쩌구 관련 모드 전부 켜기 "noImplicitAny": true, //any타입 금지 여부 "strictNullChecks": true, //null, undefined 타입에 이상한 짓 할시 에러내기 "strictFunctionTypes": true, //함수파라미터 타입체크 강하게 "strictPropertyInitialization": true, //class constructor 작성시 타입체크 강하게 "noImplicitThis": true, //this 키워드가 any 타입일 경우 에러내기 "alwaysStrict": true, //자바스크립트 "use strict" 모드 켜기 "noUnusedLocals": true, //쓰지않는 지역변수 있으면 에러내기 "noUnusedParameters": true, //쓰지않는 파라미터 있으면 에러내기 "noImplicitReturns": true, //함수에서 return 빼먹으면 에러내기 "noFallthroughCasesInSwitch": true, //switch문 이상하면 에러내기 } }
3. 타입스크립트 설치하기
기존 JavaScript 프로젝트에 TypeScript를 추가하는 방법입니다. 패키지매니저를 통해 package.json 내에 타입스크립트 관련 라이브러리르 다운받아주세요.
$ yarn add -D typescript @types/node @types/react @types/react-dom @types/jest
라이브러리 중 타입스크립트를 지원한다면, 타입스크립트 환경에서 해당 패키지를 실행하기 위해 타입스크립트 라이브러리를 추가적으로 설치해야 합니다. 만약 react-router-dom 을 사용하고 있다면, @types/react-router-dom 을 설치해야 합니다.
$ yarn add -D @types/react-router-dom / npm install @types/react-router-dom
이렇게 자신의 프로젝트에 있는 모든 패키지에 @types/xxx 를 설치합니다. 해당 패키지가 없을 경우 링크를 참조하여 해결할 수 있습니다
$ yarn add -D @types/styled-components@5.1.1
4. build 하기
$ yarn build 명령어를 통해 빌드를 하기 위한 기본적이 tsconfig.json의 설정을 자동 세팅할 수 있습니다.
$ yarn build
build 시 볼 수 있는 터미널 상의 메시지 (이미지)
{ "compilerOptions": { "target": "ES5", "module": "ESNext", "allowJs": true, "baseUrl": "src", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "lib": ["dom", "dom.iterable", "esnext"], "allowSyntheticDefaultImports": true, "noFallthroughCasesInSwitch": true, "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": ["src", "src/features/audiochat/DebugRefreshChannelButton.js"] }
속성 설명
target 컴파일된 코드가 어떤 환경에서 실행될 지 정의합니다. 예를들어서 화살표 함수를 사용하고 target 을 es5 로 한다면 일반 function 키워드를 사용하는 함수로 변환을 해줍니다. 하지만 이를 es6 로 설정한다면 화살표 함수를 그대로 유지해줍니다.
프로퍼티 명 설명 module 컴파일된 코드가 어던 모듈 시스템을 사용할지 정의합니다.
예를 들어서 이 값을 common 으로 하면 export default Sample 을 하게 됐을 때 컴파일 된 코드에서는 exports.default = helloWorld 로 변환해주지만, 이 값을 es2015 로 하면 export default Sample 을 그대로 유지하게 됩니다.allowJs JavaScript 파일의 컴파일을 허용합니다 esModuleInterop commonjs 모듈 형태로 이루어진 파일을 es2015 모듈 형태로 불러올 수 있게 해줍니다. forceConsistentCasingInFileNames 동일 파일 참조에 대해 일관성 없는 대소문자를 비활성화합니다. strict 모든 타입 체킹 옵션을 활성화한다는 것을 의미합니다. skipLibCheck 모든 선언 파일(*.d.ts)의 타입 검사를 건너뜁니다. lib 컴파일에 포함될 라이브러리 파일 목록입니다. allowSyntheticDefaultImports default export가 없는 모듈에서 default imports를 허용합니다. 코드 방출에는 영향을 주지 않으며, 타입 검사만 수행합니다. noFallthroughCasesInSwitch 스위치 문에 fallthrough 케이스에 대한 오류를 보고합니다. moduleResolution 모듈 해석 방법 결정. Node.js/io.js 스타일 해석의 경우, "Node" 또는 "Classic" 중 하나입니다. 자세한 내용은 모듈 해석 문서 를 참조하세요. resolveJsonModule .json 확장자로 import된 모듈을 포함합니다. isolatedModules 추가 검사를 수행하여 별도의 컴파일 (예를 들어 트랜스파일된 모듈 혹은 @babel/plugin-transform-typescript) 이 안전한지 확인합니다. noEmit 출력을 내보내지 않습니다. jsx .tsx 파일에서 JSX 지원: "React", "Preserve", "react-native". JSX 를 확인하세요. 그외
프로퍼티 명 설명 include include또는 속성을 사용하여 프로젝트의 파일을 명시적으로 설정할 수 있습니다.
include 속성이 없으면 기본적으로 디렉터리와 하위 디렉터리의 모든 파일을 포함합니다.
include 속성이 지정 되면 해당 파일만 포함됩니다.exclude exclude 속성은 언어 서비스(해당 프로젝트)에 소스 코드의 일부가 아닌 파일을 알려줍니다.
이렇게 하면 성능이 높은 수준으로 유지됩니다.
IntelliSense가 느린 경우 exclude 목록에 폴더를 추가합니다
(VS Code가 속도 저하를 감지하면 이를 수행하라는 메시지가 표시됨). *exclude 예시 참고exclude 예시
{ "compilerOptions": { "module": "commonjs", "target": "es6" }, "exclude": ["node_modules"] }
5. 이후에는 ?
- 향후 새롭게 작성되는 파일 및 기능은 .tsx 로 하여금 타입스크립트 파일로 작성하기
- 기존 js 에서 사용하던 라이브러리들 중 .tsx 로 썼을 때 warning 또는 에러가 난다면 @types/ 추가로 설치해주기
- npm 에서 직접 검색하거나 $ npm info @types/xxx 로 검색하여 존재하는지 여부를 파악할 수 있습니다
레퍼런스
'React.js & Next.js' 카테고리의 다른 글
Next.js - SSR, getServerSideProps 적용하기 (0) 2022.09.18 Next.js - 초기화 이후 기본 구조 설정하기 (0) 2022.09.18 리액트에서 다수의 체크 박스 다루기 (0) 2022.09.13 스타일드 컴포넌트 조건부 렌더링 활용하기 (0) 2022.08.26 리액트 18 > 17 마이그레이션하기 (0) 2022.08.23