Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio: How to debug TypeScript in a shared project using IIS Express and cross-project references (no linking or duplicating files)

Ideally, we could simply add shared TypeScript project reference to another project and be able to use the referenced code just like we can with Visual Basic or C# cross-project references. Alas, that's not available yet.

Hopefully, Microsoft will upgrade Visual Studio in a near-future version so that it supports seamless cross-project TypeScript debugging without having to duplicate shared files. Until then, we need a workaround. Several others have asked a similar question on Stack Overflow:

  • VS2013 Typescript: Referencing and debugging with multiple projects
  • Typescript debug ts files that are in other project
  • Cross-project references between two projects

But none of those questions meet all of the requirements indicated in this question. Here is why the the answers posted in those questions don't meet our needs:

Problems with linking files, either recursively or manually in Visual Studio

  • Debugging and Go To Definition both do not work well, or at all, on linked files. The linked file does not exist when debugging an ASP.NET website.
  • Some helpful plugins view each linked file as a separate file, which slows down code review and debugging across the entire solution (for example, an error in a single linked shared file will show as three separate errors: one for the original file, one for Referencing Project A, and one for Referencing Project B).
  • It's inelegant.

Problems with copying files from the shared project to the referencing project

  • No matter how careful you are, chances are high that you will edit a duplicated file directly, rather than the original shared file; when you rebuild, all your changes in the duplicated file will be lost.
  • Problems with linked files apply here, as well.

Problems with simply referencing shared project TypeScript files

  • The generated map files, which are required for debugging in multiple systems, do not point to the shared projects. Instead, it points to path-relative file references, which breaks shared file debugging.

Other requirements

  • We need to retain the ability to build shared TypeScript directly into each referencing application, rather than using a separate shared website and then including that shared code, because the referencing apps target different ECMAScript versions (e.g. ECMAScript3 for a public website and ECMAScript 5/6 for an admin website for which you can specify the minimum browser version) and different apps reference different shared files (referencing projects reference different groups of files in the shared project via different reference.ts files, thus keeping references neat).
  • Debugging via a shared website is OK in the development environment, but for production builds, the shared code needs to be built directly into the referencing projects.
  • All TypeScript files, including shared files, are compiled into a single file called App.js in each referencing project.
  • Ensure that debugging is possible outside of Visual Studio (so we can debug with Chrome, Firefox, and other browsers that support map files, as well as debug within Visual Studio/Internet Explorer).

Anyone have a solution to this problem, or know if Microsoft is building cross-project referencing (including full debugging support) into Visual Studio 2015?

like image 593
lightmotive Avatar asked Sep 29 '22 02:09

lightmotive


1 Answers

The best solution we could come up with to meet all requirements involves the following steps:

  1. Add references to your shared TypeScript files (using the special _references.ts file, or references directly in TypeScript files).

  2. Automatically update the TypeScript-generated map file using PowerShell so it points to either a shared Web Application's Project URL or a Virtual Directory (available for both IIS Express and full IIS).

I realize this looks like a lot of work, but it shouldn't take more than 30 minutes to set up. It works great and will save development effort and time in the long run:

1. Add references to your shared TypeScript files

  • Visual Studio makes this easy: drag a TypeScript file (either individual files or a _references.ts file) from a shared project to a referencing project's _references.ts file or to any other TypeScript files (_references.ts can keep references nice and neat, but it might not benefit all project structures). Note that the _references.ts file must always be in the root of your project in order to work as expected.

Sources

  • Visual Studio 2013 Typescript compiler isn't respecting '_references.ts' file
  • http://blogs.msdn.com/b/typescript/archive/2013/12/05/announcing-typescript-0-9-5.aspx.

2. Automatically update the TypeScript-generated map file using PowerShell (to enable debugging)

This step ensures that shared references point to the original shared files using a method that works with Visual Studio, Chrome, and Firefox debugging (replace relative shared references with Project URL or Virtual Directory).

To Microsoft: This type of referencing should be configurable and/or automated in a future Visual Studio release, e.g. if a file is referenced from a different project, automatically map the reference to the shared project's Project URL.

Option 1: Your shared code is in a Web Application project.

This works for multiple debugging systems (tested with Visual Studio, Chrome, and Firefox):

  1. Get the shared application Project URL from Properties | Web | Project URL.

  2. Use a Post-build Event to run a PowerShell script that will replace all shared references in your App.js.map files to point to the Project URL.

Example Post-build Command:

Powershell [io.file]::WriteAllText('$(ProjectDir)Scripts\App.js.map', ((gc '$(ProjectDir)Scripts\App.js.map') -replace '../../Shared_TypeScript/','http://localhost:12345/'))

See PowerShell Replace under Sources below for more details.

  1. Make sure you set up your shared Web App project for debugging along with your referencing Web App projects.

Option 2: Your shared code is not in a Web Application project.

This does not work for Visual Studio debugging, but might be a better option for some scenarios, and it's the only known option for non-web application projects (tested with Chrome, probably works for Firefox):

  1. Add Virtual Directories to your IIS Express website configurations that point to your shared TypeScript project: https://stackoverflow.com/a/8929315/2033465 (see the EDIT).

  2. Use a Post-build Event to run a Powershell script that will replace all shared references in your App.js.map files to point to the Virtual Directories you set up above.

Example Post-build Command:

Powershell [io.file]::WriteAllText('$(ProjectDir)Scripts\App.js.map', ((gc '$(ProjectDir)Scripts\App.js.map') -replace '../../GlobalRef/','/GlobalRef/'))

See PowerShell Replace under Sources below for more details.

Sources

  • PowerShell Replace: VS2010 Post-build event, replace string in a file. Powershell?

If you need to be able to debug TypeScript files in the production environment (not one of our requirements), then you could alter the post-build script to run a different command (similar, but point to your shared website's Virtual Directory instead of localhost). That's outside the scope of this post.

Conclusion

That is by far the best method I could come up with (thanks to all of those other sources) that meets all of the requirements.

Please let us know if you have a better method.

like image 165
lightmotive Avatar answered Nov 30 '22 04:11

lightmotive