-
Notifications
You must be signed in to change notification settings - Fork 0
[WEEK6] seulgi #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
[WEEK6] seulgi #36
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,79 @@ | ||
| <!-- 정리할 내용을 작성해주세요. --> | ||
| # 1. 자바스크립트의 런타임과 타입스크립트의 컴파일 | ||
|
|
||
| ## 1) 런타임과 컴파일타임 | ||
|
|
||
| 프로그래밍 언어는 일반적으로 고수준 언어 / 저수준 언어로 구분할 수 있다. | ||
|
|
||
| <br /> | ||
|
|
||
| ### 고수준 언어? 저수준 언어? | ||
|
|
||
| - 고수준 언어 : 사람이 이해하기 쉬운 형식으로 작성 | ||
| - 저수준 언어 : 컴퓨터가 이해하기 쉬운 형식으로 작성 | ||
|
|
||
| 자바스크립트는 대표적인 고수준 언어로, 컴파일러나 인터프리터에 의해<br /> | ||
| 저수준 프로그래밍 언어, 즉 기계가 이해할 수 있는 언어로 번역되어 실행된다. | ||
|
|
||
| ### 컴파일 타임? | ||
|
|
||
| 소스코드(개발자가 작성)가 컴파일 과정을 거쳐 컴퓨터가 인식할 수 있는<br /> | ||
| 기계어 코드(바이트 코드)로 변환되어 실행할 수 있는 프로그램이 되는 과정이다. | ||
|
|
||
| ### 런타임? | ||
|
|
||
| 소스코드의 컴파일이 완료되면 프로그램이 메모리에 적재되어 실행되는데<br /> | ||
| 이 시간을 런타임이라고 하는데 즉 런타임은 컴파일 과정을 마친 응용 프로그램이<br /> | ||
| 사용자에 의해 실행되는 과정이다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 2) 자바스크립트 런타임 | ||
|
|
||
| 자바스크립트 런타임은 자바스크립트가 실행되는 환경이다. | ||
|
|
||
| 자바스크립트 런타임의 주요 구성 요소로<br /> | ||
| 자바스크립트 엔진, 웹 API, 콜백 큐, 이벤트 루프, 렌더 큐가 있다. | ||
|
|
||
| > 자바스크립트는 대표적인 인터프리터 언어로 별도의 컴파일 과정이 존재하지 않는다고 알려져 있다.<br /> | ||
|
|
||
| > 하지만 엄밀히 말해 컴파일 단계가 존재하는데 자바스크립트를 해석하고 실행하는 역할을 하는<br /> | ||
| > V8 엔진은 때때로 자바스크립트 코드를 최적화하기 위해 컴파일 단계를 거친다.(실행 속도 향상을 위한 목적)<br /> | ||
| > 이 과정에서 자바스크립트 코드를 캐싱해 실행 시간을 단축시킨다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 3) 타입스크립트의 컴파일 | ||
|
|
||
| 타입스크립트는 **tsc**라고 불리는 컴파일러를 통해 자바스크립트 코드로 변환된다. | ||
|
|
||
| 하지만, 타입스크립트는 고수준언어 -> 고수준 언어로 변환되는 것이기 때문에<br /> | ||
| 컴파일이 아닌 트랜스파일로 불리거나 소스코드 -> 다른 소스코드로 변환하는 것이기에<br /> | ||
| 소스 대 소스 컴파일러라고 지칭하기도 한다. | ||
|
|
||
| > 타입스크립트 컴파일러는 소스코드를 해석해 AST를 만들고 이후 타입 확인을 거친 다음 결과 코드를 생성한다. | ||
|
|
||
| <br /> | ||
|
|
||
| ### 컴파일러가 소스코드를 컴파일해 프로그램으로 실행되기까지의 과정을 알아보자! | ||
|
|
||
| 1. 타입스크립트 소스코드를 타입스크립트 AST로 만든다.(tsc) | ||
| 2. 타입 검사기가 AST를 확인해 타입을 확인한다.(tsc) | ||
| 3. 타입스크립트 AST를 자바스크립트 소스로 변환한다.(tsc) | ||
| 4. 자바스크립트 소스코드를 자바스크립트 AST로 만든다.(런타임) | ||
| 5. AST가 바이트 코드로 변환된다.(런타임) | ||
| 6. 런타임에서 바이트 코드가 평가되 프로그램이 실행된다.(런타임) | ||
|
|
||
| ### AST(Abstract Syntax Tree)? | ||
|
|
||
| 컴파일러가 소스코드를 해석하는 과정에서 생성된 데이터 구조다.<br /> | ||
| 컴파일러는 어휘적 분석과 구문 분석을 통해 소스코드를 노드 단위의 트리 구조로 구성한다. | ||
|
|
||
| ### 타입스크립트 === 정적 검사기? | ||
|
|
||
| 타입스크립트를 컴파일타임에 에러를 발견할 수 있는 정적 검사기라고 부르는데 | ||
| 컴파일타임에 타입을 검사하기 때문이다.(런타임 전 에러 발견 가능) | ||
|
|
||
| <br /> | ||
| <br /> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,94 @@ | ||
| <!-- 정리할 내용을 작성해주세요. --> | ||
| # 2. 타입스크립트 컴파일러의 동작 | ||
|
|
||
| ## 1) 코드 검사기로서의 타입스크립트 컴파일러 | ||
|
|
||
| 타입스크립트는 컴파일타임에 문법 에러와 타입 관련 에러를 모두 검출한다. | ||
|
|
||
| ```js | ||
| const developer = { | ||
| work() { | ||
| console.log("working"); | ||
| }, | ||
| }; | ||
|
|
||
| developer.work(); | ||
| developer.sleep(); // TypeError; | ||
| ``` | ||
|
|
||
| > 해당 코드를 자바스크립트로 작성하는 시점에는 에러가 발생하지 않으나, 실제 실행 시 에러가 난다. | ||
|
|
||
| ```ts | ||
| const developer = { | ||
| work() { | ||
| console.log("working"); | ||
| }, | ||
| }; | ||
|
|
||
| developer.work(); | ||
| developer.sleep(); // Property "sleep" does not exist on type "{work(): void}" | ||
| ``` | ||
|
|
||
| > 타입스크립트는 코드를 실행 전에 에러를 사전에 발견해 알려준다. <br /> | ||
| > 즉, 런타임에 발생할 수 있는 문법 오류 등의 에러뿐 아니라 타입 에러도 잡을 수 있다. | ||
|
|
||
| 타입스크립트 컴파일러는 tsc binder를 사용하여 타입 검사를 하며, 컴파일타임에 타입 오류를 발견한다.<br /> | ||
| 타입 검사를 거쳐 코드를 안전하게 만든 이후에는 타입스크립트 AST를 자바스크립트 코드로 변환한다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 2) 코드 변환가로서의 타입스크립트 컴파일러 | ||
|
|
||
| 타입스크립트 코드를 각자의 런타임 환경에서 동작할 수 있도록<br /> | ||
| 구버전의 자바스크립트로 트랜스파일한다.<br /> | ||
| 이것이 <u>타입스크립트 컴파일러의 두 번째 역할</u>이다. | ||
|
|
||
| - 타입스크립트 컴파일러의 target 옵션을 사용하여 특정 버전의 자바스크립트 소스코드로 컴파일할 수 있다. | ||
| - 타입스크립트 컴파일러는 타입 검사를 수행한 후 코드 변환을 시작한다. | ||
| - 이때 타입 오류가 있더라도 일단 컴파일을 진행한다. | ||
|
|
||
| > 타입스크립트 코드가 자바스크립트 코드로 변환되는 과정은<br /> | ||
| > 타입 검사와 독립적으로 동작하기 때문이다.<br /> | ||
|
|
||
| > 타입스크립트 코드 타이핑이 잘못되서 발생하는 에러도 런타임 에러로 처리된다. 자바스크립트 실행 과정에서 런타임 에러로 처리된다. | ||
|
|
||
| ### 다만 문제가 있다..! | ||
|
|
||
| 타입스크립트 소스코드에 타입 에러가 있더라도 | ||
| 자바스크립트로 컴파일되어 타입 정보가 모두 제거된 후에는 | ||
| 타입이 아무런 효력을 발휘하지 못한다. | ||
|
|
||
| ```ts | ||
| interface Square { | ||
| width: number; | ||
| } | ||
|
|
||
| interface Rectangle extends Square { | ||
| height: number; | ||
| } | ||
|
|
||
| type Shape = Square | Rectangle; | ||
|
|
||
| function calculateArea(shape: Shape) { | ||
| // 에러! Rectangle이 타입이기 때문에 런타임은 해당 코드를 이해하지 못함 | ||
| if (shape instanceof Rectangle) { | ||
| return shape.width * shape.height; | ||
| } else { | ||
| return shape.width * shape.width; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| > 타입스크립트 코드가 자바스크립트로 <u>컴파일되는 과정에서 모든 인터페이스, 타입, 타입 구문이 제거되어 버리기 때문에 런타임에서는 타입을 사용할 수 없다.</u> | ||
|
|
||
| ### 타입스크립트 컴파일러의 역할? | ||
|
|
||
| 1. 최신 버전의 타입스크립트 / 자바스크립트 코드를 구버전의 자바스크립트로 트랜스파일한다. | ||
| 2. 코드의 타입 오류를 검사한다. | ||
|
|
||
| ### 바벨 (Babel)? | ||
|
|
||
| ECMAScript 2015 이후의 코드를 현재 또는 오래된 브라우저와 호환되는 버전으로 변환해주는 자바스크립트 컴파일러이다. | ||
|
|
||
| <br /> | ||
| <br /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,184 @@ | ||
| <!-- 정리할 내용을 작성해주세요. --> | ||
| # 3. 타입스크립트 컴파일러의 구조 | ||
|
|
||
| 타입스크립트 컴파일러가 동작하는 데 중요한 몇 가지 중요한 구성 요소가 있다. | ||
| 타입스크립트 컴파일러의 구체적인 동작을 살펴보자. | ||
|
|
||
| | 순서 | 단계 | 설명 | | ||
| | ---- | ------ | ----------------------------- | | ||
| | 1 | 스캐너 | .ts 토큰화 | | ||
| | 2 | 파서 | 토큰 기반 AST 생성 | | ||
| | 3 | 바인더 | AST 노드 기반 심볼 생성 | | ||
| | 4 | 체커 | AST + 심볼 기반 타입 검사 | | ||
| | 5 | 이미터 | AST + 코드 생성 기반 .js 생성 | | ||
|
|
||
| > 위의 5단계를 거쳐 타입 검사와 자바스크립트 소스 변환을 진행한다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 1) 프로그램(Program) | ||
|
|
||
| 타입스크립트 컴파일러는 tsc명령어로 실행된다.<br /> | ||
| 컴파일러는 tsconfig.json에 명시된 컴파일 옵션을 기반으로 컴파일을 수행한다. | ||
|
|
||
| 전체적인 컴파일 과정을 관리하는 프로그램 객체(인스턴스)가 생성되고,<br /> | ||
| 객체 내 컴파일할 타입스크립트 소스 파일과 소스 파일 내 임포트된 파일을 불러오는데<br /> | ||
| 가장 최초 불러온 파일을 기준으로 컴파일 과정이 시작된다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 2) 스캐너(Scanner) | ||
|
|
||
| 스캐너는 타입스크립트 소스 파일을 어휘적으로 분석하여 토큰을 생성하는 역할을 한다.<br /> | ||
| 소스코드를 작은 단위로 나누어 의미 있는 토큰으로 변환하는 작업을 수행한다. | ||
|
|
||
| ```ts | ||
| // 코드는 스캐너에 의해 다음과 같은 토큰으로 분석된다. | ||
| const woowa = "bros"; | ||
| ``` | ||
|
|
||
| - ConstKeyword: const | ||
| - WhitespaceTrivia: (공백) | ||
| - Identifier: woowa | ||
| - WhitespaceTrivia: (공백) | ||
| - EqualsToken: = | ||
| - WhitespaceTrivia: (공백) | ||
| - StringLiteral: "bros" | ||
| - SemicolonToken: ; | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 3) 파서(Parser) | ||
|
|
||
| 스캐너가 소스 파일을 토큰으로 나눠주면, 파서는 그 토큰 정보를 이용하여 AST를 생성한다. | ||
|
|
||
| 파서는 생성된 토큰 목록을 활용하여 구문적 분석을 수행한다. | ||
|
|
||
| 코드의 실질적인 구조를 노드 단위의 트리 형태로 표현하고,<br /> | ||
| 각각의 노드는 코드상의 위치, 구문 종류, 코드 내용과 같은 정보를 담는다. | ||
|
|
||
| ### AST? | ||
|
|
||
| 컴파일러가 동작하는 데 핵심 기반이 되는 자료 구조로,<br /> | ||
| 소스코드의 구조를 트리 형태로 표현한다. | ||
|
|
||
| AST의 최상위 노드는 타입스크립트 소스 파일이며,<br /> | ||
| 최하위 노드는 파일의 끝 지점으로 구성된다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 4) 바인더(Binder) | ||
|
|
||
| 체커 단계에서 타입 검사를 할 수 있도록 기반을 마련하는 역할은 한다.<br /> | ||
| 바인더는 타입 검사를 위해 심볼이라는 데이터 구조를 생성한다. | ||
|
|
||
| 심볼은 이전 단계의 AST에서 선언된 타입의 노드 정보를 저장한다. | ||
|
|
||
| ```ts | ||
| export interface Symbol { | ||
| flags: SymbolFlags; // Symbol flags | ||
| escapedName: string; // Name of Symbol | ||
| declarations?: Declaration[]; | ||
| // ... | ||
| } | ||
|
|
||
| // src/compiler/types.ts | ||
| export const enum SymbolFlags { | ||
| NONE = 0, | ||
| FunctionScopedVariable = 1 << 0, // Variable (var) or parameter | ||
| BloackScopedVariable = 1 << 1, // A block-scoped variable (let or const) | ||
| Property = 1 << 2, // Property or enum member | ||
| EnumMember = 1 << 3, // Enum member | ||
| Function = 1 << 4, // Function | ||
| Class = 1 << 5, // Class | ||
| Interface = 1 << 6, // Interface | ||
| ... | ||
| .. | ||
| . | ||
| } | ||
| ``` | ||
|
|
||
| - flags 필드는 AST에서 선언된 타입의 노드 정보를 저장하는 식별자이다. | ||
| - 심볼 인터페이스의 declarations 필드는 AST 노드의 배열 형태를 보인다. | ||
|
|
||
| > 바인더는 심볼을 생성하고 해당 심볼과 그에 대응하는 AST 노드를 연결하는 역할을 한다. | ||
|
|
||
| ```ts | ||
| type SomeType = string | number; | ||
| interface SomeInterface { | ||
| name: string; | ||
| age?: number; | ||
| } | ||
|
|
||
| let foo: string = "LET"; | ||
| const obj = { | ||
| name: "이름", | ||
| age: 10, | ||
| }; | ||
|
|
||
| class MyClass { | ||
| name; | ||
| age; | ||
|
|
||
| constructor(name: string, age?: number) { | ||
| this.name = name; | ||
| this.age = age ?? 0; | ||
| } | ||
| } | ||
|
|
||
| const arrowFunction = () => {}; | ||
| function func() {} | ||
|
|
||
| arrowFunction(); | ||
| func(); | ||
|
|
||
| const colin = new Class("colin"); | ||
| ``` | ||
|
|
||
| <img src="../../assets/CH06/kind_of_symbol.png" /> | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 5) 체커(Checker)와 이미터(Emitter) | ||
|
|
||
| ### 체커? | ||
|
|
||
| 체커는 파서가 생성한 AST와 바인더가 생성한 심볼을 활용해 타입 검사를 수행한다. | ||
|
|
||
| 체커의 주요 역할은 AST의 노드를 탐색하면서<br /> | ||
| 심볼 정보를 불러와 주어진 소스 파일에 대해 타입 검사를 진행하는 것이다.<br /> | ||
| 체커의 타입 검사는 다음 컴파일 단계인 이미터에서 실행된다. | ||
|
|
||
| checker.ts의 getDiagnostics() 함수를 사용해 타입을 검증하고<br /> | ||
| 타입 에러에 대한 정보를 보여줄 에러 메시지를 저장한다. | ||
|
|
||
| ### 이미터? | ||
|
|
||
| 타입스크립트 소스 파일을 변환하는 역할을 한다.<br /> | ||
| 즉, 타입스크립트 소스를 자바스크립트 파일(.js)과 타입 선언 파일(d.ts)로 생성한다. | ||
|
|
||
| 타입스크립트 소스 파일을 변환하는 과정에서<br /> | ||
| 개발자가 설정한 타입스크립트 설정파일을 읽어오고,<br /> | ||
| 체커를 통해 코드에 대한 타입 검증 정보를 가져온다. | ||
|
|
||
| emitter.ts 소스 파일 내부의 emitFiles() 함수를 사용해<br /> | ||
| 타입스크립트 소스 변환을 진행한다. | ||
|
|
||
| <br /> | ||
| <br /> | ||
|
|
||
| ## 6) 타입스크립트의 컴파일 과정 | ||
|
|
||
| 1. tsc 명령어를 실행해 프로그램 객체가 컴파일 과정을 시작한다. | ||
| 2. 스캐너는 소스 파일을 토큰 단위로 분리한다. | ||
| 3. 파서는 토큰을 이용해 AST를 생성한다. | ||
| 4. 바인더는 AST의 각 노드에 대응하는 심볼을 생성한다. 심볼은 선언된 타입의 노드 정보를 담고 있다. | ||
| 5. 체커는 AST를 탐색하며 심볼 정보를 활용해 타입 검사를 수행한다. | ||
| 6. 타입 검사 결과 에러가 없다면 이미터를 사용해서 자바스크립트 소스 파일로 변환한다. | ||
|
|
||
| <br /> | ||
| <br /> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 조금 찾아봤을떄는
대부분의 어떤 언어에서 다른 언어로 변환하는 컴파일이나, 트랜스 파일같은 경우는 모두
A언어 파싱→토큰화→AST생성→AST를 기반으로 B언어 생성이 과정을 따르는 방식으로 동작하더라구요!
제가 읽으면서 도움이 됬던 아티클 남겨둘게요!
(우리가 아는
Prettier도 이러한 방식으로 동작)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호.........감사합니다..!!!!!!