When working with TypeScript in Visual Studio, you may want to split your code up into several projects. One project may be a library while another project is a full application. Unfortunately, the Visual Studio build system currently does not support TypeScript projects, and referenced projects that have TypeScript items do not have the TypeScript files copied on build.
This build tool can be added to any project as a NuGet package and when you build, all referenced projects (and the projects they reference) will be searched for .ts files. When found, the .js, .js.map, .d.ts and .ts files will all be copied to a libraries folder in the project. Also, the .ts file will be renamed to .ts.source so Visual Studio doesn't notice it (details below) and the .js.map file will be modified to point at the .ts.source file (so debugging works).
- Create a TypeScript project (A).
- Add a TypeScript file to the project (MyModule.ts).
- In the project properties, set the TypeScript compiler to
generate a source maps
andgenerate declaration files
and to use AMD or CommonJS. - Create another TypeScript project (B).
- Add Zoltu.BuildTools.TypeScript.FromReferences NuGet package to the project.
- Add a TypeScript file to the project (MyApp.ts).
- In the project properties, set the TypeScript compiler to use AMD or CommonJS (same choice as project A).
- Add a reference to project A.
- In MyApp.ts, import MyModule like so:
import MyModule = require("libraries/MyModule");
- Build the solution.
If you were to copy MyModule.ts
into project B, you would run into some subtle problems. The primary one is that if you use Visual Studio's Go To Definition
in MyApp.ts
, it will take you to the .ts file. At first, this sounds great, but the problem is that it takes you to the copy of MyModule.ts
that is in the libraries folder of project B. If you were to make changes to this file, your changes would be overwritten with the original MyModule.ts
(from project A) as soon as you compiled again. To work around this, we copy MyModule.ts
to project B with a different name.
What happens when you use Go To Definition
in Visual Studio then? It will simply take you to the .d.ts file, which is much more obvious that you shouldn't modify. You will still get full intellisense because the .d.ts contains all of the information necessary to populate the intellisense menus, you just don't see the full source code for your functions.
Why then do we copy MyModule.ts
at all if we are just going to rename it so Visual Studio can't find it? It is because we also modify MyModule.js.map
to point at MyModule.ts.source
. This means that when you are debugging in Firefox, Chrome, Internet Explorer, or even Visual Studio you will get source mapping over to MyModule.ts.source
! This means while debugging you have full access to the source code, but while coding you only have easy-accidental-write-access to the definition file.
If you want the copied files to go somewhere other than $(ProjectDir)libraries then you just need to add a property to a PropertyGroup of your .csproj file like <TypeScriptLibraryFullPath>app\scripts</TypeScriptLibraryFullPath>
.
If you don't want the .ts or .js.map files to be copied over then you can add a property to a propertygroup (same as for changing the library Path). This property should be:
<TypeScriptLibraryCopyAll>false</TypeScriptLibraryCopyAll>
The default value for this property (if it is ommitted) is true so it will copy over your .ts and .js.map files (though see note on renaming of .ts files).