Rules_nodejs: Language service support

Created on 28 Mar 2018  路  7Comments  路  Source: bazelbuild/rules_nodejs

I'm not sure if this is supposed to work but I get errors related to modules not being found for modules mapped to the workspace, ie: what is referenced in the readme here: https://github.com/bazelbuild/rules_typescript/blob/df4a1a561d88e187438ac7791a5ac33995f2d317/README.md#writing-typescript-code-for-bazel

When building the ts_library target, everything works great so it's not an issue with the code itself when compiling with the wrapped tcs compiler. I'm assuming my editor is using the language services from the "vanilla tsserver" to provide the code completion and type checking. Before I dig deeper into the wrapped tcs compiler and how that mapping works I figured I'd ask if I'm just missing some configuration, or if this is just not implemented? @alexeagle

Thanks for all the great work on these rules so far!

Can Close? typescript questiodocs

Most helpful comment

Actually, this is a bit more of a problem than just the resolved modules. Internally we generate TypeScript code and currently consume it directly as a Bazel dependency. We also publish it as a private NPM package so we can consume it in our non-bazel build projects. Consuming it as a NPM package gives a better developer experience as the type-declarations and included along with the transpiled code. When consuming it directly as a Bazel dependency, tsserver is not aware of Bazel and we don't get type-completion in the editor, despite the wrapped stand-alone compiler working. This is a blocker for us moving more of our code into our single mono-repo which is superior to sharing via NPM as we then immediately detect breaking changes against the consumers of the code.

I looked into writing a language-service plugin but I couldn't figure out how to re-use the existing implementation but provide a separate compiler host (which is already implemented for the wrapped tsc compiler). @alexeagle I looked at the Angular language-service for inspiration, but I couldn't see any code to integrate with Bazel. Are there any plans on doing this?

I'm guessing the steps required to provide code-completion for a generated source file from Bazel would look something like:
1) Language-service plugin receives request for code completion for module "foo".
2) Use Bazel to figure out what target provides the module
3) Have Bazel build the target
4) Return the file/location of the file back to the language-service plugin and use the existing implementation to return the code-completion results.
Not sure how errors etc... would be handled.

Another option, would be to have Bazel generate the compiler.paths and use the default implementation of tsserver. The targets would have to be rebuilt everytime something changes and this seems like a more hack-ish way to solve this, but might work in the short-term.

All 7 comments

The editor relies on what's in your tsconfig.json file, so you'll need to add TypeScript pathMapping entries https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping

Thanks, that works.

I'll make a PR with a documentation suggestion since I was naively expecting this to work out of the box especially given the warning from the compiler when you have paths set:

WARNING: your tsconfig.json file specifies options which are overridden by Bazel:
 - compilerOptions.paths is determined by the module_name attribute in transitive deps[]

It would be really nice to have the modules resolved the same way but I assume this isn't so simple. If I have time I'll look into if writing an language service plugin (https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin) which I assume would be the standard way to solve this.

Thanks for your help.

Actually, this is a bit more of a problem than just the resolved modules. Internally we generate TypeScript code and currently consume it directly as a Bazel dependency. We also publish it as a private NPM package so we can consume it in our non-bazel build projects. Consuming it as a NPM package gives a better developer experience as the type-declarations and included along with the transpiled code. When consuming it directly as a Bazel dependency, tsserver is not aware of Bazel and we don't get type-completion in the editor, despite the wrapped stand-alone compiler working. This is a blocker for us moving more of our code into our single mono-repo which is superior to sharing via NPM as we then immediately detect breaking changes against the consumers of the code.

I looked into writing a language-service plugin but I couldn't figure out how to re-use the existing implementation but provide a separate compiler host (which is already implemented for the wrapped tsc compiler). @alexeagle I looked at the Angular language-service for inspiration, but I couldn't see any code to integrate with Bazel. Are there any plans on doing this?

I'm guessing the steps required to provide code-completion for a generated source file from Bazel would look something like:
1) Language-service plugin receives request for code completion for module "foo".
2) Use Bazel to figure out what target provides the module
3) Have Bazel build the target
4) Return the file/location of the file back to the language-service plugin and use the existing implementation to return the code-completion results.
Not sure how errors etc... would be handled.

Another option, would be to have Bazel generate the compiler.paths and use the default implementation of tsserver. The targets would have to be rebuilt everytime something changes and this seems like a more hack-ish way to solve this, but might work in the short-term.

Additionally, in order to help migrate between legacy NPM managed dependencies and Bazel managed dependencies, it would be nice to be able to write have each "package" maintain it's own list of NPM dependencies at a more fine-grained than a single package.json file at the root but still have the language-service support it and not have to run yarn install in every directory. Ie: let Bazel pull in the NPM dependencies and reference them as a dependency, but still get code-completion etc... This would allow us to dynamically generate the dependencies of the package.json we need to generate to allow us to consume the "packages" in non-Bazel built code.

@kyliau has worked on this internally at Google, maybe he can give some guidance on how we have set this up.

This issue has been automatically marked as stale because it has not had any activity for 90 days. It will be closed if no further activity occurs in two weeks. Collaborators can add a "cleanup" or "need: discussion" label to keep it open indefinitely. Thanks for your contributions to rules_nodejs!

This issue was automatically closed because it went two weeks without a reply since it was labeled "Can Close?"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jmhodges picture jmhodges  路  7Comments

Toxicable picture Toxicable  路  6Comments

Globegitter picture Globegitter  路  5Comments

alexeagle picture alexeagle  路  4Comments

pauldraper picture pauldraper  路  6Comments