The quick fix jumps over the lazy problem
react-scripts build is called in a directory that also contains a
.eslintrc.js file, React will automatically attempt to lint the code as part of the build. The problem (as we see it), is that our (and probably your?) linting packages are in the
devDependencies section of
package.json - which, when building in your CI environment with
NODE_ENV=production, are not installed. This of course causes the linting, and therefore the entire build, to fail.
As we lint during development and check linting for each PR, there’s no reason for us to lint during build. To tell React to skip this auto-linting, you need to set an environment variable before the
react-scripts build command runs.
DISABLE_ESLINT_PLUGIN=true react-scripts build
A little more context
We’ve been slowly building out a set of admin tools for our editorial team. (Our first tool was one to manage Collections.) We began this repo with the intent of having each tool be its own React application, which gave us the following basic structure:
. ├── .eslintrc.js ├── .gitignore ├── README.md └── collections/ ├── index.tsx └── package.json
package.json was not in the same folder as
.eslintrc.js, we didn’t encounter the auto-linting issue. However, as we are now building a second tool for our editors, we re-assessed this project structure. Wouldn’t it be easier to have a single application that shared UI components, build/deploy scripts, and infrastructre? Yes. Yes it would. So, we reconfigured the project files:
. ├── .eslintrc.js ├── .gitignore ├── package.json ├── README.md └── src/ ├── _shared/ │ ├── assets │ ├── components │ └── pages ├── index.tsx ├── collections/ │ ├── components │ └── pages └── prospects/ ├── components └── pages
package.json is now in the same directory as
All seemed well and good until we opened a PR, at which point the
docker_build step failed with the following:
Failed to compile. Failed to load plugin 'prettier' declared in '.eslintrc.js': Cannot find module 'eslint-plugin-prettier'
Knowing the fix now, the above is easy to understand. However, nowhere could I find documentation that clearly states that if
react-scripts build sees a
.eslintrc.js file in the same directory, it will attempt to lint during build.
After some mostly fruitless research (read: searching Stack Overflow), we eventually did the obvious thing and removed
.eslintrc.js. Voila! The build succeeded! However, we do want our
.eslintrc.js file for local development and PR checks, so while we weren’t exactly done, we had discovered what was triggering the “new” lint-during-build behavior.
From there we re-visited our Stack Overflow tabs, remembering seeing something about disabling linting, re-added
.eslintrc.js, and added the
DISABLE_ESLINT_PLUGIN=true environment variable. Local dev and PR linting? Check. No linting during build? Check.
This was a silly problem to run in to, and was semi-tough to figure out as it wasn’t obvious why React was trying to lint during build all of the sudden. (Additionally, some changes had been made to
package.json in the original PR, so we also had to consider those changes as culprits.)
Hopefully this explanation and fix helps y’all.
P.S. I did find that the
DISABLE_ESLINT_PLUGIN option is documented, but it still doesn’t make clear that the mere presence of a
.eslintrc.js file will trigger linting.
Until next time, take care of each other, and I’ll see you on the internet.
~ jonathan, backend team
Tagged with: #react, #linting, #ci