Running Jest in --watch mode in a Docker container in a subdirectory of git root

Viewed 2474

I have built a web project with the following file structure:

-root_folder/
  -docker-compose.yml
  -.git/
  -backend/
    -.dockerignore
    -docker/
      -dev.dockerfile
  -frontend/
    -.dockerignore
    -docker/
      -dev.dockerfile

I run the frontend app (Angular) in a Docker container. I also run the backend app (ExpressJS) in another container but the backend is not relevant to my problem.

I have mounted the volume ./frontend to /app in the container in order to allow hot reloads.

This configuration works to run Angular just fine. However, when running Jest with the --watch flag it gives the error --watch is not supported without git/hg, please use --watchAll

I went back into the dockerfile and added:

RUN apk update -q && \
    apk add -q git

But this doesn't fix the problem. From all the research I've done, it seems that the issue is that Jest watch mode uses git somehow to detect changes, but my git folder is not in the 'frontend' subdirectory.

I tried to modify my container to copy all the files to /app/frontend instead and then also copy in and mount .git folder to /app/.git but that had no effect.

I do not want to run Jest with --watchAll (but I tested it and that does run properly). Any suggestions?

EDIT Answered my own question. I was on the right track with mounting the .git folder. The missing step was setting GIT_WORK_TREE and GIT_DIR environment variables.

1 Answers

I was able to get this working exactly as I wanted. The problem is that in order for Jest to run in watch mode, it does so by looking at the changed files according to Git. I was able to get this functionality working by setting up the directory structure on the container similar to my host system with:

-app/
  -.git/
  -frontend/

Then, most importantly, setting the GIT_WORK_TREE and GIT_DIR environment variables.

Here is my dockerfile:

FROM node:alpine3.11 as dev

WORKDIR /app/frontend

# To use packages in CLI without global install
ENV PATH /app/frontend/node_modules/.bin:$PATH

COPY . .

RUN npm install --silent

EXPOSE 4200

CMD ["/bin/sh", "-c", "npm run start:dev"]

##########################################################
FROM dev as unit-test

ENV GIT_WORK_TREE=/app/frontend GIT_DIR=/app/.git

RUN apk update && \
    apk add git

CMD ["/bin/sh", "-c", "jest --watch"]

Without the env vars set, Jest continues to give the error that it can't work without git. I'm assuming it's because git init was never ran and it probably does some other stuff behind the scenes that copying in the .git folder doesn't accomplish.

Here is the docker-compose I used for the test service in case it helps someone:

  f-test-unit:
    container_name: "f-test-unit"
    build:
      context: "frontend"
      dockerfile: "docker/dev.dockerfile"
      target: "unit-test"
    volumes:
      - "./frontend:/app/frontend"
      - "/app/frontend/node_modules/"
      - "./.git:/app/.git"
    tty: true
    stdin_open: false

Side note: if you add the tty and stdin_open lines, it allows for your logs in the docker container to be colorized, which is very useful with Jest.

Related