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

Unable to resolve dependencies in NODE-PATH using DOCKER #4442

Closed
camiloperezv opened this issue May 11, 2018 · 3 comments
Closed

Unable to resolve dependencies in NODE-PATH using DOCKER #4442

camiloperezv opened this issue May 11, 2018 · 3 comments

Comments

@camiloperezv
Copy link

camiloperezv commented May 11, 2018

Is this a bug report?

YES

Description

Hi, I'm using docker to develop my solution.

In Docker I install the node-modules insite /opt folder and add this node_modules folder to NODE_PATH and PATH, if I go into the Docker container and run node then execute something like

> const react = require('react');

The output will be a success, this will happen in every location of the docker container, not just the /opt

To reproduce this issue I will show you step by step how I making my project.

My DockerFile is:

FROM node:8.11
# Install dependencies to run react app
RUN yarn global add [email protected] serve && mkdir /tmp/client

# define envirnment variables
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV

# expose port to run it
ARG PORT=4000
ENV PORT $PORT
EXPOSE $PORT

# Install node modules and add them to the PATH and Node Path
WORKDIR /opt
COPY package.json yarn.lock ./
RUN yarn install --silent --production=true
ENV PATH /opt/node_modules/.bin:$PATH
ENV NODE_PATH /opt/node_modules/:$NODE_PATH

# Define variable to check if build is required
ARG ENVIRONMENT=$ENVIRONMENT

ENV NPM_CONFIG_LOGLEVEL warn

# Copy project
WORKDIR /app
COPY . /app

# Run the build if the build-arg ENVIRONMENT is production
RUN if [ $ENVIRONMENT="production" ] ; then echo BUILD $ENVIRONMENT && yarn run build ; else echo DEVELOPMENT BUILD; fi

Now if I ejecute the docker build with

$ docker build --build-arg ENVIRNMOENT=production -t my_react_project .

Actual behavior

I will get this error message

react-scripts build
Creating an optimized production build...
Failed to compile.

Module not found: Error: Can't resolve 'react' in '/app/src'


error An unexpected error occurred: "Command failed.
Exit code: 1
Command: sh
Arguments: -c react-scripts build
Directory: /app
Output:
".

Now, If you go into the docker image running

$ docker run --rm -it my_react_project bash

Now you will be into something like

root@033a87fa9eae:/app#

Now you can execute node and test importing react, it will works

$ node
> const react = require('react');
undefined
> react
{ Children:
   { map: [Function: mapChildren],
     forEach: [Function: forEachChildren],
     count: [Function: countChildren],
     toArray: [Function: toArray],
     only: [Function: onlyChild] },
  Component: [Function: ReactComponent],
  PureComponent: [Function: ReactPureComponent],
.
.
.

Environment

As you can see my platform is
NODE: 8.11
yarn: 1.5.1

Reproducible Demo

You can clone this repo https://github.com/camiloperezv/login-template-react and reproduce the bug there.

I found this issue related #2230

Regards

@Timer
Copy link
Contributor

Timer commented Jun 1, 2018

Hi, we're not experts in Docker or this setup -- why are you installing react-scripts globally, that may be an issue?

This seems better suited for Stack Overflow. Good luck!

@Timer Timer closed this as completed Jun 1, 2018
@MrHen
Copy link

MrHen commented Dec 11, 2018

I'm having the exact same issue with the same symptoms. It seems like npm test is not picking up NODE_PATH correctly even though it is set properly in the environment. I can't tell where the problem lies; it seems like it is somewhere between node, react-scripts and jest.

I can't imagine why the Docker environment would cause any problems. If I hack up the jest-resolve/build/index.js with debug output it clearly shows that NODE_PATH is not making it through:

  resolveModuleFromDirIfExists(dirname, moduleName, options) {
    const paths = (options && options.paths) || this._options.modulePaths;
    const moduleDirectory = this._options.moduleDirectories;
    const key =
      dirname + (_path || _load_path()).default.delimiter + moduleName;
    const defaultPlatform = this._options.defaultPlatform;
    const extensions = this._options.extensions.slice();
    console.log('debug', JSON.stringify({
        paths: paths,
        moduleDirectory: moduleDirectory,
        key: key,
        defaultPlatform: defaultPlatform,
        extensions: extensions,
        nodePaths: nodePaths,
        NODE_PATH: process.env.NODE_PATH,
        dirname: __dirname,
    }, null, 2));

This leads to the output:

debug {
  "moduleDirectory": [
    "node_modules"
  ],
  "key": "/opt/app/client/src:react",
  "extensions": [
    ".web.js",
    ".js",
    ".web.ts",
    ".ts",
    ".web.tsx",
    ".tsx",
    ".json",
    ".web.jsx",
    ".jsx",
    ".node"
  ],
  "nodePaths": null,
  "NODE_PATH": "",
  "dirname": "/modules/node_modules/jest-resolve/build"
}

The specific command I run doesn't seem to matter much between:

  • npm test
  • NODE_PATH=/modules/node_modules npm test
  • NODE_PATH=/modules/node_modules react-scripts test

Other notes and observations:

  • If I run node and then output the NODE_PATH it works as expected
  • jest-resolve itself is installed in /modules/node_modules/ and is loaded correctly -- I assume by node itself
  • The reason for moving the node_modules to /modules/node_modules is a detail of the Docker environment but is necessary in order to build the proper node-sass binary and keep the development environment sane
  • The issue is specific to using create-react-app. This pattern worked for me before I switched to create-react-app. (I was using webpack directly before and did have to add some configuration to make it happy.)
  • Trying to install jest-resolve globally did not fix the problem

My package versions:

root@03cc55342435:/modules/node_modules# npm ls react jest jest-resolve react-scripts
[email protected] /modules
+-- [email protected] 
`-- [email protected] 
  +-- [email protected] 
  | `-- [email protected]
  |   +-- [email protected]
  |   | `-- [email protected]  deduped
  |   +-- [email protected]
  |   | `-- [email protected]  deduped
  |   `-- [email protected]
  |     `-- [email protected]  deduped
  `-- [email protected] 

@MrHen
Copy link

MrHen commented Dec 11, 2018

Alright, I figured it out. The issue is that react-scripts is explicitly filtering out absolute paths from NODE_PATH. You have to change it to a relative path and then it works as expected. In my case, that was changing /modules/node_modules to ../../../modules/node_modules. Ironically, it then normalizes the path back to /modules/node_modules.

I'm not sure why it wants to filter out absolute paths. This is a pretty standard docker setup due to how volume mapping local development environments is so wonky.

@lock lock bot locked and limited conversation to collaborators Jan 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants