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

Setup eslint/prettier on docker + host #1

Open
topheman opened this issue Aug 20, 2018 · 4 comments
Open

Setup eslint/prettier on docker + host #1

topheman opened this issue Aug 20, 2018 · 4 comments
Assignees
Labels
enhancement New feature or request

Comments

@topheman
Copy link
Owner

topheman commented Aug 20, 2018

TL;DR

This issue aims to describe how if you setup docker on a fullstack project, you may loose some developer experience like in-editor linting / formating + git hooks and propose a solution.

Without docker

Here is an example of how you would make an advanced setup of eslint/prettier (with husky for precommit hooks) on a regular frontend project without docker topheman/my-react-app-starter@9c0fa1b :

The husky/precommit hooks part will be addressed on an other issue.

With docker

First install prettier, eslint and a few eslint plugins because we want some advanced rules:

docker-compose run --rm front npm install --save-dev --save-exact prettier
docker-compose run --rm front npm install --save-dev cross-env eslint-config-airbnb eslint-config-prettier eslint-plugin-cypress eslint-plugin-prettier

Note: We need to docker-compose run --rm front to run the npm install command inside the docker container, which is a Linux environment, because we are making the call from our host machine which could be a MacOS or a Windows (which means that some native node_modules might differ and will need to be compiled on the right platform to run inside the docker container AND to save the proper versions on the package-lock.json).

Then we'll have to create a few files:

front/.eslintignore:

/build/**
/coverage/**
/docs/**
/tmp/**
/src/libs/**

front/.eslintrc:

{
    "extends": ["react-app", "airbnb", "prettier"],
    "plugins": ["prettier", "cypress"],
    "rules": {
      "prettier/prettier": "error",
      "no-console": "off",
      "react/jsx-filename-extension": "off",
      "react/forbid-prop-types": [2, { "forbid": ["any"] }],
      "react/no-did-mount-set-state": "off",
      "import/prefer-default-export": "off",
      "prefer-template": "off",
      "no-underscore-dangle": ["error", { "allowAfterThis": true }],
      "global-require": "off",
      "import/no-extraneous-dependencies": [
        "error",
        {
          "devDependencies": true,
          "optionalDependencies": false,
          "peerDependencies": false
        }
      ]
    },
    "globals": {
      "cy": true
    },
    "env": {
      "mocha": true,
      "cypress/globals": true
    }
  }

front/.prettierignore:

.git
package-lock.json
package.json
.eslintignore
.gitignore
.prettierignore
.gitignore
*.fixtures.json
src/libs/**

front/.prettierrc:

{}

Add the following scripts to the front/package.json:

"lint": "npx eslint .",
"pretty": "npx prettier --write '**/*.{js,jsx,json,css,scss}'",

That way, we will be able to run eslint and prettier from inside the docker container like this:

docker-compose run --rm front npm run lint
docker-compose run --rm front npm run pretty

For example, the lint task will be run from inside the docker container (NOT from the host):

  • on CircleCI
  • on precommit hooks

Developer Experience

But this is not enough.

  • I want to have my lint errors highlighted in my IDE/editor
  • I want prettier to format my code when I save a file
  • I don't want to use any global modules (can't make any assumption about the computer of the developer, only that he/she may have docker, npm and node)

The things described above:

  • need to happen on the host machine - NOT on the docker container
    • for the moment, no node_modules are installed on the host, they are installed on the container (see docker-compose.override.yml where the front-deps modules is declared)
  • they are tied with IDE/editor implementation specific plugin. For example, the VS Code ESLint extension will use the version of eslint of your working directory (and needed eslint plugins), same for prettier

Solution

This means that we also need to install the node_modules on the host and not alter package-lock.json file while installing.

  • How to run npm install based on package-lock.json, but ensure that it won't be updated in any way ?
  • On the other hand, we can't fully base the npm install on package-lock.json, because host platform and container platform may differ (if your on a Mac for example, you will have to install some optional modules like fsevents)

Further notes about Cypress and Husky

This is the same kind of problem for cypress and husky:

  • cypress:
    • needs to be ran inside the container in command line mode (as it will be ran on CI)
    • should also be ran on the host (to access the GUI to debug tests)
  • husky (not exaclty the same):
    • needs to be ran from the host (when a git commit is made on the host)
    • also, should be installed at the very root of the project, to install commit hooks inside .git at the root
@topheman topheman added the enhancement New feature or request label Aug 20, 2018
@topheman topheman self-assigned this Aug 20, 2018
@topheman
Copy link
Owner Author

topheman commented Aug 29, 2018

A solution (from this twitter thread) might be to:

  • in local:
    • dont run frontend dev env in a docker container (use installed nodejs on the developer's computer)
    • have the frontend dependencies installed on host at ./front/node_modules, based on ./front/package.json - use yarn workspaces to have husky installed at the very root of the project ?
  • in CI:
    • run the frontend unit tests / build in a docker container
    • no change for the golang api (always in a container)

@topheman
Copy link
Owner Author

The following resource may be useful as an intermediary step : https://nickjanetakis.com/blog/docker-tip-75-how-to-avoid-node-modules-in-your-volume-mounts

@pierreyves-lebrun
Copy link

pierreyves-lebrun commented Jul 13, 2019

I stumbled upon the same problem, which ends up being quite frustrating as all the workarounds I’ve seen so far are somewhat hacky.

Edit: actually there is one elegant solution to it:
https://code.visualstudio.com/docs/remote/containers

@topheman
Copy link
Owner Author

I've been told about this solution. You're right @pierreyves-lebrun , this might be the first one true elegant way to solve that problem in a long time. cc @warpdesign

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants