assetic
assetic copied to clipboard
TypeScriptFilter now uses actual file instead of temp (if it exists)
Modified TypeScriptFilter to use the actual file (instead of making a temp one) if the actual file is available (e.g., it's not a StringAsset). This allows the TypeScript compiler to honor TypeScript reference paths (without this change, you can't use them which means you have to put all of your TypeScript code in one file).
Also updated the test (TypeScriptFilterTest::testFilterLoad) to cover this new scenario.
This is wrong as some other filters may already have been applied
Do you have a proposed method for how to have it still use the original file then? The problem is if we don't use the original file (or at least a file in the original spot), the references won't match up.
I guess we could have it create a temporarily file in the original files directory, but that might be a bit ugly.
There's an example of how we do this here: https://github.com/kriswallsmith/assetic/blob/master/src/Assetic/Filter/LessFilter.php#L92
Can you configure TypeScript load paths in a similar way?
Unfortunately not, unless it is some well hidden and undocumented compiler option.
Basically, each file defines lines like this near their top:
/// <reference path="./someFile.ts"/>
All of the reference paths are usually relative, so they are dependent on where they live.
I might be able to rewrite them in the actual file right before I process them. So, something like the above may turn in to something like (assuming we are in /tmp/someFolder/somePath.ts)
/// <reference path="../../../var/www/path/to/my/file/someFile.ts"/>
That should work, in theory.
I modified it so it goes back to creating a temporary file in a temporary directory. It will now do a regex check for any references and will replace them with a path relative to the temporary file's directory and the original directory, so it should still link up properly.
I also added a new option to the constructor. When set to true (its default value), it has exactly the same behavior as before I touched it. If set to false, it will avoid using the --out flag for tsc (TypeScript Compiler).
That flag normally sets the output file, but has the odd attached behavior of also including the compiled source of any referenced files in to the file itself. Since TypeScript uses a predictable output file destination if --out isn't set (just switch .ts with .js), it's pretty easy to still catch.
So, I just discovered an interesting bug this causes. ~~Apparently TypeScript can't recognize when two reference paths are actually the same file.~~ TypeScript sees you have the class in two files, and throws an error. Thanks to this, it generates an error when it tries to do the reference path thing if you have two files referencing the same identifier (class, etc.).
Example: A.ts implements class A, B.ts implements class B. Each references the other. We use TypescriptFilter and it copies the body of A.ts to a temporary file. The reference for A to B is updated. When TypeScript looks at B, it sees it references the original A.ts file, which tries to declare class A, the same as our temp file, and throws an error.
So, this puts us back with ~~either putting the temporary file in the same directory (which does work, I had already implemented that before I implemented what I pushed a few minutes ago), or~~ we basically parse out everything all the files reference and copy them all to a temporary directory... which obviously isn't a fantastic way to go for performance reasons, or we use the original file and force this filter to not be compatible with any others. =SSS
The other alternative would be to override the source file with the updated code, then put it back. This is probably the worst option though, because if something goes wrong mid-copy, your original may be foobar.
Edit: Corrected
I'd rather not have the $this->useOut
switch. We should determine the best way to use TypeScript and do it the same way every time.
I would rather avoid it as well. The problem is with the awkwardness of the TypeScript compiler and the fact that they've bundled whether or not the code of referenced files is put in to the output file or not with the flag for output itself.
Consider the following scenario:
class A {} class B extends A {}
There are two ways you can write this, depending which pattern you follow. (You could have all of these in one file. In this scenario, it becomes a moot point, you just reference the one file, no outside references, so no big deal, so it's a third way which I'm not looking at.)
However, consider the second option, you have them in a file named A.ts and B.ts (following conventions similar to what we do with PHP). In this case, A.ts would have to reference B.ts and B.ts would have to reference A.ts. Now, if you want to just include B.js, that could work because the code of both would be there. That's one approach. The other would be to have it not, and then you reference both files in your HTML so they are both loaded.
Consider a slightly more complex example though: class A {} class B extends A {} class C extends A {}
In this scenario, you can't just include B.ts and C.ts if they have their references' code in them, because they would both declare A, which would cause you to have two declarations of the same file. If C also referenced B, it would throw an error in the filter when it tried to compile. If it didn't, it would seem to compile fine, but wouldn't update properly because changing B would only cause B.js to update, not C.js. This makes it very annoying to debug without having to manually clear your whole cache every time (not to mention slow). So, we could say that it is also best to NOT include the extra code.
However, that breaks the scenario where you purposely have a file which references everything and then rely on that functionality to put all of the needed code in to one file, in the proper order, which is probably favored by a number of people.
Both methods are perfectly valid, but come down to personal preference.
I don't think $this->useOut should be used as a value you change each time you use this though. In my implementation it's one of my configuration variables which is set for my whole system (in Symfony2). This allows someone to override the default functionality (of using --out) only if they want.
Please resolve this and merge - its very useful update for filter!