우테코 프리코스의 과제 중 하나였던 숫자 야구 게임을 타입스크립트로 구현하려고 합니다.
기존 자바스크립트로 작성된 프로젝트에 타입스크립트를 적용하고, Jest 테스트를 정상적으로 실행하기까지 과정을 설명합니다.
npm install --save-dev typescript @types/node
다음의 명령어로 기본 설정이 적용된 tsconfig.json
파일을 생성합니다.
tsc --init
기본 설정에 추가적으로 필요한 설정을 다음과 같이 적용했습니다.
// tsconfig.json
{
"compilerOptions": {
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
"baseUrl": "src" /* Specify the base directory to resolve non-relative module names. */,
"typeRoots": [
"./node_modules/@types",
"./types"
] /* Specify multiple folders that act like './node_modules/@types'. */,
"types": [
"node"
] /* Specify type package names to be included without being referenced in a source file. */,
/* JavaScript Support */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
/* Emit */
"noEmit": true /* Disable emitting files from a compilation. */,
/* Interop Constraints */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"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'. */,
/* Completeness */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["src"],
"exclude": ["node_modules", "__test__"]
}
타입스크립트 설정 후 코드를 작성하던 중 각 모듈이 지역 스코프를 가지지 않고 전역 스코프로 동작하면서 다음과 같은 에러가 발생했습니다.
블록 범위 변수 '[변수명]'을(를) 다시 선성할 수 없습니다. ts(2451)
자바스크립트가 하나의 전역 스코프를 가지는 것처럼 타입스크립트 또한 전역 스코프를 가지기 때문에 발생한 문제로 다음의 설정을 tsconfig.json
에 추가하여 해결했습니다.
해당 설정은 각 파일(모듈)이 전역이 아닌 독립된 모듈로 인식할 수 있도록 합니다.
{
"compilerOptions": {
...
"moduleDetection": "force",
}
}
설정 후 해당 오류가 해결되지 않는다면 타입스크립트 서버를 다시 시작해주세요.
타입스크립트 서버 다시 시작하기
단축키
cmd + shift + p
누른 후 'TS 서버 다시 시작'을 찾아 실행
node [파일명].js
명령어를 이용하여 자바스크립트 파일을 Node.js로 실행할 수 있습니다.
저는 현재 사용 중인 에디터(VScode)에 Code Runner라는 확장 플러그인을 설치하여 단축키(
command + option + n
)를 통해 실행합니다.
타입스크립트 파일도 동일한 방법으로 단축키를 통해 실행했습니다.
ts-node: command not found
타입스크립트 파일의 경우 ts-node
를 통해 실행을 하게 되는데, ts-node
가 설치되지 않아
위와 같은 에러가 발생했습니다.
다음의 명령어를 통해 ts-node
를 글로벌로 설치했습니다.
npm install -g ts-node
설치 후 동일한 단축키로 타입스크립트를 실행하면 ts-node
명령어가 자동으로 적용되며 타입스크립트 파일이 실행됩니다.
기존에 Jest가 설치되어 있지만 타입스크립트에서 사용하기 위해 추가적인 패키지가 필요합니다.
npm install --save-dev @types/jest
// jest.config.js
module.exports = {
testMatch: ['**/__tests__/**/*.+(ts|js)', '**/?(*.)+(spec|test).+(ts|js)'],
transform: {
'^.+\\.ts$': 'ts-jest',
},
};
testMatch
: 테스트를 적용할 파일을 설정합니다.transform
: 어떤 babel-plugin을 사용하여 트랜스파일 할것인지를 결정합니다. 위 설정은 참고 링크의 설정을 그대로 가져오되 불필요한 부분을 제외하고 동일하게 적용했습니다.
따라서 transform
도 참고 링크와 동일하게 ts-jest
를 적용했으나 ts-jest
를 설치하지 않은 상태에서 적용하여 에러가 발생했습니다.
● Validation Error:
Module ts-jest in the transform option was not found.
위 에러는 링크를 참고하여 다음과 같이 수정하였습니다.
node_modules
내에 babel-jest
가 있는 것을 확인하고 설정했습니다.
// jest.config.js
module.exports = {
...
transform: {
'^.+\\.ts$': '<rootDir>/node_modules/babel-jest',
},
};
타입스크립트에서 Jest를 사용하려면, Babel을 이용해 트랜스파링을 한 후 테스트를 수행합니다.
npm install --save-dev @babel/core @babel/cli @babel/preset-typescript @babel/preset-env
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};
// package.json
{
...
"scripts": {
"test": "jest"
},
}
npm test
> javascript-baseball@1.0.0 test
> jest
PASS __tests__/StringTest.test.js
FAIL __tests__/ApplicationTest.test.js
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 6 passed, 7 total
Snapshots: 0 total
Time: 1.961 s, estimated 2 s
참고