The best solution we could come up with to meet all requirements involves the following steps:
Add references to your shared TypeScript files (using the special _references.ts file, or references directly in TypeScript files).
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
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):
Get the shared application Project URL from Properties | Web | Project URL.
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)ScriptsApp.js.map', ((gc '$(ProjectDir)ScriptsApp.js.map') -replace '../../Shared_TypeScript/','http://localhost:12345/'))
See PowerShell Replace under Sources below for more details.
- 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):
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).
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)ScriptsApp.js.map', ((gc '$(ProjectDir)ScriptsApp.js.map') -replace '../../GlobalRef/','/GlobalRef/'))
See PowerShell Replace under Sources below for more details.
Sources
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.