-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Dependency ordering with internal modules (namespaces) #8013
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
Comments
Why? What happens if the user writes code like this? console.log('A init');
class A extends C { }
console.log('B init');
class B { } B.ts console.log('C init');
class C { }
console.log('D init');
class D extends B { } There's no real solution here other than understanding that code ordering matters. |
I clearly understand code ordering matters for TypeScript and Javascript. As i commented above, there may be some edge cases. Let's say it should at least work with one class per file. Anyway Saltaralle is also a transpiler and it can handle the case you wrote above without any problems at all. It will order classes correctly before outputting. |
You can re-order C# code arbitrarily because there's no code outside of classes in C#. But in the above example, where should the |
I understand, but my request wasn't this. I didn't ask TS to order classes, just input files. If something could be resolved with // reference statements, it should be resolved with topological sort too. If not, it's perfectly ok. Your sample can't be resolved with /// references too... |
Maybe it was my mistake to state Saltaralle can do this, was just informational. Also this should be an "option" that goes into tsconfig.json, not default. |
+1 on @volkanceylan see for an instance: class Utilizer { class Proxy { console.log(Utilizer.iUseIt) Console shows the error: If you invert Proxy and Utilizer the run gives the correct result. |
Or worse: class Utilizer { class Proxy { Utilizer.tellme() |
After working on a project for over a year, I am surprised that we just ran into this issue as well. I'm surprised the compiler does not throw an error on something like:
At the time the import runs (in an IIFE), the |
Worst part is it is really hard to understand what is the problem from the error message you get. This is especially true in large scale projects, where TypeScript is supposed to "scale" better compared to Javascript. |
I Agree: |
In my use case we are either wiredep'ing individual files which just come in in alphabetic order or we concat/uglify them into one application code file. Coming back from ngConf, it is apparent that external modules (ES6 imports) and using rollup.js or WebPack v2 (to concatenate as needed) are the preferred solution. |
@rcollette more than on file compilation order it's dependent The small example I posted before works (breaks) even as a single file. That's why I think that tsc should at least file a dependency warning. |
Users already started to report issues related to this ordering problem. I think it should at least be deterministic in ordering. If input files are not specified, and located by searching in file system, compiler shouldn't enumerate them in random order. It should order them with some some deterministic sort, e.g. full path name. Otherwise, it produces different output in each compile, and it works on one compile, while it doesn't in another. |
I've written about the hazards of |
@volkanceylan You can order the |
Adding files to tsconfig.json manually and in the position it should is like something from ancient times. And i cant imagine a compiler that cant do such a simple thing. Using outFile is bad just because compiler cant handle it properly, not because its a bad idea. If a build tool can order files correctly, compiler should do it much easier. |
The build tool can only do it if you provide the hints needed aka module exports / imports. And then the TypeScript compiler can also do it (e.g. |
As an analogy, we don't re-order statements in a function. It's up to you to determine what the correct order of statements in a function is, and it's up to you determine what the correct order of your files is (if ordering matters for your program). In any other mode than folder enumeration, that ordering follows a deterministic algorithm. I agree that when enumerating files in a folder, that ordering should be deterministic. Logged #8776 |
Ok, thanks, i can live with deterministic order and references statements. |
TypeScript Version:
1.8.0
Code
I'm porting my ASP.NET MVC app platform (Serenity) which were using Saltaralle C# -> JS transpiler to TypeScript. Currently TS is an alternate option but hoping to make it primary soon, after resolving some issues.
Saltaralle and its predecessor Script# uses some code similar to TypeScript internal modules or namespaces. So it was natural for me to choose this model over more complicated AMD/CommonJS etc. modules, which is a bit overkill for web apps in my humble opinion. Also it is much easier to explain to novice users.
I'm using tsconfig.json with outFile option, and no "files" list, so all .ts files in all subfolders are included by default.
If you have A.ts:
and B.ts:
I'd expect combined output.js file to have A defined before B, otherwise it would cause a javascript error.
But, sometimes this is true, sometimes opposite. I know that you'd suggest me to put /// references or put files in correct order in tsconfig.json files property, or use external modules, but this exactly what i'm trying to avoid. I've read among several issues reported here, and workarounds offered like these, but dependency order resolving shouldn't be the job of developer, compilers are specially made for this.
I'd handle these workarounds myself, for my own projects, but my targeted users (devs) usually don't have the skills to understand what this ordering is all about. They'll simply report a bug with details: "not working", and without looking at their output file, i can't even guess what it is really about.
I understand that in some edge cases this might be difficult, but please offer an option to perform topological sort on input files for basic cases like this, e.g. a class extends another, references it in a decorator argument etc.
Expected behavior:
I'd expect internal modules to be topologically sorted based on dependencies.
Actual behavior:
Sometimes it is not. Derived class outputted before base class.
The text was updated successfully, but these errors were encountered: