# outFile 주의사항

이것의 사용이 나쁜 이유는 아래와 같습니다:

* 런타임 오류
* 빠른 컴파일
* 글로벌 스코프
* 분석이 어려움
* 확장이 어려움
* `_references`
* 코드 재사용
* 여러 개의 타겟
* 분리된 컴파일

## 런타임 오류

코드가 어떤 식으로든 JS 순서에 영향을 받는다면 런타임에 무작위적인 오류가 발생할 수 있습니다.

* **클래스 상속이 런타임에 깨질 수 있음.**

`foo.ts` 를 보세요:

```typescript
class Foo {

}
```

그리고 `bar.ts`:

```typescript
class Bar extends Foo {

}
```

올바른 순서로 컴파일하지 않는다면, 예를 들어 알파벳 순으로 `tsc bar.ts foo.ts`, 컴파일은 잘 되지만 런타임에 `ReferenceError` 오류가 발생할 것입니다.

* **모듈 분할이 런타임에 실패할 수 있음.**

`foo.ts` 를 보세요:

```typescript
module App {
    export var foo = 123;
}
```

그리고 `bar.ts`:

```typescript
module App {
    export var bar = foo + 456;
}
```

올바른 순서로 컴파일하지 않는다면, 예를 들어 알파벳 순으로 `tsc bar.ts foo.ts`, 컴파일은 잘 되지만 런타임에 *조용하게* 실패하고 `bar` 는 `NaN` 으로 설정될 것입니다.

## 빠른 컴파일

`--out` 을 사용한 경우, 특별한 조작을 하지 않는 이상 하나의 `.ts` 파일이 하나의 `.js` 로 분리되어 생성될 수 없습니다. 결과적으로 `--out` 은 더 느린 점증적 빌드를 강요합니다.

또한 소스 맵은 위치에 민감해지고 런랭스(run-length) 인코딩이 되어 소스 맵을 사용하려면 (당연히 사용해야 함!) 대부분의 파일을 재컴파일로 다시 빌드해야 합니다. 라인 수가 1만 후반에서 10만 정도라면 느려질 수 밖에 없습니다.

## 글로벌 스코프

이름 공간을 사용할 수 있지만 브라우저에서 실행한다면 여전히 `window` 에 속한 것입니다. 이름 공간은 불필요한 문제 조치일 뿐입니다. 또한 `/// <reference` 주석이 여러분의 코드에 글로벌 컨텍스트을 추가하기 때문에 관리가 까다롭습니다.

그리고 여러분의 회사에 독립적으로 일하는 여러 개의 팀이 있고 누군가가 각 팀에서 작성한 앱을 하나로 합치게 된다면 아주 높은 확률로 이름 충돌이 발생할 수 있습니다.

## 분석이 어려움

우리는 더 많은 코드 분석 툴을 공급하고 싶습니다. 우리에게 종속성 체인이 제공된다면 더 쉽게 할 수 있을 것 입니다 (외부 모듈을 사용하면 이게 공짜로 깔끔하게 제공됨).

또한 코드 분석이 어려워지는 것은 *개발 툴* 만의 문제가 아닙니다. 다음에 오는 사람도 어떤 내용이 어디서 임포트되는지 이해하려면 많은 양의 코드 베이스를 이해해야 합니다. 내부 모듈을 사용하면 코드를 단독으로, github 같은 곳에서 리뷰할 때도 어렵습니다.

## 확장이 어려움

무작위적인 런타임 오류 + 느리고 느린 컴파일 시간 + 다른 사람의 코드를 이해하기 어렵기 때문입니다.

## `_references.ts`

`tsconfig.json` : <https://github.com/Microsoft/TypeScript/issues/2472#issuecomment-85330803> 에서 지원하지 않으며, 수동으로 `files` 배열의 순서를 관리해야 합니다.

## 코드 재사용

코드의 일부를 다른 프로젝트에서 재사용하려면 모든 *암묵적인* 종속성을 관리해야 하므로 이식이 어렵고 런타임 오류로 이어질 가능성이 높습니다.

## 여러 개의 타겟

그리고 브라우저 용 코드를 (예를 들면 API *테스트* 를 위해) nodejs 같은 다른 곳에서 사용하기로 했다면 모듈 시스템으로 포팅하거나 nodejs의 `global` 이 여러분의 글로벌 스코프 (예를 들어 `window`)에 대응되도록 복잡한 꼼수를 써야할 것입니다.

## 분리된 컴파일

파일을 분리해서 컴파일할 수 없습니다. 예를 들어, 다음의 `a.ts`:

```typescript
module M {
  var s = t;
}
```

파일은 다음 형태의 `b.ts` 가 있는지 없는지 여부에 따라 출력이 달라질 것입니다:

```typescript
module M {
  export var t = 5;
}
```

또는

```typescript
var t = 5;
```

그러므로 `a.ts` 파일은 [분리해서 컴파일할 수 없습니다](https://github.com/Microsoft/TypeScript/issues/2715).

## 요약

`--out` 은 사실 빌드 툴이 해야하는 일입니다. 그런 툴일지라도 외부 모듈을 통해 제공되는 종속성 정보가 있다면 도움이 될 것입니다. 그러므로 우리는 외부 모듈을 사용하고 필요에 따라 빌드 툴이 단일 `.js` 를 생성하게 하는 방식을 추천합니다.

<https://twitter.com/nycdotnet/status/613705850574778368>

![The Bas Signal](https://pbs.twimg.com/media/CIRSOBmWsAQdzvP.jpg)
