Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript Compile Order to Single File

I'm compiling my TypeScript project into a single JS file, at the moment by specifying an outFile in the compiler options. In my project each class is defined in a different file.

The problem is that classes that depend on each other are not concatenated in the output JS in the right order.

For example, if I have class A that extends class B, it'd mean class B would have to be compiled before class A.

(1)

class A extends B { } //error - can't find B

class B { }

(2)

class B { }

class A extends B { } //works as expected

The problem is the file order in TypeScript compile is not defined according to class dependencies, resulting in many instances of (1).

It can be solved by manually defining the compile order with many lines of:

/// <reference path="myFile.ts"/>

however it is not ideal and can quickly become a headache in large projects.

The other option from what I read is to use external modules and be able to require/import relevant classes/files.

It sounds good, but it seems to only take care of ASYNC loading during runtime of the required files after each ts file has been compiled into its own js file.

What I need is defining the right compile order according to class dependencies during compile time from ts to js.

I googled "typescript compile order" and read thoroughly the first 10 results - meaning following references to turoials, documentations, videos, etc...

It seems people have been experiencing the same problem but their questions have never been answered to satisfaction.

From what I understand it should be possible to do using the CommonJS external module, but all I can understand from the answers is a general sense of what should be happening rather than a simple and straightforward answer of how to actually do it.

If you know the answer, let's solve this issue once and for all :)

like image 956
Royi Bernthal Avatar asked Jul 30 '16 12:07

Royi Bernthal


1 Answers

It is not an issue with TypeScript, but with ECMAScript: classes are not hoisted.

See the book of Dr. Axel Rauschmayer:

Function declarations are hoisted: When entering a scope, the functions that are declared in it are immediately available – independently of where the declarations happen. That means that you can call a function that is declared later:

foo(); // works, because `foo` is hoisted

function foo() {}

In contrast, class declarations are not hoisted. Therefore, a class only > exists after execution reached its definition and it was evaluated. Accessing it beforehand leads to a ReferenceError:

new Foo(); // ReferenceError

class Foo {}

You have to take care to the order.

… or to use a bundler (Webpack) or a loader (SystemJS) with ES6 modules.

like image 115
Paleo Avatar answered Sep 19 '22 19:09

Paleo