dgp1130 / rules_prerender

A Bazel rule set for prerending HTML pages.
14 stars 0 forks source link

Bazel `compatible_with` and `restricted_to` #73

Open dgp1130 opened 1 year ago

dgp1130 commented 1 year ago

Since rules_prerender heavily relies on explicitly defining JavaScript running in specific environments (client, server, build, ...), we should look into enforcing those constraints in the depgraph. It would be awesome if it was possible to define certain targets as "client-only" and adding a dependency in any other location would be an error. Something like:

// dom.ts

const div = new HTMLDivElement();
div.textContent = 'Hello, World!';
document.appendChild(div);
# BUILD

ts_project(
    name = "dom",
    srcs = ["dom.ts"],
    # Requires DOM, must be run in the browser.
    restricted_to = ["@rules_prerender//platforms:browser"],
)

prerender_component(
    name = "component",
    prerender = ":dom", # ERROR: Must support `@rules_prerender//platforms:build`.
)

Unfortunately there are places where this gets cheated, such any environment with DOM emulation. It technically runs in Node, but actually has a DOM, which might be sufficient for some (but not all) browser code.

An important question here is how useful it actually is to enforce these constraints at the depgraph level. How common of a mistake is it to use a library in the wrong environment and how much does managing this get in the way. Ideally it would be great to find a path which optionally allowed these constraints but didn't force them for users who don't want to deal with it.

I don't know much about how restricted_to and compatible_with actually work and I'm struggled to find good docs right now. But something to consider as a way of making it potentially easier and more reliable to write portable JavaScript.