Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: TypeScript Library Project in Visual Studio #11

Closed
RyanCavanaugh opened this issue Jul 15, 2014 · 31 comments
Closed

Suggestion: TypeScript Library Project in Visual Studio #11

RyanCavanaugh opened this issue Jul 15, 2014 · 31 comments
Assignees
Labels
Committed The team has roadmapped this issue Suggestion An idea for TypeScript Visual Studio Integration with Visual Studio

Comments

@RyanCavanaugh
Copy link
Member

Create a project template and project system support for a TypeScript 'library'

Library project outputs would include a .d.ts and a .js file; referencing projects would consume the .d.ts file automatically and have separate compilation. Refactoring in the referenced project would be reflected in any loaded referencing projects.

@jvilk
Copy link

jvilk commented Jul 21, 2014

Library project outputs would include a .d.ts and a .js file

This would be excellent as a standalone compiler feature. As it stands, my multiple AMD module projects are compiled into a single JS file using the RequireJS compiler, but there's no way to automatically tell the TypeScript compiler to do the same for their declaration files (you end up with one .d.ts per module). This is problematic for the same reason: I have no 'clean' way to reference one library from another (although I am using npm modules, not Visual Studio projects).

My use case is that one module ends up being the exported 'frontend' in a global variable, from which all library functionality is exported. If this is the common case, then perhaps TypeScript could support a command line option for emitting a .d.ts file that contains the frontend module exported as a particular global variable, and all types/modules that are 'reachable' from the frontend.

Namespacing might be an issue here when you are using 100% AMD/CommonJS modules; I haven't thought too deeply about it yet.

@andrewvarga
Copy link

This is somewhat related to #293 as that also aims to help using library projects.

Library project outputs would include a .d.ts and a .js file

To me this wouldn't be a feature I'd use, as one of the advantages for using typescript library projects (specified with a custom path) would be that I only use the classes/modules that I need, there's no point packing everything together when I may only use one small feature of it.

@MrKWatkins
Copy link

I would love to see a dedicated project type for TypeScript in Visual Studio that handles references and copying of output around automatically, in much the same way that a C# project automatically copies around it's assemblies. Currently I have the following:

  • A web project containing core TypeScript code.
  • A web project containing tests for the core code.
  • Two different websites in different solutions that both use the core code.

To make this all work I have to:

  • Have pre-build actions to copy the .js and .d.ts files from the core project into the websites and test project before building.
  • Specify 'Combine JavaScript output into file'.
  • Specify the two root directories to get s in the output .d.ts correct.
  • Make the websites and test project reference the core project. Without this we can't guarantee that our core project is built first so we might copy an old version into the other projects

The problems with this are:

  • You lose TypeScript debugging for the core project - you instead have to step through the final .js output. (Even if you copy the .js.map files across -
  • It's a lot to setup! (No-one likes using pre/post build actions if they can help it...)

Minor problems:

  • Because the web projects are really C# projects you get empty .dlls floating around the place.
  • Any references to third party typings in the Core project come through as s in the output .d.ts file. Due to their paths this forces me to put them in my root directory, rather than Scripts\typings.

Now it maybe that I'm not setting these projects up correctly and some of these things can be fixed. (s seems like it should be fixable for instance) But in an ideal world there would be a dedicate project type for TypeScript that solves all this automagically for me. The project would:

  • Contain just TypeScript only. No empty C# .dlls. If I want webpages/C# as well, as I might for unit tests, then I can just use the existing web project.
  • Be referenceable by other TypeScript projects and web projects.
  • Automatically copy the .js output into the target project on build, much like a C# .dll is automatically copied around. Maybe allow the path for it to be specified in target web projects? (E.g. a web project by default puts its .js files under /Script but you might want that to be configurable)
  • The biggie - when debugging a web project that references a TypeScript project I'm able to put breakpoints in the .ts files in the TypeScript project and have them hit. (Instead of the having to hit breakpoints in the output .js file in the web project.)
  • Also automatically copy .d.ts/.js.map if needed to make everything work, changing references directories in them as necessary. (This is really an implementation detail for me - I don't care if there files are there or not provided the above works!)

That's how I see it working anyways, hope it helps. Happy to give more detail and help out if you want, get in touch.

@joewood
Copy link

joewood commented Jan 22, 2015

Wouldn't the simplest solution be for Visual Studio to support the new .tsconfig file? A simple TypeScript only project that uses this new file to drive the settings for the compiler. Debugging would be supported using source maps.

I'm not sure we need a new way to do package sharing/references over and above the normal web way of using npm and browserify etc...

@MrKWatkins
Copy link

You say 'normal web way'... But that's not what I'd consider normal...

So from my point of view, this is what's happened.

  • I've been doing ASP.NET and ASP.NET MVC for websites for years.
  • Need to start a new website, so I fire up Visual Studio and create a website project.
  • I think "right, TypeScript sounds good, I'll code in that instead of JavaScript for all the client side code that is gonna run in my users' browsers".
  • I then need to start another website, so I fire up Visual Studio, create another website project and use TypeScript in it.
  • Then I decide "right, I'm writing the same code in both websites, lets see if I can share it". So I go to add a new project in Visual Studio, see the TypeScript project, add that in and go from there.

That's normal from my point of view. :)

Now if I'm supposed to be using Node and NPM and Browersify and so on, that's fine. Happy to go with the norm. Where is that documented though? I can't see anything on typescriptlang.org or the Visual Studio docs about setting up TypeScript projects in VS and using NPM and the like. I've done a lot of web searching about TypeScript projects without much luck.

Also if its the norm then why doesn't the website/TypeScript projects in Visual Studio use all that stuff already? Maybe that's the answer - change those projects (or create new ones) that use this NPM/Browserify approach.

Also with NPM - would I also then be in a position where I have to use NPM as my package manager for JavaScript stuff and NuGet for the rest? That would suck!

Sorry if that sounds like I'm moaning, I'm really not. Just as a relative newbie to TypeScript setting all this stuff up has proved hard for me so if we could make it easier for other newbies that would be great. And if one of you could tell me the answer to my problems then that would be even better still. :P

@NoelAbrahams
Copy link

@MrKWatkins, as far as I know there is no way to mix ASP.Net/Nuget and npm.

If you want to use npm in Visual Studio then I suggest trying out NTVS. They have a lovely set of tools (interactive Node.js window, test harness, debugging) that integrate well with Visual Studio. They also have an npm UI:

image

I was hoping for something similar for TypeScript. @paulvanbrenk seemed to suggest that the TypeScript team is working with the NTVS team. Haven't seen anything yet.

@MrKWatkins
Copy link

Thanks @NoelAbrahams. I don't really want to use NPM to be honest, I'd just be prepared to if it solved my problems. Or if it was the accepted way of doing things. I'd really much prefer a TypeScript project as a first class citizen, with all my references and debugging automagically working.

@NoelAbrahams
Copy link

Perhaps the following two issues should be subsumed under here:

@EvAlex
Copy link

EvAlex commented Apr 21, 2015

👍 Came here to suggest this feature. Found this issue already created.

@SilentPenguin
Copy link

@MrKWatkins, Another similar approach, debugging with mappings works for the setup I have.

Currently, I'm working with website projects as you discussed, and inserting links to typescript files I wish to access in my main site, this can be done just fine using the project explorer, using "Insert Existing Item" and then choosing "Add As Link". Your .csproj file then looks something like:

<ItemGroup>
    <TypeScriptCompile Include="..\..\Test.ts\Test.ts\Assert.ts">
      <Link>Scripts\Assert.ts</Link>
    </TypeScriptCompile>
    ...
</ItemGroup>

At the bottom of my project file is I've then included some post build actions to copy across the linked, and generated files:

<Target Name="CopyLinkedContentFiles" AfterTargets="Build">
    <Copy Condition="'%(TypeScriptCompile.Link)' != ''" SourceFiles="%(TypeScriptCompile.Identity)" DestinationFiles="%(TypeScriptCompile.Link)" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true"/>
    <Copy Condition="'%(TypeScriptCompile.Link)' != ''" SourceFiles="@(TypeScriptCompile -> '%(RootDir)%(Directory)%(Filename).js')" DestinationFolder="$([System.IO.Path]::GetDirectoryName(%(TypeScriptCompile.Link)))" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" />
    <Copy Condition="'%(TypeScriptCompile.Link)' != ''" SourceFiles="@(TypeScriptCompile -> '%(RootDir)%(Directory)%(Filename).js.map')" DestinationFolder="$([System.IO.Path]::GetDirectoryName(%(TypeScriptCompile.Link)))" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" />
</Target>

This then pulls down the typescript, and their counterpart javascript and map files to the linked location. This will only work for the default build behaviour though, without combining, and without code redirecting. Linking with recursion should be possible, not that I've tested it.

I don't know if would be possible to do, but it would be fantastic if referencing an assembly from within a project would trigger some msbuild magic to inspect the project file of the referenced assembly, instead of manually linking directly.

@r4nyc
Copy link

r4nyc commented May 14, 2015

If you're taking this idea all the way allow a symbol package with the .ts files and one giant js..map to map the minified combined js back to the ts files.+
That way you could distribute a package developed in typescript and allow developers to step into the source just like you can with .net assemblies.

@MrKWatkins
Copy link

@SilentPenguin I did initially use links but I had various problems with it. Sadly can't remember the details now, it was a while ago...

@Lenne231
Copy link

Lenne231 commented Jun 9, 2015

I don't think that a TypeScript project system using MSBuild makes sense because there are so many ways to build JavaScript projects (gulp, grunt, broccoli, ...). It would be nice to have a simple project system that supports the new Task Runner Explorer like the ASP.NET 5 project system does and shows all files in the folder except some folders (node_modules, bower_components, ...) that can be defined by the user.

@mhegazy
Copy link
Contributor

mhegazy commented Jun 9, 2015

@Lenne231 TypeScript has no project system. you can just use any project you like.. there is not really anthing as "TypeScript Project". if you want to use an ASP.net5 project and add typescript files, use grunt/gulp to build nothing would block you. the only missing piece that we are working on, is the support for tsconfig.json in VS. this should be available in the next public release of VS2015.

@Lenne231
Copy link

Lenne231 commented Jun 9, 2015

@mhegazy The problem is that i don't need ASP.NET 5 and don't want to write Universal Apps in JavaScript or something like that. I'm currently using gulp, but there is no plain JavaScript project type.

@jvilk
Copy link

jvilk commented Jun 9, 2015

I just want to be able to open a folder with my TypeScript library project in Visual Studio, and, ideally, have the ability to build it (using whicheverflavor-of-the-month JS build tool I prefer), run unit tests, and debug it. Right now, that's not possible without making an ASP or Universal App project.

I realize there's a number of practical concerns here, such as where to draw the line regarding intricate build setups and folder structures, which is complicated by the fact that there are multiple types of JS modules. But as of right now, there's no Visual Studio story for JS/TS-only library projects, although right now Visual Studio Code does all of these things for free, so maybe it's no longer a concern. 😄

@Lenne231
Copy link

Lenne231 commented Jun 9, 2015

Yes, Visual Studio Code looks promising, but i'm using F#/Suave. I don't need web tooling in the F# project, but it would be nice to have a plain JavaScript project beside the F# project for the client side code.

@kungfusheep
Copy link

I created a workflow a few weeks back that provides the concept of a typescript library project. Granted, my implementation runs on node/gulp, but there's no reason the idea couldn't be ported to another build system. 

The idea is essentially, you expose the code to the language service in one way and pass the code to the compiler in another.  The code is here if you're interested - https://github.com/kungfusheep/ts-internal-module-workflow 

I'm not proposing this as a solution, I've just found it to be a better approach to working with code over say 7-8 different projects/libraries.

On Tue, Jun 9, 2015 at 7:24 PM, Lennart notifications@github.com wrote:

Yes, Visual Studio Code looks promising, but i'm using F#/Suave. I don't need web tooling in the F# project, but it would be nice to have a plain JavaScript project beside the F# project.

Reply to this email directly or view it on GitHub:
#11 (comment)

@MichalPaszkiewicz
Copy link

Library projects would be awesome!!!

@AbubakerB
Copy link
Contributor

It would be awesome!

+1

@nkosi23
Copy link

nkosi23 commented Oct 23, 2015

+1 would be great to have that.

@pksorensen
Copy link

I created a project structure, using visual studio 2015 and aspnet empty website template - which means that it has some dnx and website stuff that is not needed. But I got a working library project for my needs.

https://github.com/s-innovations/S-Innovations.PortalFramework

I can distribute the library using bower, (currently i just bower install s-innovations/S-Innovations.PortalFramework --save when i need the stuff in the library and it pulls the latest head (later i could create tags and releases if needed).

Key points from creating a library template, which i currently use yeoman to create a new project with by running "yo si-portal" (generator project https://github.com/s-innovations/generator-si-portal-framework)

  1. A tsconfig.json that outputs builded javascript as amd modules to "artifacts/dev" aswell as declarations.
{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "declaration": true,
    "removeComments": false,
    "sourceMap": true,
    "module": "amd",
    "target": "es5",
    "rootDir": "src",
    "outDir": "artifacts/dev",
    "experimentalDecorators": true
  },
  "exclude": [
    "artifacts",
    "node_modules",
    "bower_components",
    "wwwroot",
    "dist"
  ]
}
  1. Combine all definitions to one .d.ts file with amd modules defined in the project and output to dist/typings.
dtsGenerator: {
            options: {
                name: 'si-portal-framework',
                baseDir: 'artifacts/dev',
                out: 'dist/typings/si-portal-framework.d.ts',
                main: 'si-portal-framework/index',
                externs: ["./koExtensions/knockoutExtensions.d.ts", "./utils/utils.d.ts"]

            },
            default: {
                src: ['artifacts/dev/**/*.d.ts']
            }
        }

3.sync/copy all the required files to dist/src that is needed from my other projects that will pull in this library.

sync: {           
            default: {
                files: [{
                    cwd: "src",
                    src: ["**/*.d.ts"],
                    dest: "dist/typings",
                },
                {
                    cwd: "src",
                    src: ["**/*.less", "**/*.html"],
                    dest: "dist/src",
                },
                {
                    cwd: "artifacts/dev",
                    src: ["**/*.js"],
                    dest: "dist/src",
                }
                ],
                pretend: false,
                verbose: true
            }
        },

Since I will from my other projects use requirejs as module loader and build tool to combine and minify javascript files this was sufficient. I also created a demo project that consumes my library.
https://github.com/s-innovations/SiPortalFrameworkDemos/tree/master/AzurePortal

Anyway - my library is not for production and I just used it to learn and get a overview of how I want to structure my typescript projects moving forward. And using yeoman and bower seems like a good starting point to me.

Feel free to create issues in any of the projects to discuss or provide feedback - maybe some of the information is usefull to others who start working with typescript projects.

@kellyelton
Copy link

Poke

@RichTeaTime
Copy link

+1 - Just want a VS "Typescript Shared Library" project type that has the same .ts -> .js compilation on save, and "Typescript Build" properties tab as the "HTML Application with Typescript" project type, but doesn't need to be an application. Otherwise, the .tsconfig approach sounds cleanest; all the gulp/npm stuff is just adding an unnecessary layer of extra tooling.

@zspitz
Copy link
Contributor

zspitz commented Jan 10, 2017

Is there still any value in this proposal, now that tsconfig supports extends?

@sdunst
Copy link

sdunst commented Jul 26, 2017

I still think that there is value in this proposal.
A class-library-like project type would simplify the workflow in web projects greatly.
Just like you would create a class-library project for shared C# code you could create a TS-class-library for shared TS controls or logic.

Of course it is possible to do something like that with grunt/gulp, but an integrated wy would be nice.

@drewnoakes
Copy link
Member

+1. My use case is having some library code written in TS that I want to include in the output of several other csproj projects. I'd like the build system to compile the .ts files and carry the .js and .js.map files into the dependant's output directories.

The code needn't leave my solution. Setting up a local npm repo for this seems like overkill, and would be inconvenient when changes are made.

If there's an alternative approach that solves this, I'd like to hear about it.

@ivan-lapitski
Copy link

+1.

A workaround today is to use separate folders for each and one of your "ts projects" and let each folder contain its own .tsconfig json with outFile specificed.
Then in the consuming projects use the tsconfig "include" keyword to include the .d.ts files in the correct order.

If you do this inside an asp.net web core project in the correct way you will even get debugging support on all "sub projects" if you emit sourceMaps.

@doivosevic
Copy link

Wow it's been 5 years since this was proposed. @RyanCavanaugh any chance there have been recent talks about supporting this scenario? What I'm looking for is I'd like to have a typescript project shared between multiple asp.net+angular apps as a project with the ability to of course step in if neccessary

@JosepBalague
Copy link

JosepBalague commented Oct 10, 2019

Still Not implemented in VS2019 16.3.3 / TS 3.6.3

It should be interesting to have ts and cs files in a netstandard or core library

@joj joj self-assigned this Apr 10, 2023
@RyanCavanaugh RyanCavanaugh added the Committed The team has roadmapped this issue label Apr 10, 2023
@joj
Copy link
Member

joj commented Apr 10, 2023

I'm closing this one in favor of #14533 to keep the conversation there.

@joj joj closed this as completed Apr 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Committed The team has roadmapped this issue Suggestion An idea for TypeScript Visual Studio Integration with Visual Studio
Projects
None yet
Development

No branches or pull requests