create-react-app: postcss plugins not found when compiling with CRA v5.0.0 and fomantic-ui

Describe the bug

CRA v5 appears to be incompatible with fomantic-ui, since installing this package causes compile errors about postcss plugins not existing

Did you try recovering your dependencies?

Yes

❯ npm --version 8.5.4

Which terms did you search for in User Guide?

I searched for postcss

Environment

Environment Info:

current version of create-react-app: 5.0.0 running from /home/davidg/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app

System: OS: Linux 5.10 Ubuntu 18.04.6 LTS (Bionic Beaver) CPU: (8) x64 Intel® Core™ i7-6700 CPU @ 3.40GHz Binaries: Node: 16.8.0 - ~/.nvm/versions/node/v16.8.0/bin/node Yarn: Not Found npm: 8.5.4 - ~/.nvm/versions/node/v16.8.0/bin/npm Browsers: Chrome: 99.0.4844.51 Firefox: Not Found npmPackages: react: ^17.0.2 => 17.0.2 react-dom: ^17.0.2 => 17.0.2 react-scripts: 5.0.0 => 5.0.0 npmGlobalPackages: create-react-app: Not Found

Steps to reproduce

  1. npx create-react-app@latest cra-test --use-npm

Follow documented fomantic-ui install instructions: 2. npm install --ignore-scripts fomantic-ui 3. cd node_modules/fomantic-ui 4. npx gulp install (select defaults) 5. npx gulp build 7. npm start (this works normally) 8. rm node_modules package-lock.json -Rf 9. npm install 10. npm start

Expected behavior

Successful compilation

Actual behavior

ERROR in ./src/index.css (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!./node_modules/source-map-loader/dist/cjs.js!./src/index.css) Module Error (from ./node_modules/postcss-loader/dist/cjs.js): Loading PostCSS “postcss-flexbugs-fixes” plugin failed: Cannot find module ‘postcss-flexbugs-fixes’ Require stack:

/home/davidg/cra-test/node_modules/postcss-loader/dist/utils.js /home/davidg/cra-test/node_modules/postcss-loader/dist/index.js /home/davidg/cra-test/node_modules/postcss-loader/dist/cjs.js /home/davidg/cra-test/node_modules/loader-runner/lib/loadLoader.js /home/davidg/cra-test/node_modules/loader-runner/lib/LoaderRunner.js /home/davidg/cra-test/node_modules/webpack/lib/NormalModule.js /home/davidg/cra-test/node_modules/webpack-manifest-plugin/dist/index.js /home/davidg/cra-test/node_modules/react-scripts/config/webpack.config.js /home/davidg/cra-test/node_modules/react-scripts/scripts/start.js

image

Reproducible demo

I hope the steps above are concise enough to serve as a reproducible demo also

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 15
  • Comments: 18

Most upvoted comments

Additional notes:

  • The issue doesn’t exist with CRA version before v5.0.0
  • I created an issue on the fomantic-ui github as well since I’m not sure if this is a CRA or fomantic-ui bug.

Workaround:

npm install postcss-flexbugs-fixes postcss-normalize postcss-preset-env (even though according to npm ls these are all already installed as dependencies of react-scripts

I have the same issue except I’m not using fomantic-ui but Material-UI. The npm install postcss-flexbugs-fixes postcss-normalize postcss-preset-env workaround also fixes the issue for me.

I believe something in my codebase is triggering the postcss which is failing since the packages are installed under node_modules/react-scripts/node_modules/

Before running npm install postcss-flexbugs-fixes

$ find node_modules/ -name 'postcss-flexbugs-fixes'
node_modules/react-scripts/node_modules/postcss-flexbugs-fixes

After running npm install postcss-flexbugs-fixes

$ find node_modules/ -name 'postcss-flexbugs-fixes'
node_modules/postcss-flexbugs-fixes

I’m pretty sure the above change in postcss-flexbugs-fixes package location is the reason why it starts working. Do you know if there’s a way to fix it other than installing those three packages? Also any idea what is triggering the postcss processing in cra application? I tried but couldn’t find the culprit from my fairly large codebase.

Rebuilding the lockfile worked for me as well.

For those still struggling with this problem. I use craco to customize the webpack config and remove postcss.


   webpack: {
      configure: (webpackConfig, {env, paths}) => {
         // Remove post css loader from webpack config
         webpackConfig.module.rules[1].oneOf.map((e)=>{
            if(e.use!=null){
               e.use=e.use.filter((e)=>e?.options?.postcssOptions==null);
            }
            return e;
         });

I believe @samuliasmala is correct that the relative positioning between packages is the fundamental issue.

Solution 1

I was able to solve the issue by manually relocating the postcss-loader package in my package-lock.json file.

Git diff package-lock.json
diff --git a/package-lock.json b/package-lock.json
index 1bbfc8b..b096334 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18122,43 +18122,6 @@
         "url": "https://tidelift.com/funding/github/npm/postcss"
       }
     },
-    "node_modules/postcss-loader": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz",
-      "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==",
-      "dev": true,
-      "dependencies": {
-        "cosmiconfig": "^7.0.0",
-        "klona": "^2.0.5",
-        "semver": "^7.3.5"
-      },
-      "engines": {
-        "node": ">= 12.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      },
-      "peerDependencies": {
-        "postcss": "^7.0.0 || ^8.0.1",
-        "webpack": "^5.0.0"
-      }
-    },
-    "node_modules/postcss-loader/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/postcss-opacity-percentage": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz",
@@ -19787,6 +19750,28 @@
         "postcss": "^8.4"
       }
     },
+    "node_modules/react-scripts/node_modules/postcss-loader": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz",
+      "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==",
+      "dev": true,
+      "dependencies": {
+        "cosmiconfig": "^7.0.0",
+        "klona": "^2.0.5",
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "postcss": "^7.0.0 || ^8.0.1",
+        "webpack": "^5.0.0"
+      }
+    },
     "node_modules/react-scripts/node_modules/postcss-logical": {
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",

In short, I changed the node_modules/postcss-loader key under the packages section of package-lock.json to node_modules/react-scripts/node_modules/postcss-loader and relocated that entry so the packages section remained in tidy alphabetical order. After this, running npm i will make a few other small modifications to the file (for me it removed the node_modules/postcss-loader/node_modules/semver key from packages and removed the postcss-loader entry from the dependencies section, nesting it under dependencies['react-scripts'].dependencies instead.

From here, npm run build succeeds just fine. I have no idea why postcss-loader was not already located under react-scripts, as that’s the only package that depends on it. Perhaps I previously had another package installed that depended on it? Unsure.


Solution 2

I wasn’t entirely comfortable with manually editing this generated file (though after it’s committed to version control there it shouldn’t be an issue), so I also messed around with rebuilding the package-lock.json file altogether. This approach worked too, though it was a little more complicated and involved updating thousands of sub-dependencies. My project depends on two packages which themselves depend on postcss: react-scripts and madge, which I use in a script to detect cyclical imports in my codebase:

➜ npm ls postcss
my_project@1.0.0 /path/to/my/repo
├─┬ madge@3.10.0
│ └─┬ detective-postcss@3.0.1
│   └── postcss@7.0.34
└─┬ react-scripts@5.0.1
  ├── postcss@8.4.12
  └ [60 other sub-dependencies also depending on postcss]

Because both react-scripts and madge depend on postcss, the postcss package is hoisted up the tree to their common ancestor package, which is the repository root. If I uninstall madge, this alone does not solve the problem. However, if I delete the package-lock.json file, delete my node_modules directory and rerun npm install, things are different:

➜ npm run build

> my_project@0.1.0 build
> react-scripts build

Creating an optimized production build...
Failed to compile.

Loading PostCSS "postcss-flexbugs-fixes" plugin failed: Cannot find module 'postcss-flexbugs-fixes'
[snip]

➜ npm uninstall madge

removed 89 packages, and audited 1860 packages in 1s
[snip]

➜ rm package-lock.json
➜ rm -rf node_modules
➜ npm i
added 1727 packages, and audited 1729 packages in 37s

# Force installation of specific versions--my project already depended on these.
# This was necessary because my package.json permitted subsequent minor releases of these
# packages to be installed, and these introduced minor breaking changes. So I am downgrading.
➜ npm i @material-ui/core@4.11.0 @material-ui/lab@4.0.0-alpha.56 @reduxjs/toolkit@1.4.0
➜ npm run build

Creating an optimized production build...
Compiled successfully.

In other words, forcing npm to rebuild the package-lock.json file solved the issue. What makes this extra frustrating is that, after doing all this, I can reinstall the exact same version of madge and my build will continue to run just fine:

➜ npm i -D madge@3.10.0
➜ npm run build
[snip]
Compiled successfully.

Deleting the node_modules directory now and running npm i again (using the newly generated lockfile) does not break the build. At this point, my package.json file has not changed at all, only the package-lock.json file which has thousands of lines changed so I can’t possibly determine which of those changes resolved the problem. However, following the re-generation of the lockfile:

➜ find node_modules -name 'postcss-flexbugs-fixes'
node_modules/postcss-flexbugs-fixes
➜ find node_modules -name 'postcss-normalize'
node_modules/postcss-normalize
➜ find node_modules -name 'postcss-preset-env'
node_modules/postcss-preset-env

At the end of the day, I have no idea why rebuilding the lockfile caused these packages to be hoisted to the repository root, but I strongly suspect that’s why the build now succeeds.

For those still struggling with this problem. I use craco to customize the webpack config and remove postcss.


   webpack: {
      configure: (webpackConfig, {env, paths}) => {
         // Remove post css loader from webpack config
         webpackConfig.module.rules[1].oneOf.map((e)=>{
            if(e.use!=null){
               e.use=e.use.filter((e)=>e?.options?.postcssOptions==null);
            }
            return e;
         });

Facing this issue now. My team does use craco, but what does this actually do? I’m hesitant to rebuild the lockfile since that will imply many dependency changes.