๐ก ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ์คํ๋๊ธฐ๊น์ง์ ๊ณผ์ ์ ํฌ๊ฒ Compile, Bundle, Deploy 3๋ฒ์ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์น๋ค. ํ ๋ฒ ํ์ ์คํฌ๋ฆฝํธ๊ฐ ์ด๋ป๊ฒ ์๋๋๋์ง ํ ๋ฒ ํบ์๋ณด์!

์ฐ์ ๋ชจ๋ ์ปดํ์ผ ๊ณผ์ ์ ๊ธฐ์ค์ด ๋ ์ถ์ ๊ตฌ๋ฌธ ํธ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๋ธ๋ค. ์ฌ๊ธฐ์ ํต์ฌ์ด ๋ ๋ ๊ฐ์ง๋ Scanner์ Parser์ด๋ค.
์ด๋ค์ ์ปดํ์ผ ๊ณผ์ ์ ๊ฐ ๊ตฌ๋ฌธ์ ํ ํฐ์ผ๋ก ์ถ์ถํ์ฌ AST๋ก ๋ณํํ๊ธฐ๊น์ง์ ์ญํ ์ ์ํํ๋ค. ์ถ์ ๊ตฌ๋ฌธ ํธ๋ฆฌ (Abstract Syntax Tree)๋ ์์ค ์ฝ๋์์ ๋ฐ์๋๋ ๊ตฌ์กฐ๋ฅผ ํธ๋ฆฌ ํ์์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค. ์์ธํ ์ฝ๋๊ฐ ์๋ ์ถ์์ ์ธ ๊ตฌ๋ฌธ์ผ๋ก ๋ํ๋ธ ํธ๋ฆฌ๋ผ๋ ๊ฒ์ ์๋ฏธํ๋ค. ๊ตฌ๋ฌธ ํธ๋ฆฌ๊ฐ ๋ง๋ค์ด์ง๋ฉด ์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ์, ํ์
๊ฒ์ฌ๋ฅผ ํ๋ค.
๋จผ์ Scanner๊ฐ ํ์ ์คํฌ๋ฆฝํธ๋ก ์ ๋ ฅ๋ ์ฝ๋ ๋ฌธ์์ด์ ๊ฐ๊ฐ ์์ฝ์ด, ์ฝ๋ก , ๋ถํธ ๋ฑ์ ํ ํฐ์ผ๋ก ๋ถ๋ฆฌ์ํค๋ ์ญํ ์ ํ๋ค. ์ ๊ทธ๋ฆผ์ Tokens๋ Scanner๋ฅผ ํตํด ๋ถ๋ฆฌ๋ ๊ฐ๋จํ ํ ํฐ๋ค์ ๋ณด์ฌ์ค๋ค. (์ด ๊ณผ์ ์ tokenizer๋ผ๊ณ ํ๋ค.)
Parser๋ Scanner๊ฐ ๋ถ๋ฆฌํด์ค ํ ํฐ์ ๊ตฌ๋ฌธ์ ๊ตฌ์กฐ์ ๋ฐ๋ผ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋ง๋ค์ด๋ด๋ ์ญํ ์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฌธ๋ฒ์ธ์ง ๋ถ์ํ์ฌ ๊ตฌ๋ฌธ ์ค๋ฅ๋ฅผ ์ก์๋ด๋ ์ญํ ๋ ๋งก๊ณ ์๋ค.

ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ์ ๊ฐ์ฅ ํฐ ์ญํ ์ ํ๋ ํ์ ๊ฒ์ฌ ๋จ๊ณ์ด๋ค. ์ด ๋จ๊ณ์์๋ binder, type system์ ํต์ฌ์ด๋ผ ํ ์ ์๋ type checker๊ฐ ๋ฑ์ฅํ๋ค.
Binder๋ ์ ์ฒด AST๋ฅผ ์ฝ์ด์ ํ์ ๊ฒ์ฌ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ๊ณผ์ ์ด๋ค. ๊ฐ ์์ญ ๋ณ๋ก identifier๋ฅผ ๊ตฌ๋ถํ๊ณ ์๋ณ์๊ฐ ์ด๋ ์์น์ ์ ์๋์๋์ง ์ด๋ค ํ๋๊ทธ๋ฅผ ์ ์ฉํ ๊ฒ์ธ์ง ์ ํํ์ฌ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด ๋ธ๋ค. ์ด๋ ๊ฒ ์ค์ ๋ Symbol: primary building block of the TypeScript semantic system์ symbol table์ HashMap์ผ๋ก ์ ์ฅ๋๋ค. ์ด๋ ์ดํ ๋จ๊ณ์์ ์ฝ๋ ๋ถ์์ ์งํํ ๋ ๊ธฐ์ค์ด ๋๋ค. ์๋๋ ํจ์์ ๋ณ์๋ฅผ symbol๋ก ๊ฐ๋จํ ํํํ๊ณ ์๋ค.
functionName
FunctionDeclaration
Flags: Function
variableName
VariableDeclaration
Flags: BlockScopedVariable
๋ํ binder๋ Flow nodes๋ก ๋ณ์๋ฅผ ์ถ์ ํ๋ค.
์ฝ๋์ ๋ถ๊ธฐ์ ์ด ๋๋ ํ๋ฆ ์กฐ๊ฑด๋ถ, ์ฆ Flow Conditional์ ๊ธฐ์ค์ผ๋ก ์์ญ์ ์ ํ์ฌ Flow Container๋ฅผ ์ง์ ํ๋ค.

ํ์ ์คํฌ๋ฆฝํธ๋ ๊ฒ์ฌํ ๋ ธ๋๋ก๋ถํฐ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ์ฐพ์๊ฐ๋ฉฐ ์ญ๋ฐฉํฅ์ผ๋ก ์ฐพ์๊ฐ๋ฉฐ ๋ณ์์ ํ์ ์ ์ถ์ ํ ์ ์๋ค. ์๋๋ Typescript Playground์์ ์ง์ํ๋ ํ๋ฌ๊ทธ์ธ์ผ๋ก ํ์ธํ Flow Graph์ด๋ค.

TypeChecker๋ ์์์ ๋ง๋ค์ด ๋ธ AST์ Symbols table์ ๊ธฐ์ค์ผ๋ก ํ์ ๊ฒ์ฌ๋ฅผ ์ํํ๋ค. ๊ฒ์ฌ๋ ๊ตฌ์กฐ์ ์ผ๋ก ์ด๋ฃจ์ด ์ง๋ฉฐ ์ธ๋ถ์์ ๋ด๋ถ๋ก ์งํ๋๋ค. ๋จผ์ ์ด ๊ฐ์ด object ํํ์ธ์ง, ๋ค์์ ํ๋, ๋ง์ง๋ง์ผ๋ก๋ ๊ฐ์ ํ์ ์ด ์ผ์นํ๋์ง ๋น๊ตํ๋ค. ์ด๋ ๊ฒ ํ์ ์ ๊ฒ์ฌํ๋ ํน์ง์ ํ์ ์คํฌ๋ฆฝํธ์ ๊ตฌ์กฐ์ ํ์ดํ์ด๋ผ๊ณ ํ๋ค.
{ age: number } = { age: 'nextree' }
์์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ๊ฐ์ ๋น๊ตํ ๋, TypeFlags.NumberLike์ โnextreeโ๋ TypeFlags.StringLiteral์ด๋ฏ๋ก false๋ฅผ ๋ฐํํ ๊ฒ์ด๋ค.
์ด ๋น๊ต๋ TypeFlags๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ด Enum์ Typescript ํ์ผ์ /src/compiler/types.ts์ ์ ์๋์ด ์์ผ๋ฉฐ, ๊ฐ๋ฅํ ๋ชจ๋ ํ์ ์ ๊ฐ์ง๊ณ ์๋ค.
์๋์ ๊ฐ์ด ํ์ ์ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ์ AST์ initializer์ ๊ฒฐ๊ณผ ๊ฐ(โHello world!โ)์ ํ์ ์ message์ type ์ ํ ์ค๋ก ๋์ ํ๋ค.
const message = 'Hello World!';
ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํํ๊ธฐ ์ํด์๋ compile Option์ด ํ์ํ๋ค. ์ฐ๋ฆฌ๋ ์ด ์ต์ ๋ค์ tsConfig.json ํ์ผ๋ก ๊ด๋ฆฌํ ๊ฒ์ด๋ค.
{
"compilerOptions": {
"module": "system", // TSC๊ฐ ์ปดํ์ผํ ๋์ ๋ชจ๋ ์์คํ
"outDir": "dist", // ์์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋๋ ํฐ๋ฆฌ
"target": "es2015", // ์ปดํ์ผ ํ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฒ์
},
"include": ["src/**/*"], // typescript ๊ฐ ์ฐพ์ ๋๋ ํฐ๋ฆฌ
}
ํ์ ์คํฌ๋ฆฝํธ์๋ AST๋ฅผ ํ์ผ๋ก ๋ณํํ๋ ์ญํ ์ ํ๋ emmiter๊ฐ ์๋ค. emitter์๋ ๋ ๊ฐ์ง๊ฐ ์๋๋ฐ ์ญํ ๋ก ๋๋ ๊ฐ๋จํ ๋น๊ต๋ ์๋์ ๊ฐ๋ค.
| emitter.ts | declarationEmitter.ts |
|---|---|
| js code | .d.ts code |
emitter๋ AST์ Checker๋ฅผ ํตํด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๋ง๋ค์ด ๋ธ๋ค.
๋จผ์ ํ์ ์คํฌ๋ฆฝํธ AST๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ AST๋ก ๋ณํํ๋ค. ๊ฐ๋จํ๊ฒ ํ์ ์คํฌ๋ฆฝํธ AST์์ ํ์ ์ ๋ํ๋ด๋ keyword ์ ํ ์ค๋ฅผ ์ ๊ฑฐํ๋ ๊ณผ์ ์ด๋ผ๊ณ ๋ง ํ ์ ์๋ค.
๊ทธ ํ, ๊ฐ ๋ฌธ๋ฒ ๋ฒ์ ์ ๋ฐ๋ผ Asset flag๋ฅผ ์ง์ ํ๋ค. transformer๋ ์ด๋ ๊ฒ Asset, ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋, ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํ ํ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋(.js)๋ฅผ ๋ง๋ค์ด ๋ธ๋ค. ๋ํ ํ์ ๋ง ์ ์ํด ๋์ type definition(.d.ts) ํ์ผ๋ ํจ๊ป ์์ฑํ๋ค.
// es2015 Asset
const message: string = โHello worldโ; // typescript code
console.log(message); // javascript code
// ์์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋
"use strict";
const message = 'Hello world';
console.log(message);
// ์์ฑ๋ DTS ์ฝ๋
declare const message: string;
์ด .d.tsํ์ผ์ ์ปดํ์ผ๋ฌ๊ฐ ๋ง๋ค์ด ๋ด๊ธฐ๋ ํ์ง๋ง ์ฌ์ฉ์๊ฐ ์ ์ํ ์ ์๋ ํ์ผ์ด๋ค. ์ด ํ์ผ๋ก ๋ณ์ ์ ํ์ ์ง์ ํด ๋์ผ๋ฉด, ์ปดํ์ผ๋ฌ๋ .d.tsํ์ผ์ ์ด์ฉํด ํ์ ์ถ๋ก ์ ์ฐธ๊ณ ํ๋ค.