0

I'm setting up a dockerized dev environment for node/typescript for an api project. The goal is to run everything in docker and not have any of installed node, npm or modules installed on the host. This is to isolate all versions of node and all modules from other projects.

./node

docker run \
    -it \
    -p "8080:80" \
    --rm \
    -w "/app" \
    -v "$(pwd):/app" \
    "node:10" "$@"

./npm

#!/bin/sh
./node npm $@

./npx

#!/bin/sh
./node npx $@

./package.json

{
  "name": "testapi",
  "version": "0.0.1",
  "description": "a hello world api",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "npx ts-node src/app.ts",
    "lint": "npx ts-lint --project src $@"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^6.2.0",
    "fastify": "^1.13.2",
    "ts-node": "^7.0.1"
  },
  "devDependencies": {
    "@types/node": "^10.12.15",
    "ts-lint": "^4.5.1",
    "typescript": "^3.2.2"
  }
}

[edit]

I use ./npm install to build my node_modules. The node_modules is in a shared volume so it persists on the host after the container is removed. That way I don't need a Dockerfile to build an image.

[/edit]

When I run the lint command, I get the following error:

testapi$ ./npx ts-lint -i
10: Pulling from node
Digest: sha256:5af431757f84bf7878ff72447eb993fc37afcd975874fff13278157bf83661e6
Status: Image is up to date for docker-remote.registry.kroger.com/node:10
npx: installed 32 in 2.883s
Cannot find module 'typescript'

I think this has to do with module resolution, but I don't know this for sure. I see people install typescript globally, but that would mean I have to do a Dockerfile instead of using the stock node image. I don't mind using a Dockerfile for dev, but I think there should be a way to make this work without doing that.

Mnebuerquo
  • 5,759
  • 5
  • 45
  • 52
  • Did you try running `./npm install` prior to running your `.npx` command? Also, with the `node` container you can simply use the regular commands: `npm`, `node`, `npx`, etc. – Tim Klein Dec 18 '18 at 13:55
  • Yes, I didn't mention that in my question, but I did the `./npm install` first. I also tried `rm -rf node_modules` and doing the install again to see if something was installed wrongly. – Mnebuerquo Dec 18 '18 at 14:18
  • Try just calling `npm install` and `npx ts-lint` without using your custom bash scripts – Tim Klein Dec 18 '18 at 15:57
  • @TimKlein the npm install and npx ts-lint are run in the container, so the only way to do that is with docker run. The bash scripts just save me a bunch of typing to get the arguments to the command. – Mnebuerquo Dec 19 '18 at 13:17
  • Fair enough, the naming of the scripts was a little confusing because they shadow the actual command names. Seems like you figured out the issue, so nice job. – Tim Klein Dec 19 '18 at 13:37

2 Answers2

2

So I figured out the answer. It wasn't obvious, and I stumbled upon it by accident.

I had installed ts-lint (see package.json above), and I saw an example which referenced tslint (without the hyphen).

So I removed ts-lint and installed tslint and it worked like a champ. I'm not sure what the difference is, but the one with the hyphen does not work in my project configuration. Also, the one without the hyphen installed a higher version number than the one with the hyphen.

See my new package.json containing the working dependency:

{
  "name": "testapi",
  "version": "0.0.1",
  "description": "a hello world api",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "npx ts-node src/app.ts",
    "lint": "npx tslint --project ./ 'src/**/*.ts?(x)' $@"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^6.2.0",
    "fastify": "^1.13.2",
    "ts-node": "^7.0.1"
  },
  "devDependencies": {
    "@types/node": "^10.12.15",
    "tslint": "^5.12.0",
    "typescript": "^3.2.2"
  }
}

This works when run in a docker container, just using the public node:10 image. It doesn't need a Dockerfile to install any global dependencies.

Mnebuerquo
  • 5,759
  • 5
  • 45
  • 52
0

Try

yarn global add tslint typescript

or if it complained for permissions:

sudo yarn global add tslint typescript
Alex Sed
  • 700
  • 5
  • 12
  • 1
    I'm not using a dockerfile, so I'm not able to add a global package in my container. This might be fine in a docker build step, but I'm just using the node:10 image and mounting my directory as a volume. – Mnebuerquo Aug 03 '20 at 14:27