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

Issue requiring modules from a non-parent directory. #422

Open
mancusi opened this issue Aug 30, 2022 · 2 comments
Open

Issue requiring modules from a non-parent directory. #422

mancusi opened this issue Aug 30, 2022 · 2 comments
Labels
question This issue is a question. Close the loop with documentation?

Comments

@mancusi
Copy link

mancusi commented Aug 30, 2022

I have a repository which has some interesting quirks including the fact that our main node_modules folder is not in the typical Node module resolution path. Our node_modules is in a directory ./js and our source code is in ./src and a few other directories.

Normally, one could pass a NODE_PATH envvar (see here) which is a list of absolute paths that node_modules could be found at outside of the typical "parent directory" resolution algorithm to run anything in src with node.

I've created a simple example repo which replicates the structure of our repository here. Running bazel build //src:run fails with

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

Error: Cannot find module 'acorn'
Require stack:
- /private/var/tmp/_bazel_jmancusi/9291d80434b6d660950274f29d1a5907/sandbox/darwin-sandbox/24/execroot/node_modules_not_in_parent_directory/bazel-out/darwin-opt-exec-2B5CBBC6/bin/src/bin.sh.runfiles/node_modules_not_in_parent_directory/src/require_acorn.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/private/var/tmp/_bazel_jmancusi/9291d80434b6d660950274f29d1a5907/sandbox/darwin-sandbox/24/execroot/node_modules_not_in_parent_directory/bazel-out/darwin-opt-exec-2B5CBBC6/bin/src/bin.sh.runfiles/node_modules_not_in_parent_directory/src/require_acorn.js:4:16)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/private/var/tmp/_bazel_jmancusi/9291d80434b6d660950274f29d1a5907/sandbox/darwin-sandbox/24/execroot/node_modules_not_in_parent_directory/bazel-out/darwin-opt-exec-2B5CBBC6/bin/src/bin.sh.runfiles/node_modules_not_in_parent_directory/src/require_acorn.js'
  ]
}

As you can see I've been unable to successfully get this working with rules_js. Is there a suggested way of handling repositories of this structure or will I need to move the repository such that the node_modules are linked in a parent directory?

@cgrindel cgrindel added question This issue is a question. Close the loop with documentation? discussion needed Discussion required to progress further and removed discussion needed Discussion required to progress further labels Sep 27, 2022
@jbedard
Copy link
Member

jbedard commented Oct 6, 2022

I think this is difficult because NODE_PATH must be absolute and until runtime we really have no idea where that will be (in the sandbox etc).

You can set it programmatically at runtime using things such as process.env.RUNFILES but it requires a bit of a hack: https://stackoverflow.com/a/33976627

I think ideally you wouldn't depend on this. I assume it is primarily just to hide the node_modules directory? If it's all hidden within bazel is that still necessary?

@gregmagolan
Copy link
Member

gregmagolan commented Oct 12, 2022

Yeah. There is no easy way to use NODE_PATH since the directory the build takes place in is a dynamic sandbox under Bazel as @jbedard said. You could in theory hard-code it based on the execroot path and build outside of the sandbox but that is not very portable between machines and probably more trouble than its worth.

In theory you could patch npm_translate_lock to take the pnpm-lock.yaml file from the js folder but still link to the root of the repository under Bazel. That would probably be the easiest way to make your configuration work under rules_js.

It should be just one line of code to change that you can carry as a patch.

root_package = rctx.attr.pnpm_lock.package

        # root package is the directory of the pnpm_lock file
        root_package = rctx.attr.pnpm_lock.package

to

        # root package is hard-coded to the root package
        root_package = ""

@gregmagolan gregmagolan moved this to 📋 Backlog in Open Source Feb 4, 2023
@gregmagolan gregmagolan moved this from 📋 Backlog to 🔖 Ready in Open Source Feb 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question This issue is a question. Close the loop with documentation?
Projects
Status: On Deck
Development

No branches or pull requests

4 participants