-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
What do we call this command-line option? #2715
Comments
If you're in single-file mode, how do you even know that the module, M, in b.ts is being re-opened? |
That's the tricky thing -- this isn't a flag that turns on single-file mode. It's a flag that says "Compile this normally, but error if you do anything that doesn't work in single-file mode" |
Just in order to be sure, in such a "single-file-mode", does this following file compile? b.ts
|
Maybe --segregated, although --singleFileMode seems to say what it does. Maybe put them on the whiteboard until you hate them more than your original ideas :) |
If |
So, this is not as "single-file" as it would mean... ^_^ EDIT: I would suggest something like --localBinding |
So what you're really doing is adding linting flags or increasing the warnings level to disallow certain unsafe constructs. Is tsc.exe the right place to put this functionality as it has nothing to do with compiling and a lot to do with whether other tools can make assumptions about potentially unsafe constructs? |
-singularCompile, -individualCompile, -bounded Compile (bounded context pattern) |
Why not |
The entire point of this flag is to enable the compilation of files without examining their dependencies. 99% of the code to do this checking is in tsc already. A hypothetical external tool to do this checking would start with the tsc.js code and make about five edits. So yes, tsc.exe is absolutely the right place for this.
This isn't about conflicts. References outside the declaring file to |
Maybe --noDependencies or the team suggestion --isolated. Isolated seems to describe the kind of restrictions you may encounter. |
@RyanCavanaugh Thanks for your explanations. You know specs better :p @Steve-Fenton --noDependencies should go on the whiteboard |
I'm confused. You want to compile single files without worrying about "the world", but you want to provide warnings about re-opening modules, which you can only do by looking at the world. What am I missing here? |
This isn't a flag that says "ignore the world". It's a flag that says "Compile this normally, but error if you do anything that doesn't work if you are not allowed to look at the world" |
In this mode, we are not allowed to call a function defined in another file, are we? |
The word "strict" is basically reserved for any
It's totally allowed. The only things that would be disallowed are:
|
Since things that are disallowed are quite special cases, you should maybe consider a term with a vague, broad meaning like |
--standalone |
I don't like the "safeFor" stuff, I think names like that are leading to the confusion in the thread -- you're not changing the compilation, you're just adding warnings to the output. How about a flag named a bit more to the point, like: |
What about making it not a boolean flag but rather a two valued enum, something like:
|
@Jaykul If we refer to the cases given by @RyanCavanaugh above, I think any term including "singleFile" or "dependency" a bit too strong since all dependencies are not disallowed but only few of them. Also the compilation would look at the project scope for resolving "simple" dependencies like functions, Thus, the compilation will not be restricted to a "single file", a misleading term I think. |
@yahiko00 -- have I misunderstood? The idea is a flag which would be passed when compiling all the files which will warn you about stuff that would prevent you from getting the exact same result if you compiled individual files. That is: warn me if there's anything that will break if I compile individual files one at a time. Thus, warnForSingleFileUse -- since the only reason you'd care about these warnings is if you want to be able to to compile single files. |
What about something like |
Maybe the flag could be the answer to the question "why would I use this flag?", for example if it is to allow faster single-file compilation, it could be |
Sidetrack: such issues don't exist when only using external modules right ? |
Perhaps it's implicit on if module is specified |
@basarat there are still the const enum from an ambient declaration that needs to be flagged here. |
@mhegazy can you give me an example of what changes in emit of a file depending on a constant enum in another file. My follow up question will be "does anything bad happen if we don't do this different emit" |
The use of the const enum is replaced by the value (i.e. the number is inlined). |
@basarat emit is not conditioned on the flag. the differences is you will get an error if you use the flag with a full compilation. the example is as follows: // a.d.ts
declare const enum E {
a = 0
} // b.ts
var x = E.a; in full program compilation mode: // b.js
var x = 0 /* E.a */; in single file emit: // b.js
var x = E.a; The problem is at single file emit, we have no way to know that you can see the implementation in PR #2550. |
@mhegazy With this new flag, What would be the emit for: // b.ts
var x = E.a; (assume |
The emit would be the same. The flag is not "emit one file at a time" it is "tell me what breaks if I build one file at a time" |
@mhegazy If I have one file module M {
var s = t;
} And another file we can't look at: module M {
export var t = 5;
} And yet another we can't look at: var t = 5; Would single compiling |
The current behavior is no. But if you call ts.transpile it will give u an error because a.ts is not an external module. Would u propose to make that an error in the command line case? |
No. With that answer, why can't we get people to just use module M {
var s = t;
} Which is essentially anything that's ambient right? rant.
But I guess this is exactly what /rant |
yes :D, that is where we landed. that still leaves you with the const enum from an ambient declaration issue.. |
Got it. We want to expose
Reason for no |
Again my feature suggestion: noExternalLookupslocally:
build server
@mhegazy can you provide a |
@basarat i was not thinking of the server/local scenario, but that should work as well.. here is the scenario i had in mind. you are using something like JSPM, or es6-module-loader (with TypeScript support), system.js enabled website with TypeScript as a transpiler ..etc.. in these work flows, there are no build step. transpilation is happening on the fly, no errors reported from the compiler, only runtime errors from your browser. i.e. the compiler is called through ts.transpile.. now, you would have some tooling, e.g. VS, atom, sublime texts, etc.. you would set the flag the same can be said in a workflow like atom plugins, in your editor/local build you would use the flag, then deploy to atom and that will grantee that it is safe to transpile using typescript-simple. |
@mhegazy That scenario can be served by:
This way any errors in the tooling are errors at runtime otherwise runtime will work fine. Does that not cater for it, or do we still needs this flag? |
even with --perseveContantEnum, if you are consuming a const enum from another .d.ts that was not built with --perserveConstantEnum, it is going to fail at runtime. |
Got it. Effectively this new flag is for IDE's to:
With the purpose of safe for per file transpilation. So : |
for future references, the flag name is |
I noticed the autocomplete in VSCode for my tsconfig included the |
I makes the compiler behave as if you called ts.transpile (#2499) on each file sparely. There are some rules in place, i.e. const enums are always preserved, no namespaces, and the emitter will emit some checks when inlining types for decorators. if you are not using |
@mhegazy +1 for updating the current docs for this argument, with a better explanation or a link to a more detailed explanation like the one you have just given! :-) |
Consider two TypeScript files:
_a.ts_
_b.ts_
If we compile b.ts on its own, the
t
invar s = t
refers to the outer vart
, astring
. The emit for this line is simplyvar s = t;
.If we compile b.ts along with a.ts, the
t
invar s = t
refers toM.t
, the exported variable of typenumber
. The emit for this line isvar s = M.t
.This behavior, and a few other language features (e.g.
const enum
), prevent TypeScript from being able to correctly operate on a single file without understanding the entire universe of files involved in the program. This has performance implications for features like compile-on-save, especially in larger projects, and blocks scenarios like on-the-fly compilation in module loaders.We'd really prefer to be able to emit a file without first understanding the entire program it's a part of. The language as-is prevents this. However, by slightly subsetting the language to disallow things that require whole-program binding/typechecking, we can re-enable those scenarios. People can "opt in" their project to this language subset as a trade-off.
Tentatively, we're calling the prongs of this fork "whole program mode" and "single file mode". Naming TBD.
A key part of this is that you need to be able to compile e.g. a.ts and b.ts above in a mode that says "This code will not work in single-file-mode", e.g.:
We need some help naming these things, especially the commandline flag. The current list of ideas on the whiteboard, of which nobody likes anything, consists of the following 😦
separateCompile
singleFileEmit
disableGlobalOptimizations
safeForTranspile
safeForSyntacticTranspilation
separate
isolated
safeTransform
singleFileScope
crossFileSafe
crossFileRestrictions
Please help 🚲 🏠!
Ref #2499
The text was updated successfully, but these errors were encountered: