devspace-sh / devspace

DevSpace - The Fastest Developer Tool for Kubernetes ⚡ Automate your deployment workflow with DevSpace and develop software directly inside Kubernetes.
https://devspace.sh
Apache License 2.0
4.37k stars 361 forks source link

npm scripts not working #2566

Closed ph55 closed 1 year ago

ph55 commented 1 year ago

What happened? Trying to run nodejs up with watch either by nodemon or pm2 but none of the npm scrips are working from within devspace

How can we reproduce the bug? (as minimally and precisely as possible)

devspace ./app # npm run pm2

> myApp@0.0.0 pm2
> pm2

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

Error: Cannot find module '../lib/binaries/CLI.js'
Require stack:
- /app/node_modules/.bin/pm2
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/app/node_modules/.bin/pm2:3:1)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Module._load (node:internal/modules/cjs/loader:922:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/app/node_modules/.bin/pm2' ]
}

Node.js v18.13.0
devspace ./app # npm run nodemon

> myApp@0.0.0 nodemon
> nodemon

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

Error: Cannot find module '../lib/cli'
Require stack:
- /app/node_modules/.bin/nodemon
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/app/node_modules/.bin/nodemon:3:13)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Module._load (node:internal/modules/cjs/loader:922:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/app/node_modules/.bin/nodemon' ]
}

Node.js v18.13.0
devspace ./app #

My devspace.yaml:

version: v2beta1
name: nodejs

# This is a list of `pipelines` that DevSpace can execute (you can define your own)
pipelines:
  # This is the pipeline for the main command: `devspace dev` (or `devspace run-pipeline dev`)
  dev:
    run: |-
      run_dependencies --all       # 1. Deploy any projects this project needs (see "dependencies")
      ensure_pull_secrets --all    # 2. Ensure pull secrets
      create_deployments --all     # 3. Deploy Helm charts and manifests specfied as "deployments"
      start_dev nodejs             # 4. Start dev mode "nodejs" (see "dev" section)
  # You can run this pipeline via `devspace deploy` (or `devspace run-pipeline deploy`)
  deploy:
    run: |-
      run_dependencies --all                            # 1. Deploy any projects this project needs (see "dependencies")
      ensure_pull_secrets --all                         # 2. Ensure pull secrets
      build_images --all -t $(git describe --always)    # 3. Build, tag (git commit hash) and push all images (see "images")
      create_deployments --all                          # 4. Deploy Helm charts and manifests specfied as "deployments"

# This is a list of `images` that DevSpace can build for this project
# We recommend to skip image building during development (devspace dev) as much as possible
images:
  nodejs:
    image: XXX.dkr.ecr.us-east-1.amazonaws.com/nodejs
    dockerfile: ./Dockerfile

# This is a list of `deployments` that DevSpace can create for this project
deployments:
  nodejs:
    # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
    helm:
      # We are deploying this project with the Helm chart you provided
      chart:
        name: ../tt-helm/nodejs
      # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
      # You may also use `valuesFiles` to load values from files, e.g. valuesFiles: ["values.yaml"]
      values:
        someChartValue: ""

# This is a list of `dev` containers that are based on the containers created by your deployments
dev:
  nodejs:
    # Search for the container that runs this image
    labelSelector:
      app.kubernetes.io/name: nodejs
    # Replace the container image with this dev-optimized image (allows to skip image building during development)
    devImage: ghcr.io/loft-sh/devspace-containers/javascript:18-alpine
    # Sync files between the local filesystem and the development container
    sync:
      - path: ./
    # Open a terminal and use the following command to start it
    terminal:
      command: ./devspace_start.sh
    # Inject a lightweight SSH server into the container (so your IDE can connect to the remote dev env)
    ssh:
      enabled: true
    # Make the following commands from my local machine available inside the dev container
    proxyCommands:
      - command: devspace
      - command: kubectl
      - command: helm
      - gitCredentials: true
    # Forward the following ports to be able access your application via localhost
    ports:
      - port: "9229"
      - port: "3000"
    # Open the following URLs once they return an HTTP status code other than 502 or 503
    open:
      - url: http://localhost:3000

# Use the `commands` section to define repeatable dev workflows for this project 
commands:
  migrate-db:
    command: |-
      echo 'This is a cross-platform, shared command that can be used to codify any kind of dev task.'
      echo 'Anyone using this project can invoke it via "devspace run migrate-db"'

# Define dependencies to other projects with a devspace.yaml
# dependencies:
#   api:
#     git: https://...  # Git-based dependencies
#     tag: v1.0.0
#   ui:
#     path: ./ui        # Path-based dependencies (for monorepos)
...

Local Environment:

Client Version: v1.26.1
Kustomize Version: v4.5.7
Server Version: v1.23.14-eks-ffeb93d
WARNING: version difference between client (1.26) and server (1.23) exceeds the supported minor version skew of +/-1
lizardruss commented 1 year ago

Hello! This looks like an error from npm. Did you happen to run npm install after adding those dependencies?

It might also be helpful to include the devspace_start.sh script and package.json files. I believe devspace init will configure devspace_start.sh to run npm install, but you'll still need to run npm install from the container's terminal as you make changes to package.json.

ph55 commented 1 year ago

@lizardruss Yes.

As you can see it the error stack example error thrown from installed nodemon directory in node_modules:

    at Object.<anonymous> (/app/node_modules/.bin/nodemon:3:13)

As a workaround, installing nodemon globally with npm install -g nodemon by adding it to devspace_start.sh - fixes the problem.

Also, after switching from DevSpace image javascript:18-alpine to our own ECR image - everything works.

lizardruss commented 1 year ago

@ph55 Glad you got everything working!

ph55 commented 1 year ago

@lizardruss It is working by not using DevSpace quick start image. It doesn't mean the bug is resolved (if any).

Could be related to this issue https://github.com/devspace-sh/devspace/issues/2047

lizardruss commented 1 year ago

@ph55 I think your addition of npm install -g nodemon to devspace_start.sh was the correct fix. Running npx nodemon in your package.json's scripts may also work. If there were other issues please share a minimal package.json that will reproduce the issue. From what you've shared so far, it looks like you've used devspace init to generate an initial devspace.yaml with an existing package.json. Because it's an existing project, some adjustments might be needed for globally installed packages.

ph55 commented 1 year ago

@lizardruss Sorry maybe I wasn't clear enough in the description will try again. nodemon is installed as dev dependency. I don't want to use it as global dependency.

Here an example to reproduce the issue with another popular nodejs package/framework NestJS.

Steps to reproduce

  1. Create new nest project

    • npm i -g @nestjs/cli
    • nest new devspace-test (choose npm)
  2. Initialize devspace

devspace.yaml

version: v2beta1
name: app

# This is a list of `pipelines` that DevSpace can execute (you can define your own)
pipelines:
  # This is the pipeline for the main command: `devspace dev` (or `devspace run-pipeline dev`)
  dev:
    run: |-
      run_dependencies --all       # 1. Deploy any projects this project needs (see "dependencies")
      ensure_pull_secrets --all    # 2. Ensure pull secrets
      create_deployments --all     # 3. Deploy Helm charts and manifests specified as "deployments"
      start_dev app                # 4. Start dev mode "app" (see "dev" section)

# This is a list of `dev` containers that are based on the containers created by your deployments
dev:
  app:
    # Search for the container that runs this image
    labelSelector:
      app.kubernetes.io/name: nodejs
    # Replace the container image with this dev-optimized image (allows to skip image building during development)
    devImage: ghcr.io/loft-sh/devspace-containers/javascript:18-alpine
    workingDir: /app
    # Sync files between the local filesystem and the development container
    sync:
      - path: ./
    # Open a terminal and use the following command to start it
    terminal:
      command: ./devspace_start.sh
    # Inject a lightweight SSH server into the container (so your IDE can connect to the remote dev env)
    ssh:
      enabled: true
    # Make the following commands from my local machine available inside the dev container
    proxyCommands:
      - command: devspace
      - command: kubectl
      - command: helm
      - gitCredentials: true
    # Forward the following ports to be able access your application via localhost
    ports:
      - port: "9229"
      - port: "3000"

# Use the `commands` section to define repeatable dev workflows for this project 
commands:
  migrate-db:
    command: |-
      echo 'This is a cross-platform, shared command that can be used to codify any kind of dev task.'
      echo 'Anyone using this project can invoke it via "devspace run migrate-db"'

devspace_start.sh

#!/bin/bash
set +e  # Continue on errors

# Run npm or bash scripts here if needed.
echo "Installing NPM Dependencies"
npm install

COLOR_BLUE="\033[0;94m"
COLOR_GREEN="\033[0;92m"
COLOR_RESET="\033[0m"

# Print useful output for user
echo -e "${COLOR_BLUE}
     %########%      
     %###########%       ____                 _____                      
         %#########%    |  _ \   ___ __   __ / ___/  ____    ____   ____ ___ 
         %#########%    | | | | / _ \\\\\ \ / / \___ \ |  _ \  / _  | / __// _ \\
     %#############%    | |_| |(  __/ \ V /  ____) )| |_) )( (_| |( (__(  __/
     %#############%    |____/  \___|  \_/   \____/ |  __/  \__,_| \___\\\\\___|
 %###############%                                  |_|
 %###########%${COLOR_RESET}

Welcome to your development container!

This is how you can work with it:
- Files will be synchronized between your local machine and this container
- Some ports will be forwarded, so you can access this container via localhost
- Run \`${COLOR_GREEN}npm run start:dev${COLOR_RESET}\` to start the application in watch mode
- Run \`${COLOR_GREEN}npm run start:debug${COLOR_RESET}\` to start the application in watch mode with debugger
"

# Set terminal prompt
export PS1="\[${COLOR_BLUE}\]devspace\[${COLOR_RESET}\] ./\W \[${COLOR_BLUE}\]\\$\[${COLOR_RESET}\] "
if [ -z "$BASH" ]; then export PS1="$ "; fi

# Include project's bin/ folder in PATH
export PATH="./bin:$PATH"

# Open shell
bash --norc
  1. devspace dev and try to run the app with npm run start:dev It will fail with error:
devspace ./app # npm run start:dev

> devspace-test@0.0.1 start:dev
> nest start --watch

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

Error: Cannot find module '../commands'
Require stack:
- /app/node_modules/.bin/nest
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/app/node_modules/.bin/nest:14:20)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Module._load (node:internal/modules/cjs/loader:922:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/app/node_modules/.bin/nest' ]
}

@nestjs/cli is installed as dev dependency.

image

Similar error will happen with EVERY package that is installed as dev dependency and used in npm scripts section.