컴파일러 옵션이란
타입스크립트의 컴파일은 작성한 타입스크립트 코드에 타입 오류가 없는지를 검사하고 오류가 없다면 자바스크립트 코드로 변환합니다. 이러한 컴파일 과정에서 아주 세부적인 사항들(얼마나 엄격하게 타입을 검사할 건지 또는 컴파일 되는 자바스크립트 코드의 버전은 어떻게 할 건지 등)을 컴파일 옵션이라고 합니다.
컴파일러 옵션 자동 생성
타입스크립트의 컴파일러 옵션은 tsconfig.json
파일에서 설정할 수 있으며, Node.js 패키지 단위로 설정됩니다. 컴파일러 옵션을 가장 쉽게 설정하는 방법은 자동 생성 도구를 이용하는 방법입니다. tsc
를 이용하면 기본 옵션이 설정된 컴파일러 옵션 파일을 자동 생성할 수 있습니다.
tsc --init
터미널에서 위 명령어를 입력하면 자동으로 기본 설정이 완료된 tsconfig.json
파일이 생성됩니다.
{
"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 legacy experimental 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": "node10", /* 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. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'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. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "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. */
// "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. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "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. */
}
}
만들어진 sconfig.json
파일은 굉장히 많은 옵션들이 담겨있지만 대부분 주석처리되어 있어서 실제 적용되는 옵션은 몇개 없는 것을 볼 수 있습니다.
컴파일러 옵션 직접 설정하기
include
include
옵션은 tsc
에게 컴파일 할 타입스크립트 파일의 범위와 위치를 알려주는 옵션입니다.
{
"include": ["src"]
}
위와 같이 include
옵션을 설정하면 파일 하나하나 직접 컴파일하지 않고 src
폴더 아래에 있는 모든 타입스크립트 파일이 동시에 컴파일 할 수 있습니다.
target
target
옵션은 컴파일 결과 생성되는 자바스크립트 코드의 버전을 설정하는 옵션입니다.
{
"compilerOptions": {
"target": "ES5"
},
"include": ["src"]
}
target
옵션을 ES5으로 설정하면 컴파일 된 자바스크립트 코드는 ES5 버전의 자바스크립트 코드로 변환됩니다.
ES6의 문법 중 하나인 화살표 함수를 작성한 후
const func = () => console.log("Hello");
해당 타입스크립트 파일을 컴파일 하면 다음과 같이 화살표 함수가 함수 표현식으로 변환되는 걸 확인할 수 있습니다.
const func = function(){
console.log("Hello");
}
변환되는 자바스크립트의 버전을 최신 버전으로 하고 싶다면 target
옵션을 ESNext
로 설정하면 됩니다.
module
module
옵션은 변환되는 자바스크립트 코드의 모듈 시스템을 설정하는 옵션입니다.
{
"compilerOptions": {
"target": "ESNext",
"module": "CommonJS"
},
"include": ["src"]
}
위와 같이 module
옵션을 CommonJS
로 설정하면 변환되는 자바스크립트 코드의 모듈을 CommonJS
문법으로 변환시킬 수 있습니다.
// hello.ts
export const hello = () => {
console.log("hello");
};
// index.ts
import { hello } from "./hello";
hello();
index.ts
파일과 hello.ts
파일에 import와 export를 사용해서 코드를 작성한 후에 tsc
로 컴파일 하면 아래와 같이 CommonJS 문법으로 변환되는 것을 볼 수 있습니다.
// index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const hello_1 = require("./hello");
(0, hello_1.hello)();
// hello.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hello = void 0;
const hello = () => {
console.log("hello");
};
exports.hello = hello;
module
옵션을 ESNext
로 설정하면 자바스크립트 코드가 ES 모듈 시스템을 사용하는 것을 볼 수 있습니다.
outDir
outDir
옵션은 컴파일 결과를 생성할 자바스크립트 코드의 위치를 결정하는 옵션입니다.
{
"compilerOptions": {
...
"outDir": "dist"
},
"include": ["src"]
}
tsc
를 이용해 컴파일 하면 컴파일 결과가 dist
폴더에 생성되는 것을 볼 수 있습니다.
strict
strict
옵션은 타입스크립트 컴파일러의 타입 검사 엄격함의 수준을 정하는 옵션입니다.
{
"compilerOptions": {
...
"strict": true
},
"include": ["src"]
}
strict
옵션을 true
로 설정하면 코드를 아주 엄격하게 검사하게 됩니다.
strict
옵션을 설정하지 않았을 때는 hello
함수의 매개변수의 타입을 지정하지 않아도 오류가 발생하지 않습니다. 하지만 옵션을 true
로 설정하고 나면 아래와 같이 타입 오류를 발생하게 됩니다.
타입스크립트에서는 특별히 매개변수의 타입은 프로그래머가 직접 지정하도록 권장합니다. 왜냐하면 타입스크립트는 함수 매개변수의 타입을 자동 추론할 수 없기 때문에 타입을 프로그래머가 직접 지정하지 않을 경우 엄격한 타입 검사 모드에서는 오류가 발생하게 됩니다.
이때 반대로 strict
를 끄면 엄격하지 않게 타입을 검사하기 때문에 오류가 사라지게 됩니다.
ModuleDetection
타입스크립트의 모든 파일은 기본적으로 전역 파일(모듈)로 취급됩니다. 그렇기 때문에 다른 타입스크립트 파일에서 동일한 이름의 변수를 선언하게 되면 오류가 발생하게 됩니다.
이럴 때에는 각 파일에 모듈 시스템 키워드(export, import)를 최소 하나 이상 사용해 해당 파일을 전역 모듈이 아닌 로컬(독립) 모듈로 취급되도록 만들어야 하는데, 이를 자동화 하는 옵션이 바로 moduleDetection
옵션입니다.
다음과 같이 moduleDection
옵션을 force
로 설정할 경우 자동으로 모든 타입스크립트 파일이 로컬 모듈(독립 모듈)로 취급됩니다.
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "dist",
"moduleDetection": "force"
},
"include": ["src"]
}
ts-node
moduleDetection
옵션을 활성화 하고 타입스크립트 파일에서 모듈 시스템을 사용하게 되면 ts-node로 실행할 때 오류가 발생하게 됩니다.
이 때 다음과 같이 ts-node
의 옵션을 설정하면 ts-node
로 타입스크립트 모듈을 실행할 수 있게 됩니다.
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "dist",
"moduleDetection": "force"
},
"ts-node": {
"esm": true
},
"include": ["src"]
}
'TypeScript' 카테고리의 다른 글
제네릭(Generic) (0) | 2023.08.14 |
---|