8000 Suggestion: CompilerHost should be able to "plug into" a LanguageServiceHost · Issue #9017 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Suggestion: CompilerHost should be able to "plug into" a LanguageServiceHost  #9017
Closed
@TheLarkInn

Description

@TheLarkInn

Background

The traditional method of transpiling a typescript application is through ts.CompilerHost. This is awesome, and there are slowly becoming more and more CompilerHost based "flavors" of tsc that developers are wanting to use. I spoke about this with @alexeagle and @mhegazy briefly on this as well:

Webpack Loaders

A webpack loader in its most simple form does the following:

function takeASingleFileThatIsServedToThisFunctionViaWebpack(rawFileStringContent) {
  let newlyUpdatedRawFileString = rawFileStringContent + 'console.log(WOW THIS MAKES SENSE);'


  return newlyUpdatedRawFileString;
}

As you can see all a loader does is take a raw source, and return it. On top of this webpack handles file resolution through some crafty regex:

loaders: [
  {
    test: /\.ts/,  // this regex string tells webpack which files to 'send' to the loader
    loader: ‘ts-loader’ // this specifies the loader to use (resolves to node modules)
  }
]

Webpack Typescript Loaders Cannot & Should Not Use ts.CompilerHost

So knowing what we know about how a file is tranformed and resolved through webpack, ts.CompilerHost is not an option for a ts-webpack loader. Why? Loaders are a powerful tool in webpack because they can be chained together with other loaders. For example: This Angular2 TS Loader I wrote. CompilerHost (as you know probably) runs a build/transpiliation against a whole project, and not one file per time. Therefore if you tried to plop a CompilerHost in a webpack loader, it would lose the context between each file.

Webpack TS Loaders & ts.LanguageServiceHost.

Because of this, the current typescript webpack loaders that are being used (ts-loader, awesome-typescript-loader) are both using ts.LanguageServiceHost. Why? Because LSG's support transpilation at a long-term lifetime one-file-at-a-time transpilation, persisting the transpile context back to the ts.Program. (This is tranditionally useful for IDE'S yes, but its a match made in heaven for a webpack loader). I would call this an 'edge-case' request, however, with 5+ million downloads a month, webpack is increasingly more popular than any bundler at the moment.

The Problem:

Trying to use ts.CompilerHost implementations in a ts.LanguageServiceHost is a huge pain, and doesn't port well into an existing LSH. Its true that they share some functions, however there lacks a way to use a CompilerHost in a LanguageService incrementally.

The Solution.

Create some way to attach the functionality of a custom CompilerHost implementation, and then perform it on a per-file basis, updating the LanguageServiceHost to help persist the transpilation/program contex. This will allow not only @s-panferov and @TypeStrong able to create plugin's systems that allow for super powerful TS builds in webpack. Or instead a plugin system where you add/override certain functionalities to an existing LSH.

Please refer to this conversation thread of me explaining the issue to @DanielRosenwasser with lots of examples:

Start: https://gitter.im/Microsoft/TypeScript?at=5757ab04662b042b7e596b70
End: https://gitter.im/Microsoft/TypeScript?at=5757b77445cf128e5f1d7429

References

#6508 (comment)
angular/angular#8759
TypeStrong/ts-loader#223
https://github.com/TypeStrong/ts-loader/issues/
s-panferov/awesome-typescript-loader#153
TypeStrong/ts-loader#224

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIRelates to the public API for TypeScriptFixedA PR has been merged for this issueIn DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0