TypeScript Template for ASP.NET MVC4

Microsoft introduced TypeScript to the world on October 1, 2012. Read my post on Hello TypeScript – Getting Started if you are new to TypeScript. It’s a typed superset of JavaScript and has rich tooling support. However it’s still in Alpha and there is only one ASP.NET MVC project that has TypeScript integrated in it and that is for ASP.NET MVC3. To use it in ASP.NET MVC4, you need to jump through a few (not so difficult) hoops.

So while until VS2012 out-of-band change comes in and adds the support for us, let us see what we can do to help ourselves. In this article, we will see the steps required to Add TypeScript support to MVC4. In the end, we will end up with a reusable Visual Studio Project template.

Pre Requisites

Make sure you have TypeScript plugin for Visual Studio 2012 installed. You can get it from www.typescriptlang.org/#Download.

Reverse Engineering the MVC3 Template

Fire up Visual Studio and start the new MVC3 Project Template.

mvc3-typescript-template

You will see the new TypeScript project option as follows. It’s a TypeScript enabled Internet Application template, as in it includes the Authentication and Authorization module.

The Project that is created has the following TypeScript specific things

1. In the _Layout.cshtml, we have an Anchor tag that’s decorated as a button using CSS.
2. In the Scripts folder, we have jquery.d.ts and site.ts. The jQuery.d.ts is the type descriptor for jQuery base and the site.ts is our custom script.

what-s-new-in-typescript-for-mvc3

3. In the site.ts we have the simple script

$(document).ready(function () {
    $(".btn-slide").click(function () {
        $("#main").slideToggle("slow");
        $(this).toggleClass("active");
    });

});

It is a simple script that is pretty much straight jQuery. However the thing to note is if you make changes to this script, it will get compiled into its corresponding .js file and the js will be available at runtime.

Under the Hood

Now let’s look under the hood to see what the project specific changes are. From the solution explorer, right click and select ‘Unload Project’. This closes all the open files and shows the project node greyed out in the Solution Explorer and marked ‘(Unavailable)’.

Now right-click on the solution node and select ‘Edit .csproj’. This opens the csproj file as an XML.
A new Target node is added which targets files specified in the <TypeScriptCompile … > node. Now as we can see, the Exec command refers to the 0.8.0.0 folder directly. We will see later that this will cause a small problem. But for now, this is the most significant change

type-script-project-changes-2
type-script-project-changes-1

The jquery type descriptor file (jquery.d.ts) is wrapped in a <None …> node so that no action is taken for this file ts file.

clip_image001

For every other TS file we add, we will get the following set of nodes. First one is the indicator for the TS compiler as we showed above. The Content node simply helps group the TS file and its corresponding JS file together in the Solution Explorer.

So along with the TypeScript tooling, these are the changes that happen in a given .csproj file to be able to support TypeScript. That’s easy, let’s do it for an MVC4 Project Manually.

Manually Including TypeScript in MVC4 projects

Let’s create an MVC4 Internet Project and then add TypeScript Support to it.

Step 1: Create an MVC4 Internet Project.

Step 2: Unload the Product using the shortcut in the Solution Explorer context menu

Step 3: Edit the csproj file as XML

Step 4: Add the following XML above the <Target Name=”AfterBuild”>…</Target> node

<Target Name="BeforeBuild">
  <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.0.0\tsc&quot; @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>


This will tell Visual Studio how to compile TypeScript Files. TypeScriptFiles are inside the <TypeScriptCompile… /> node. When you add a new TypeScript file, Visual Studio does this for you automatically.

Step 5: Save and close the XML. Reload the Project.

Step 6: Add a new TypeScript file under the Scripts folder called ts-site.ts. This will generate the ts-site.js file so at runtime, you can easily identify TS generated code.

Step 7: Delete the default code in the new TS file. If you were to go back in the XML csproj file you’ll see a node like the following.

<TypeScriptCompile Include="Scripts\ts-site.ts" />
<Content Include="Scripts\ts-site.js">
  <DependentUpon>ts-site.ts</DependentUpon>
</Content>


Step 8: Clear out the default code in the TS file and add the same code we have in the MVC3 Project sample.
///<reference path='jquery.d.ts' />
$(document).ready(function () {
    $(".btn-slide").click(function () {
        $("#main").slideToggle("slow");
        $(this).toggleClass("active");
    });
});


Step 9: You will see that the $ signs have a red squiggly indicating an error. This is because we don’t have the jquery.d.ts file. You can ideally download it from Codeplex. I copied it from the MVC3 project’s location.

Step 10: Once the jquery.d.ts file has been added, select it in the Solution Explorer and hit F4 to go to the properties window for the file. Now change the Build Action from Content to None

jquery-d-ts-properties-window

Now if you go back to the ts-site.ts file, you will see the red squiggles are gone and you can compile the project successfully.

Step 11: Testing it out.

a. Open the _Layout.cshtml and replace the ‘Your Logo Here’ with the following markup. This add an Anchor Tag with the text “Hello TypeScript”.

<a class='btn-slide'
  style='text-align: center;
  line-height: 2.8em;
  padding: 10px 20px;
  font-weight: bold;
  text-decoration: none;
  background-color: #e8eef4;
  color: #034af3;'>Hello TypeScript</a>


b. Now scroll down in the page to the section that warps the @RenderBody and give it an id=”main”

<section id="main" class="content-wrapper main-content clear-fix">
@RenderBody()
</section>


c. Now to ensure our ts file is bundled, in the BundleConfig.cs create a new bundle as follows

bundles.Add(new ScriptBundle("~/bundles/typescripts").Include(
  "~/Scripts/ts-site.js"));


d. Now to reference the Bundle in _Layout.cshtml at the bottom of the page below jquery add the typescripts bundle

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/typescripts")
@RenderSection("scripts", required: false)


typescript-home-page

And we are all set. Run the Project.

Click on the ‘Hello TypeScript’ and it will collapse the ‘We suggest the following:’ section.

typescript-home-page-collapsed

Cick it again and it will re-appear.

Create a TypeScript+MVC4 Project Template

Of the above 10 steps, first 9 were pure IDE plumbing stuff and we shouldn’t have to re-do this everytime we want to start a new TypeScript project. So let’s create a project template for ourselves.

Step 1: From the File Menu in Visual Studio 2012, select “Export Template…”. This bring up the following dialog. Select Project Template and the Web Project that you just modified. Click Next.

export-project-step-1

Step 2: In the second page update the Template Name and Description as follows

export-project-step-2

Click Finish to complete.

Using the Project Template

The project template is in our GitHub repo, so you can avoid all the steps and just download the zip file and drop it in your Visual Studio Templates folder. Typically it is at C:\Users\<user id>\Documents\Visual Studio 2012\Templates\ProjectTemplates folder.

Once you drop it here, go to Visual Studio->New Project and select Visual C # project type. You will see the following

use-exported-project

Click OK to create a new Project.

However at this point, you can’t build because if you expand the References folder, you’ll see the following references missing. Why?

new-project-missing-references

Reason is these packages are pulled in by Nuget on project creation but Visual Studio Export Project wizard does not export these specific settings. Also the fact that Nuget keeps all references at a Solution level .packages folder and the Export Project wizard considers only files in the current project. The fix is simple.

Fixing the Missing References

Step 1: Right click on the Solution node and Enable NuGet Package Restore.

new-package-enable-package

This will add a .nuget project with three files and add them to the Solution

restore-packages

Step 2: Right Click on the Solution Node again and select Manage NuGet Packages for Solution

Step 3: Click on the ‘Restore’ button to restore the missing references.

Conclusion

TypeScript is on the bleeding edge of technology and using it on a day to day basis has some rough edges out-of-the-box. Today we saw how to make our lives easier while using TypeScript in ASP.NET MVC by converting a 10 Step process into a 3 Step one using some of the built in Visual Studio Automation

Download the entire source code (click zip)




6 comments:

Unknown said...

Hi Sumit!

Nice post, thank you! But unfortunately it does't work in Visual Basic projects. What about VB? Why Typescript cannot be used in VB projects?

Anonymous said...

Hi Zoltán,
I would like to think same Steps for a VB.NET MVC Project would do the trick. Did you try it out?

I'll give it a shot in a bit and let you know.
Thanks and Regards,
Sumit.

Unknown said...

Hi Sumit!

Thank you for reply! Yes, I did it step by step. If you are in a VB project, you cannot add ts file by the Add New Item wizard, because there is no ts file option. So I added it manually. I made the modification in vbproj file (beforebuild tag and TypeScriptCompile with content tags for my ts and js files). After reloading the project I can see the ts file with associated js, I can open the ts file, the editor shows in the rigth side the js file content, but...
If I save the typescript nothing happens. VS does't compile the ts to js, js file remains empty. No error messages.
I would be very happy with typescript in VB project, because I have a lot of MVC solutions with tons of javascript code.

Thank you for help! Best regards,
Zoltán

Anonymous said...

Hi Zoltán,
I just got it going for VB.NET. I'll add the VB template to the GitHub Repo a little later in the night (here).

VB Doesn't have an item template for ts files. Looks like I have to build that too.

So rest assured it works for VB.NET hope to get you going soon enough.

Cheers,
Sumit.

Anonymous said...

Hi,

Did you manage to get it working with VB? I need this too.

Cheers

Unknown said...

If you are using the Microsoft ASP.NET Web Optimization Framework (aka Bundling and Minification), then try to use the Bundle Transformer (http://bundletransformer.codeplex.com) with installed module BundleTransformer.TypeScript (http://nuget.org/packages/BundleTransformer.TypeScript).
In addition to the compiling of TypeScript-code to JS, you can also produce minification of the generated JS-code by using other modules of the Bundle Transformer (now available modules based on Microsoft Ajax Minifier, YUI Compressor, Google Closure Compiler, Douglas Crockford's JSMin, Mihai Bazon's UglifyJS, Dean Edwards' Packer, Sergey Kryzhanovsky's CSSO (CSS Optimizer) and WebGrease).