Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Not able to add generated js files to docker image #263

Closed
abqadeer opened this issue Aug 31, 2018 · 10 comments
Closed

Not able to add generated js files to docker image #263

abqadeer opened this issue Aug 31, 2018 · 10 comments

Comments

@abqadeer
Copy link

I am using docker_build rule from rules_docker https://github.com/bazelbuild/rules_docker#container_image-1 to build a docker image. My code is pretty basic an index.ts file with console.log() and call to a function in another file which also logs a message.
When i build the my code using ts_library the output i get on terminal is the location of d.ts files only, and not the js files. The docker_build rule has argument files which accepts an array and i am giving it the output from ts_library which only prints the location of d.ts files. My image builds successfully but only the d.ts files are added to it.
I have tried to use the glob() function but it can only be used for the source files not the generated file.
Is this possible to output the location of js files in addition to d.ts files?
Is there some other way to add files to docker?
I have tried other rules but none works for my specific case. Also i think if rules_typescript output the location of js files the problem will be solved.
Here is how my BUILD file looks

package(default_visibility=["//visibility:public"])
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_devserver")
load("@io_bazel_rules_docker//docker:docker.bzl", "docker_build")

ts_library(
    name = "sample_project",
    srcs = glob(["index.ts"]),
    deps = [":depOne"]
)


ts_library(
    name = "depOne",
    srcs = glob(["depOne.ts"])
)

docker_build(
    name = "my_image_bazel",
    base = "@alpine//image:image.tar",
    files =  [":sample_project"] ,
    cmd = ["index.js"],
    workdir = "/app_bazel",
    directory = "/my_code_bazel",
)
@enriched
Copy link

enriched commented Sep 4, 2018

@abqadeer I wasn't able to get these rules working very well for creating dockerized node servers, and it seems like most of the development here is focused on frontend development. I am currently using the bazel-javascript rules developed by zenclabs. The main contributor for those was kind enough to write up a dockerized example.

I have successfully built some of our production containers on a mac and am working right now on some fixes to make it work for windows.

If you do want to stick with the official Bazel rules then you will probably want to check out the es6_output example. As far as I know you need to create a rule that will gather all the es6 sources and list them as outputs. Or you need to use something like the rollup_bundle rule to output a single js file that you can include in your docker image. But I think that if you go with that route you will not be able to use any native nodejs modules.

@nimerritt
Copy link
Contributor

@abqadeer We use https://github.com/bazelbuild/rules_docker#nodejs_image and it works with TypeScript. Is there a reason you don't want to use the rule specifically designed for Nodejs code?

@abqadeer
Copy link
Author

abqadeer commented Sep 6, 2018

@nimerritt nodejs_image is the rule that i ended up using, i did try it in the start but it didn't work(the issue was that i was building the code in on mac, nodejs_image uses nodejs_binary which installs the node binary for mac as i am running nodejs_binary rule on mac and hence the problem) plus i wanted to use my own base_image which nodejs_image does not give the option of. That's how my rule looked for the basic setup

nodejs_image(
    name = "node_img",
    entry_point = "my_workspace/src/index.js",
    node_modules = "@npm_deps//:node_modules",
    data = ["//src:sample_project"],
)

@enriched
Copy link

enriched commented Sep 6, 2018

@abqadeer I was running into the same issue. Would love to hear about any solutions that you come up with.

@abqadeer
Copy link
Author

abqadeer commented Sep 6, 2018

@enriched a build server is most likely to have linux on it, so you would not have this issue on a actual build server, i tested building my code on a VM running linux and it worked. But the problem is still there if i build and run on mac.

@alexeagle
Copy link
Contributor

so at this point you do have the .js files in the docker image, but end up with nodejs executable for the host platform (where you did the build) rather than the target platform?

@abqadeer
Copy link
Author

Yes, so
bazel build on mac => docker run on mac does not work.
bazel build on ubuntu => docker run on ubuntu works.
bazel build on ubuntu => docker run on mac works.

@olegsmetanin
Copy link

Mac OS X, bazel //workspaces:ls outputs only one file - index.d.ts. Where is compiled index.js?

ts_library(
    name = "lib",
    srcs = ["index.ts"],
    tsconfig = "//:tsconfig.json",
)

genrule(
    name = "ls",
    srcs = [
        ":lib",
    ],
    outs = ['qwe'],
    cmd = "ls `dirname $(location lib)`; echo qwe > $(location qwe)",
)

olegsmetanin pushed a commit to olegsmetanin/gobazel that referenced this issue Oct 26, 2018
@alexeagle
Copy link
Contributor

I think the remaining issue here is resolved by bazel-contrib/rules_nodejs#827 which would make bazel build on any platform able to create a docker image with the linux nodejs binary included.

@olegsmetanin I think you have a separate question? the default output of ts_library is just .d.ts to make you select which JS mode you want (devmode/prodmode) so currently you need another rule downstream of the ts_library to select these.

@thesayyn
Copy link

thesayyn commented Jul 6, 2019

@olegsmetanin @abqadeer
The workaround is creating another rule which basically picks up the es5_sources from ts_library targets.

load("@npm_bazel_typescript//internal:common/compilation.bzl", "DEPS_ASPECTS")
load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect")

def _tslibrary_downstream(ctx):
    sources = depset()
    for d in ctx.attr.libraries:
        if hasattr(d, "typescript"):
            sources = depset(transitive = [sources, d.typescript.es5_sources])

    return DefaultInfo(files = sources)

ts_library_d = rule(
    implementation = _tslibrary_downstream,
    attrs = {
        "libraries": attr.label_list(
            aspects = [sources_aspect],
            doc = "Compile-time dependencies, typically other ts_library targets",
        )
    },
)

usage:

ts_library(
    name = "init_sources",
    srcs = ["init.ts"],
)

ts_library_d(
    name = "init_sources_d",
    libraries = [
        ":init_sources"
    ]
)
container_image(
    name = "mycontainerimage",
    files = [":init_sources_d"]
)

Keep in mind this rule does not pick up npm deps.

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

No branches or pull requests

6 participants