Is it possible to make a reference between two TypeScript projects? Assume we have the following project structure:
The accepted answer disallows debugging in Visual Studio when a breakpoint is set in the Shared project. (At best the debugger will stop on a line in the compiled javascript, but not the original Typescript and certainly not in its original project location.)
In the Shared project's properties, let's say that Combine Javascript output into [a single] file is checked and set to AllShared.js
, which also makes a AllShared.d.ts
file because Generate declaration files is checked, and also makes a AllShared.js.map
because Generate source maps is checked.
The referencing project should NOT copy or link these files in the way the accepted solution does. Instead:
Part 1, in the referencing project, create /typings/tsd.d.ts
if it doesn't already exist, and append to the bottom of that file the line ///<reference path="../../SharedProject/AllShared.d.ts" />
. Once this is done, (and at least one successful compile of SharedProject is done), Intellisense and the Typescript compiler should see Interface1 etc. (You'll likely get a red squiggly line underlining the statement if the path/file doesn't exist, which is nice.)
Part 2, in the referencing project's index.html
, add the line <script src="http://localhost:29944/AllShared.js"></script>
before that project's own script tags. The localhost part comes from the Shared project's Properties, Web tab, Project Url. (Both 'IIS Express' and 'Local IIS' work.)
Now when you run the referencing project, you should see Internet Explorer** request the relevant files from their respective "websites". Visual Studio breakpoints should be hit regardless whether they're in SharedProject or the referencing project.
. Although this solution works without gulp/grunt/powershell, Visual Studio's Combine Javascript output into one file doesn't glue together the files in any particular order, and it will eventually break your code. Then you'll need to add Gulp/etc. to the referencing project to insert a <script src="http://localhost:29944...
tag for each file in Shared***, because keeping index.html
updated by hand is a poor option. (Adding Gulp to the Shared project, to concat the .js and .d.ts files into singles runs into an issue with .js.map files, which can't be simply concatted.)
** IE and VS are both Microsoft products, so IE really works better if you want to use VS's breakpoints and debugger instead of a web browser's.
*** Gulp doesn't like injecting urls, only filepaths. Given HTML comments in index.html
like <!-- SharedStuff:js --><!-- endinject -->
, circumvent this like so:
gulp.task('insert-into-html', [], function () {
var common = gulp.src(['../SharedProject/**/*.js'], { read: false });
return gulp.src('./index.html')
.pipe(inject(common, {
relative: true,
name: "SharedStuff",
transform: function (filepath) {
return '<script src="http://localhost:29944/'+filepath+'"></script>';
}
}))
.pipe(gulp.dest('./'));
});
If you need to share the code between multiple projects you can always create a symbolic link on each project where you need it. http://en.wikipedia.org/wiki/Symbolic_link
There's lots of ways you can do this.
Option 1 - Project References (TypeScript 3.0+)
If you are using TypeScript 3.0 then look at using project references. Read more here.
Option 2 - Build script
Use something like gulp-typescript, grunt-ts, or just a batch script to copy the files over into a folder in the main project.
Alternatively, run a build event in Visual Studio that will copy the files over to the main project.
Option 3 - npm package
If you use npm, you could create a package for your other project. Then you can use your package in your main project. Specifying a local dependency is a good way to do this or by using something like sinopia, which is a private repository server. I've never used it, but it looks like it would work well.
Option 4 - NuGet package
You could look into creating a nuget package and then installing it locally.
Option 5 - --declaration --outDir
compiler option
You can set the --outDir
compiler option or the outDir
property in tsconfig.json with the directory to your other project then also compile it with --declaration
so that it generates the declaration files (.d.ts
) too. For example: --declaration --outDir ../Test1/External
.
Original Answer (Using --out
)
You can do something similar in Visual Studio if you right click on your library project and click properties. In the TypeScript Build
tab, check off the option to Combine JavaScript output into file
and specify the location in your main project you want it to go (Ex. $(SolutionDir)/TypedApp/External/TypedLibrary.js
). Then also check off Generate declaration files
in order to generate a .d.ts
file.
Once this is done, build your library project and then include the .js
, and .d.ts
in your main project. Include the .js
file in your html and reference the .d.ts
in your typescript files.
Each time you rebuild the library project, it will automatically update the main project with the changes.
I just want to add to the answer of David Sherret that the lib files to the TypedApp project could be added as Link files instead of depending on post build events. I'm having some issues with post build events in big solutions with a lot of projects, and the link files are now working ok for me. (I cannot add a comment to the answer because I only have 35 reputation points).
basarat's answer is the closest to being the most reliable solution for cross-project TypeScript references. However, when merging shared TypeScript code with a referencing project's TypeScript (important, for example, if you need to target different ECMAScript versions), the Source Map file doesn't resolve to the shared project's directories, so debugging won't work (in fact, Visual Studio often crashes after adding breakpoints to the files referenced in another project).
Linked files of any kind (Visual Studio links and symbolic links) don't work with debugging in any system (Visual Studio, Chrome, WebStorm, etc.)--linked files essentially don't exist to the ASP.NET debugger, nor any other debugger; they exist only in Visual Studio.
Please see this question/answer indicating what has worked great for both solid code maintenance and debugging in Visual Studio, Chrome, and Firefox, while still retaining the ability to combine shared code with the referencing projects' code (important, for example, if you need to target different ECMAScript versions): Visual Studio: How to debug TypeScript in a shared project using IIS Express and cross-project references (no linking or duplicating files)
Frustrated with the state of affairs, I wrote a NuGet package that mostly solves this problem. Using the NuGet package you can just add a reference from one project to another and it will do the work of copying files around in a way that is safe from accidentally editing the wrong file and still gives intellisense and debugging.
Details can be found in the Readme.md, or you can just install the NuGet package and run (I recommend at least reading the how to use section).
https://github.com/Zoltu/BuildTools.TypeScript.FromReferences