-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Generation of javascript files with --outDir is foolish. #812
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
in each example you pass in different files to the compiler. you need to pass the files you want to build. outDir controls the output, and not the input. so in
OutDir mirrors the source tree in the output. this is reliant on finding a "common root". so in:
hope that helps. |
Consider situation when I want to compile project incrementally so after file is created and saved I am executing tsc and then I want to add my custom logic that will be executed over generated file. As described in the previous example you will see that it is impossible, because files will be overwritten and until you compile all in one go you won't get expected result and even so considering 4th example still it is impossible to recognize location of your generated files. What am I asking here is to add flag that will force compiler to reflect the structure of folders just like in the example where common root is "src". |
Solvable by running the "finding a |
I think this is broken. I'm trying to use Webstorm to compile each file on save while developing and use grunt ts task to compile the files on the build server. grunt tsc works correctly because it compiles all the files at once as given in your example. Compiling each file individually fails to create the proper folder structured in the outDir I think it should take the prefix of the file passed on input and map that to output. It seems to only be taking a portion of the file path given on input which makes no sense to me, even after reading the explanations. tsc app\js\controllers\reporting\reportsController.ts --target ES5 --outDir build\ts Why is app\js ignored while controllers\reporting is honored? I've tried it with 1.0.1 and 1.1.0 |
@swalters this should go to the Webstorm folks. the interface the compiler provides allows you to emit a single file given its context, that is give me output for file a.ts knowing that the compilation contains (a,.ts, b\c\d\e.ts). I am not familiar with how WebStorm implemetns this features, so I can not help further. In Visual Studio, if you are using a project context, you should be getting this working as expected. similarly, if you are using --watch on the commandline, the right thing should be happening. the idea is that Compile-on-Save output, on every file separately, should result in identical results if you built all of them in one shot. |
The problem is I'm not building all of them at once. I was able to hack it by including one root dummy file, baseDir.ts, to always be compiled along with the current file For Webstorm users, my hack is: Create a baseDir.ts file with nothing in it in your project root dir. the Watcher settings I'm using are:
|
I'm using IntelliJ and use the same hack as swalters, it works but it's not ideal. Currently, it seems we only have two options to maintain directory structure:
This should be solvable by adding an option to specify a root or source directory. For example:
|
Upcoming tsconfig support should help with this scenario (see #1667) |
I like the idea of tsconfig and I think it would definitely help when you need to compile your entire project, but it doesn't look like it'll help when you just want to compile a single ts file. If I have 100 ts files and only made changes to 1 of them, I don't think I should have to recompile the other 99 just to make sure the output goes in the right directory. |
More : TypeStrong/grunt-ts#77
With |
The problem is on finding the "common root", why the common root is not just an argument ? TypeScript knows best ? Probably to simplify the usage but it's just incoherent. Let's see a very unexpected behaviour.
The file I compile "main.ts" SHOULD be in js/app, but the compiler detects a relative path to a sub-directory, and it decides to generate the file elsewhere that the directory expected. It means that depending the content of the file, it can be generated in a totally different directory :-/ The immediate solution is to do: but like we have seen before with the library: Depending of the content of the file (it's really critical), we have to adapt the command line to run. It's impossible to make automation with this unpredictable behaviour.
So, my solution was to compile twice: once with noResolve to get a nice javascript file, once with "resolve" to get error output... But thanks to open source, I have patched myself this bug. You can see the devil here: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/program.ts#L376 TypeScript considers each referenced files as input file.
Then, it looks for the "common root" like @mhegazy said. Which is "ts/", and use this common root as input source root (to mirror the file structure in the output). That's why a solution (TypeStrong/grunt-ts#77) is to create a typescript file at the root and to include it each time, in this way, we can predict that tsc will always use the same common root. This typescript file at the root can be can created before the compilation, and removed after, it's maybe the solution used by grunt-ts with their option "baseDir", and I have hesitated to use it too. But it's an ugly fix. A compiler in which we cannot predict where the output files will be is very weird. But it looks like not so critical because it's only when you do not have a root typescript file and when you do not concatenate all files in one. So, not everyone is concerned with this problem. Probably with Visual Studio this problem does not exists. At least, an argument "--auto-dir" or "--auto-root" or whatever would be fine for people who want weird behaviour. And an argument --root-dir or --base-dir should exist for the other who want a predictable behaviour. I don't know if the ".tsconfig" file will solve this problem, in particular if the "common root" algorithm stills exist. The solution was to patch this mess. If only one file is in input (I do not care about multiple files as input, because multiple files really need a "base dir" argument), and if the common root dir is different than the directory of the file, then the output directory is adjusted. For example, if the input file is /dir/ts/app/main.ts and the output directory is /dir/js/app, and the common root detected is /dir/ts (one level change), then the new output directory is changed to /dir/js (one level change too). You can view the commit here: https://github.com/synaesthesia/TypeScript/commit/8b0590686bb60b09f9e4ebf53bc38257d26994b3 I hope the ".tsconfig" will solve the problem (but by definition, we will need to have a ".tsconfig" file, it won't solve anything except that it will be a new workaround for this bug). |
Agree, very annoying and non-standard behavior. Especially if you want other tooling to pick up generated JS, it must be consistent |
Yup. Should close now probably. |
Check the examples:
//generated/example.js
tsc --outDir generated src/directory/subdirectory/example.ts
//generated/example.js
tsc --outDir generated src/directory/example.ts
//generated/example.js
tsc --outDir generated src/example.ts
//generated/example.js
//generated/subdirectory/example.js
tsc --outDir generated src/example.ts src/directory/subdirectory/example.ts
//generated/example.js
//generated/directory/subdirectory/example.js
//generated/directory/example.js
tsc --outDir generated src/example.ts src/directory/subdirectory/example.ts src/directory/example.ts
Why files path is not reflected in output folder all the time? When you define outDir you are loosing information about location of your generated file.
The text was updated successfully, but these errors were encountered: