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

npm packages Docker integration #116

Closed
bazaglia opened this issue May 22, 2022 · 7 comments · Fixed by #249
Closed

npm packages Docker integration #116

bazaglia opened this issue May 22, 2022 · 7 comments · Fixed by #249
Assignees

Comments

@bazaglia
Copy link
Contributor

bazaglia commented May 22, 2022

I'm wondering what are the current limitations to build a Docker image out of targets created using rules_js. I'm able to create a tar from the ts_project rule or swc from rules_swc, but I'm struggling with bundling the npm packages.

I've tried to use the container_layer rule to create a npm_deps layer that is copied to the /node_modules of my image:

container_layer(
    name = "npm_deps",
    data_path = "node_modules",
    files = [
        "@npm//axios",
        "@npm//@types/node",
    ],
)

The problem is, indirect dependencies end up exclusively inside .aspect_rules_js (follow-redirects is an indirect dependency of axios):

/node_modules # tree -L 2 -a
.
├── .aspect_rules_js
│   ├── @[email protected]
│   ├── [email protected]
│   └── [email protected]
├── @types
│   └── node
└── axios
    ├── CHANGELOG.md
    ├── LICENSE
    ├── README.md
    ├── SECURITY.md
    ├── UPGRADE_GUIDE.md
    ├── dist
    ├── index.d.ts
    ├── index.js
    ├── lib
    ├── package.json
    ├── tsconfig.json
    └── tslint.json

In the following example, lodash.camelcase is an indirect dependency of an external npm package. When running my Docker container, it fails with:

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module 'lodash.camelcase'

That makes sense since one of the npm packages tried to import it but it isn't linked (but is available inside .aspect_rules_js). Is there a way to get the indirect dependencies also linked to the node_modules?

As a side note, symlinks seem to become the whole directory copied, so there are three axios and two follow-redirects (I'm limiting the tree to 2 subdirectories, but inside the node_modules of packages in .aspect_rules_js the duplication happens).

@alexeagle
Copy link
Member

We haven't tried this at all so far. Maybe @thesayyn has some ideas since he has worked on both sides of this.

@thesayyn
Copy link
Member

Hmm, I suspect a few things that could go wrong here;

1- container_layer mishandles TreeArtifact symlinks. (this is more likely given the side note)
2- you are trying to import something you haven't declared a dependency on.
3- lodash.camelcase seems to be missing from the virtual store altogether hence could be improper handling of transitive depsets.

I'd like to take a look if you could provide a repro.

@bazaglia
Copy link
Contributor Author

Hey @thesayyn! Here's the repro. My understanding is that the symlinks mishandling starts in the pkg_tar already. More info in the README: https://github.com/bazaglia/rules_js_repro

@thesayyn
Copy link
Member

Thanks! I'll take a look

@bazaglia
Copy link
Contributor Author

I made a comment on an existing pkg_tar issue about this limitation: bazelbuild/rules_pkg#115 (comment)

@alexeagle
Copy link
Member

Yeah I think that's the principled answer, do we know how hard that is to contribute?

@thesayyn
Copy link
Member

#249 fixes this issue. if you want to have more fine-grained layers eg node_modules into their own layer, one has to modify the expand_runfiles function to yield more than one tar.

@thesayyn thesayyn added this to the 1.0 milestone Jun 27, 2022
@alexeagle alexeagle modified the milestones: 1.0, 1.1 Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants