2

I'm working on a project inside a VM (really docker on windows via vscode remote-containers). I would like to avoid building my react app at $(pwd)/node_modules, because everything under $(pwd) is synced to my windows file system which causes serious performance issues.

I'm fairly new to nodejs in general, but I'm surprised how difficult this seems to figure out.

I successfully started with this:

  • yarn --modules-folder /tmp/vendor

This gave me a /tmp/vendor folder with expected dependencies listed.

For the next step, I want to run the development server, so I run this:

  • yarn --modules-folder /tmp/vendor start

I get /bin/sh: react-scripts: command not found. I figure yarns --modules-folder doesn't reconfigure PATH information when running commands (yarn start calls react-scripts start). So I just added my own PATH as a workaround:

  • PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start

But now I get this:

[root@352b76226b83 owio]# PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start
yarn run v1.22.5
$ react-scripts start
internal/modules/cjs/loader.js:965
  throw err;
  ^

Error: Cannot find module 'react-dev-utils/crossSpawn'
Require stack:
- /tmp/vendor/react-scripts/bin/react-scripts.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:962:15)
    at Function.Module._load (internal/modules/cjs/loader.js:838:27)
    at Module.require (internal/modules/cjs/loader.js:1022:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/tmp/vendor/react-scripts/bin/react-scripts.js:18:15)
    at Module._compile (internal/modules/cjs/loader.js:1118:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:10)
    at Module.load (internal/modules/cjs/loader.js:982:32)
    at Function.Module._load (internal/modules/cjs/loader.js:875:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/tmp/vendor/react-scripts/bin/react-scripts.js' ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command

Since it is complaining about missing modules, I also set the NODE_PATH (I guess yarn doesn't forward this variable either):

  • NODE_PATH=/tmp/vendor PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start

With this, I get:

./src/index.jsx
Line 0:  Parsing error: Cannot find module 'eslint-scope' from '/tmp/vendor/eslint/lib/api.js'

I'm stuck here, because eslint-scope does exist, and I've already what I can to work around path problems.

I'm half tempted to start trying other tools outside of CRA and yarn but I don't really know the ecosystem well enough yet to understand how to port my application over. Any advice would be greatly appreciated.

EDIT:

I've gotten closer by changing vendor to node_modules. I guess this convention is somehow necessary. I also added NODE_PATH=/tmp/node_modules to a .env file, and the --modules-folder /tmp/node_modules to a .yarnrc file.

EDIT 2:

I made a symlink for $(pwd)/node_modules -> /tmp/node_modules as suggested and this seems to have worked this time around, given that I added the NODE_PATH to .env.

It seems all the react-script stuff is working now, but when compiling the local source files under src/components/, I get errors about not resolving modules from /tmp/node_modules that do indeed exist.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
spanishgum
  • 1,030
  • 1
  • 14
  • 29
  • 1
    What about a link to custom folder? Does it cause problems too? – Estus Flask Nov 03 '20 at 00:47
  • Just added an `EDIT 2`. I tried this earlier and had issues, but I'm seeing a new error this time around with the sym link. – spanishgum Nov 03 '20 at 00:56
  • Oh hold on, I made the wrong link from my earlier naming convention. – spanishgum Nov 03 '20 at 00:58
  • Seems to have taken this time around, thanks. I think I tried this earlier without having `NODE_PATH` set in `.env` and it had issues. Maybe I'll narrow down exactly what I need and don't need and post follow up answer. – spanishgum Nov 03 '20 at 01:03

1 Answers1

2

After some tinkering and support from Estus, I found that having the following things works for me:

  • .env file with NODE_PATH=/tmp/node_modules
  • .yarnrc file with --modules-folder /tmp/node_modules
  • symlink for $(pwd)/node_modules -> /tmp/node_modules

I'm not sure why the symlink is necessary, and would love to know if anyone has a .env like solution. It seems my local source files are compiled against this folder regardless of having NODE_PATH set.

Other oddities I don't understand, but maybe someone will:

  • I could not just have NODE_PATH as a variable in my yarn command. It seems having the value in .env changed how modules within node_modules were compiled.

  • I could not use a name other than node_modules. No idea why.

As an aside:

For anyone landing here having the same issue (slow docker performance on windows or mac), you may need to make sure you're editor is not indexing node_modules. For example, I have set files.watcherExclude in my .vscode/settings.json to include "**/node_modules": true,".

spanishgum
  • 1,030
  • 1
  • 14
  • 29