Recently our team has been using TypeScript for all our Javascript work. To be honest it has been a complete pleasure as it ‘just works’. However one annoyance we quickly found was that we had to choose what was the best approach for using TypeScript. Do we have a single .ts file which compiles down to a single .js file or do we have multiple .ts files which each compile down to their own .js file. There are clearly pros/cons to both approaches
Single .ts file pros/cons
Pros:
- Means keeping all our javascript in a single place, making it a bit easier to find/update
- Means that we only need to reference on .js file in our bundles
Cons:
- Means that our .ts file could become very large and unmanageable over time
- Means that we are increasing our risk of merge issues when we commit it to git
Multiple .ts files pros/cons
Pros:
- Means we have smaller files to work w/ which should allow for better manageability
- Means we could include a given .js file in a view if we so chose
- Means we could reduce our .js file size for downloads if we so chose
Cons:
- Means we have multiple .js files which need to be references in our bundles
After weighing the pros/cons of each we decided the we better liked the idea of having multiple .ts files, but we also wanted a single .js output file. Yea we want our cake and be able to eat it to.
The good news is that this is 100% percent doable. One of my kick ass devs on our team spent a bit of time working on this problem (read that as THIS IS NOT MY DISCOVERARY) and found a solution.
The trick was finding out that the command line tool for compiling .ts files has an –out options. Below is what he did to get this to work
Step 1: setup the correct content type
Open up your .csproj file and look for all references to your .ts files. They should look something like below
<Content Include="ViewModels\Authentication\LoginViewModel.ts" />
You will want to change the type from ‘Content’ to ‘TypeScriptCompile’ as below
<TypeScriptCompile Include="ViewModels\Authentication\LoginViewModel.ts" />
Step 2: Add the property group below to your .csproj file
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptSourceMap> --sourcemap</TypeScriptSourceMap>
</PropertyGroup>
You will want to add this towards the top of the .csproj file
Step 3: Add a Before Build Step to your .csproj file
Open your .cspoj file and add the block below to the bottom of your file
<Target Name="BeforeBuild">
<Message Text="Compiling TypeScript files - $(TypeScriptSourceMap)" />
<Message Text="Executing tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'"%(fullpath)"', ' ')" />
<Exec Command="tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'"%(fullpath)"', ' ') --out Scripts/MySingleFile.js" />
</Target>
You will want to change the path in the Exec command. I have mine set to Scripts/MySingleFile.js, you may have a different need
Step 4: Add this .js file to your MVC Bundles
bundles.Add(new ScriptBundle("~/bundles/projects").Include(
"~/Scripts/MySingleFile.js"));
Step 5: Include the new bundle in your view
@Scripts.Render("~/bundles/projects")
The only issue we have found so far is that unless you use the TypeScript project template you will have to manually switch your Content type for all .ts files each time you add a new one. This is a PITA but i am sure there is a solution for this to but we have not spent the time or energy to solve it.
Till next time,
Posted
12-08-2012 9:00 AM
by
Derik Whittaker