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

Shared javascript provider #57

Closed
kamalmarhubi opened this issue Nov 22, 2017 · 10 comments
Closed

Shared javascript provider #57

kamalmarhubi opened this issue Nov 22, 2017 · 10 comments
Assignees
Milestone

Comments

@kamalmarhubi
Copy link

(Not sure which repo this belongs in, please redirect if there's somewhere better.)

To handle more compile-to-js languages, we will need a shared provider that they can all use. This is alluded to in this repo in a comment.

@alexeagle
Copy link
Collaborator

/cc @shicks @blickly

@enriched
Copy link

Any news on this? Is something like NodeModuleInfo going to be made public? Or is the recommended way to interop by creating an aspect similar to the module_mapping_aspect?

@alexeagle
Copy link
Collaborator

We just had a good discussion at BazelCon. We need to look at the interactions between existing JS consumers and producers - rules_kotlin, rules_nodejs, pubref/rules_node, dropbox/rules_node, rules_typescript, rules_closure, some presumed CoffeeScript rules from @kamalmarhubi and the protobuf rules. We'll have a new Provider (NodeModuleInfo is only intended for npm packages that are interop-ed into a Bazel build).
Maybe we'll put it in a generic repo like bazelbuild/rules_javascript so it's not layered along with one of the existing repos.
We have an OKR on the Angular Tooling team this quarter to design this - expect a design doc draft posted to this issue.

@gregmagolan
Copy link
Collaborator

Success criteria:

  • third parties can write rules and they compose with ours
  • An example of TS to serving pipeline working (ts_library -> rollup_bundle -> terser_minified -> web_package (with differential loading) -> history-server)

@DavidANeil
Copy link
Contributor

I'm worried that "javascript" is too big a target for a single provider.
If a rule can only handle dependencies, for example, in ES2017 with named AMD modules, then I think that should be a encoded as a unique provider (JS_ES2017_NamedAMD or something similar), rather than the rule saying it needs "javascript" and then hoping that it is the correct type of javascript.

@gregmagolan
Copy link
Collaborator

We tossed around the idea of having a larger set of very specific providers but for a set of shared JS providers that becomes too fine grained for the general case. A large number of specific providers would make interop between rules more difficult as potentially every provider type would have to be checked for in consuming rules that can handle a wide variety of javascript modules formats & language levels.

We settled on a small set (JSModuleInfo, JSEcmaScriptModuleInfo, JSNamedModuleInfo) for the general cases described here https://docs.google.com/document/d/1ggkY5RqUkVL4aQLYm7esRW978LgX3GUCnQirrk5E1C0/edit#.

JSEcmaScriptModuleInfo is landing here #1201 and it allows ts_library outputs to be consumed by the new @bazel/rollup rollup_bundle which will replace the legacy rollup_bundle.

As a rule author you can add as many JS providers on top of the set of shared ones as you need for your own purposes and maybe some rules in the ecosystem will require very specific ones.

JSModuleInfo which hasn't landed yet and may still be change a bit will likely have the module_format field that can be used by consuming rules to look for specific module formats.

JSModuleInfo = provider(
    doc = """JavaScript files and sourcemaps.""",
    fields = {
        "module_format": "a string like [amd, cjs, esm, iife, umd] or \"mixed\" if the sources are of mixed formats",
        "sources": "depset of direct and transitive JavaScript files and sourcemaps",
    },
)

@DavidANeil
Copy link
Contributor

Makes one wish providers had some sort of inheritance/polymorphism aspect....

I suppose we'll just end up writing an aspect that produces the JS (for example JS_ES2017_NamedAMD), and give that aspect the ability to view the JSModuleInfo and JS_ES2017_NamedAMD on the target and if it can find the JS to just pass it through in the expected JS_ES2017_NamedAMD provider.

I'm just uncertain what the behavior will be if a rule wants to return two providers of JsModuleInfo with different values for module_format.

@alexeagle
Copy link
Collaborator

Lots of providers also can mean lots of actions run if a consumer requests all of them. A combinatorial explosion of them will slow down builds.

@gregmagolan
Copy link
Collaborator

gregmagolan commented Oct 10, 2019

A few update on this:
JSEcmaScriptModuleInfo landed in: #1201
JSNamedModuleInfo landed in: #1215
These are both in providers.bzl: https://github.com/bazelbuild/rules_nodejs/blob/master/providers.bzl

A typescript specific provider DeclarationInfo was also added: https://github.com/bazelbuild/rules_nodejs/blob/master/declaration_provider.bzl

The last provider that we had planned is JSModuleInfo which is still pending here: #1040

@alexeagle
Copy link
Collaborator

We think we can cover all the use cases with the existing providers. The new one in #1040 is useful in theory as a way to get only direct and not transitive .js outputs from some rule, without relying on ESModule output. But we only needed that in one place and there was an easy workaround.
Might revisit #1040 after 1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants