lucidsoftware / rules_play_routes

Bazel rules for compiling Play Framework routes files
Apache License 2.0
11 stars 13 forks source link

Static routes not accessible #44

Closed gergelyfabian closed 2 years ago

gergelyfabian commented 3 years ago

I have a project that I've set up with rules_play_routes (using Play 2.8). Everything works nicely (including dynamic routes), but static files from /public do not seem to be accessible, even though I made them accessible:

# In conf/routes:
# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

# In public/BUILD:
filegroup(
    name = "public",
    srcs = glob(["**/*"]),
    visibility = ["//visibility:public"],
)

# in conf/BUILD:
play_routes(
    name = "play-routes",
    srcs = ["routes"],
    generate_reverse_router = True,
    include_play_imports = True,
    routes_imports = [],
    visibility = ["//visibility:public"],
)

# Settings for my service:
scala_binary(
    name = "service",
    srcs = glob([
        "controllers/**/*.scala",
    ]) + ["//conf:play-routes"] + [":twirl-templates"],
    classpath_resources = [
        "//conf:application.conf",
        "//conf:prod-logback.xml",
    ],
    data = ["//public"],
    jvm_flags = [
      ...
    ],
    main_class = "play.core.server.ProdServerStart",
    resources = [
        "//conf:prod-logback.xml",
    ],
    visibility = ["//visibility:public"],
    deps = DEPS + [
        "@maven//:com_typesafe_play_play_server_%s" % SCALA_VERSION,
        "@maven//:com_typesafe_play_play_guice_%s" % SCALA_VERSION,
        "@maven//:com_typesafe_play_play_akka_http_server_%s" % SCALA_VERSION,
        ...
    ],
)

I can see the static files in bazel-bin/app/service.runfiles/my-app/public/. In addition I'm wondering what about static files that Play framework is adding magically (like jquery min js).

gergelyfabian commented 3 years ago

Any hints what I could be doing wrong?

SrodriguezO commented 3 years ago

Hey @gergelyfabian, what errors are you seeing? Do you have a sample repo I could pull to repro your error? I guess I could try recreating it with what you've shared here, but if you have a repo on hand that'd be easier.

In addition I'm wondering what about static files that Play framework is adding magically (like jquery min js).

Apologies, I'm not sure I understand what you're asking here. _ Sidenote: Static Asset support hasn't been explicitly added to this rule set, but it may (should?) work. If you can get me a small repro case I may be able to help you troubleshoot.

gergelyfabian commented 3 years ago

The magical static files appearing are because of the following dependency in my project, I just realized (works with sbt):

"org.webjars"             %   "bootstrap"                   % "3.4.1"

Then the question is, how to get these files also to appear with Bazel, along with the custom ones included as static assets (in a public folder).

I'll try to provide a repro.

gergelyfabian commented 3 years ago

Here is the reproduction: https://github.com/gergelyfabian/bazel-play-example

Sbt:

sbt run

Bazel:

bazel run //app:service

The difference is that with sbt these things work:

These are missing with Bazel.

At least the two first issues may be caused by static routes not working correctly. I tried providing the public files as data to the service, but it did not help. I also tried debugging, and I could have access to the public files in the controllers (as they are in runfiles). I guess the best would be to debug the generated routers, where they are searching for the static files (and where they are in reality), but I did not manage to do that.

gergelyfabian commented 3 years ago

I fixed both issues.

For the general /public access I needed to move //public to become service's resources:

    resources = [
        "//public",
    ],

As in https://github.com/gergelyfabian/bazel-play-example/blob/ab0df99ffcf85c03b669c6906e0483497e8aabc3/app/BUILD#L37-L39

Then, for webjars, it's a bit tricky, as Play documentation says:

WebJars are automatically extracted into a lib folder relative to your public assets for convenience. For example, if you declared a dependency on RequireJs then you can reference it from a view using a line like: <script` data-main="@routes.Assets.at("javascripts/main.js")" type="text/javascript" src="@routes.Assets.at("lib/requirejs/require.js")"></script> Note the lib/requirejs/require.js path. The lib folder denotes the extracted WebJar assets, the requirejs folder corresponds to the WebJar artifactId, and the require.js refers to the required asset at the root of the WebJar.

Quote from: https://www.playframework.com/documentation/2.8.1/AssetsOverview#WebJars

Bazel does not do this magic automatically for Play, so once we have the webjars dependency, we need to unpack it manually. This can be done with a genrule. I've demonstrated that in my example project:

https://github.com/gergelyfabian/bazel-play-example/blob/ab0df99ffcf85c03b669c6906e0483497e8aabc3/public/BUILD#L7-L37

Finally, the unpacked files need to become a resource dependency of the service:

https://github.com/gergelyfabian/bazel-play-example/blob/ab0df99ffcf85c03b669c6906e0483497e8aabc3/app/BUILD#L37-L39

gergelyfabian commented 3 years ago

Maybe such a genrule for webjars could become a functionality of this plugin? (with proper parameters I guess) A new rule maybe?

gergelyfabian commented 3 years ago

I changed my solution for a macro for webjars. Maybe this could be something to be moved into rules_play_routes?

Macro definition: https://github.com/gergelyfabian/bazel-play-example/blob/012379905a571e243019f01b5ab1f120ec594d81/tools/webjars.bzl

How it's used: https://github.com/gergelyfabian/bazel-play-example/blob/012379905a571e243019f01b5ab1f120ec594d81/public/BUILD

gergelyfabian commented 3 years ago

Reopening to discuss what to do with the support for webjars in rules_play_routes, as it's officially supported by Play Framework Assets (by automatically unpacking the jars by Play):

https://www.playframework.com/documentation/2.8.1/AssetsOverview#WebJars

gergelyfabian commented 3 years ago

After considering what is the purpose of rules_play_routes I came to a conclusion that the functionality for webjars is most probably not well fitting into rules_play_routes. I moved this unzipping functionality for Webjars into a new project:

https://github.com/gergelyfabian/rules_play_utils

You can simply use this along with rules_play_routes, the two should nicely play together.

I use this from my bazel-play-example project.

gergelyfabian commented 3 years ago

I'd propose https://github.com/lucidsoftware/rules_play_routes/pull/45 to improve documentation, and if it's merged, I'd close this issue, if you agree, @SrodriguezO.

SrodriguezO commented 2 years ago

LGTM; approved/merged that. Thanks!