facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
56.95k stars 8.57k forks source link

Fails when installing in a repo using Tailwind PostCSS plugin: cannot read config from undefined #6631

Open Kiyozz opened 2 years ago

Kiyozz commented 2 years ago

Have you read the Contributing Guidelines on issues?

Prerequisites

Description

Cannot start/build docusaurus classic template

Tried with node@14/node@16/node@17

Steps to reproduce

Waiting for npx create-docusaurus@latest web classic to complete

cd web
yarn start

Expected behavior

Client compiled

Actual behavior

❯ yarn start
yarn run v1.22.17
$ docusaurus start
[INFO] Starting the development server...
[SUCCESS] Docusaurus website is running at http://localhost:3000/.

✖ Client
  Compiled with some errors in 3.01s
[...]
TypeError: Cannot read properties of undefined (reading 'config')
TypeError: Cannot read properties of undefined (reading 'config')
TypeError: Cannot read properties of undefined (reading 'config')
TypeError: Cannot read properties of undefined (reading 'config')
client (webpack 5.68.0) compiled with 88 errors

Your environment

new.docusaurus codesandbox bad gateway. new.docusaurus stackblitz all ok

Reproducible demo

My project

  1. pnpm i to setup the project deps
  2. cd docs/web
  3. yarn
  4. yarn start
  5. See the errors in console without stack trace

You could remove the docs/web directory and create a docusaurus yourself

  1. rm -rf docs/web
  2. cd docs
  3. npx create-docusaurus@latest
  4. web for the project name
  5. classic for the template
  6. use typescript
  7. cd web
  8. yarn start
  9. See the errors in console without stack trace

Self-service

Josh-Cena commented 2 years ago

Without a reproduction we can't do anything. You must be doing something wrong with your website's code, possibly referencing a variable that doesn't exist. Please don't use the GitHub issue tracker for your question; and even if you do, questions without literally any code can't get you help.

Kiyozz commented 2 years ago

Did you read my issue description or is this an automatic message? This is totally the code that comes from the result of the create-docusaurus command.

There is no reproduction repo because it comes from the template itself.

What do you want me to do then?!

Please don't use the GitHub issue tracker for your question

This is not a question. Please reopen

Kiyozz commented 2 years ago

This might be because the new docusaurus project is in a subdirectory of a pnpm project (docusaurus project dependencies has been installed via yarn).

project/docs/web <- this directory is docusaurus.

When creating outside, everything works.

Josh-Cena commented 2 years ago

I create new projects almost every two days (for repro purposes) and we have E2E tests that scaffold new websites on every PR, so it's hard for me to conclude that there's something wrong with the init template. That's why I'm asking you to provide a repro.

We have detailed instructions in the issue template telling you that you should spend some time trying to reduce this to a minimum reproduction sample so that we can further inspect the offending code, but you seem to spend less time reading that text and working on the bug yourself than we did to write that instruction. Hence I did exactly what was said in that template:

What happens if you skip this step? Someone will read your bug report, and maybe will be able to help you, but it’s unlikely that it will get much attention from the team. Eventually, the issue will likely get closed in favor of issues that have reproducible demos.

Please remember that:

  • Issues without reproducible demos have a very low priority.
  • The person fixing the bug would have to do that anyway. Please be respectful of their time.
  • You might figure out the issues yourself as you work on extracting it.

And you seem to concede that

new.docusaurus stackblitz all ok

which means it must be your local setup. How do you expect me to reproduce it?


This might be because the new docusaurus project is in a subdirectory of a pnpm project (docusaurus project dependencies has been installed via yarn).

That sounds better, but I still need more details than that. If you managed to reliably reproduce it and have solid evidence that it's a bug and not something wrong with your setup or some misunderstanding about how Docusaurus works, I'm okay to reopen this.

Note that we don't support installing dependencies with PNPM yet, so if you are managing a monorepo, you'd rather want to install with --skip-install and manually run pnpm install in your repo's root.

Kiyozz commented 2 years ago

Note that we don't support installing dependencies with PNPM yet, so if you are managing a monorepo, you'd rather want to install with --skip-install and manually run pnpm install in your repo's root.

I'll link my repo with a docusaurus inside of it to a commit that failed. I tried dependencies with yarn, npm, and pnpm. All same result. After spending time to fix this, I tried outside of the project, and it worked. Despite the docusaurus is installed (and deps) with yarn (so no conflict with pnpm as it is a new node_modules dir), the build failed.

Josh-Cena commented 2 years ago

You are also missing stack traces in your error. In order for me to investigate, I would need the stack trace and a reproduction demo. I seldom use PNPM and neither do I have a working PNPM repo set up.

Kiyozz commented 2 years ago

So, I updated the main post. There is now a repro branch of my project. Thanks you for your help into this.

Josh-Cena commented 2 years ago

Note that mixing package managers in the first place is a bad idea, especially with PNPM which has a different node_modules assembling strategy.

Kiyozz commented 2 years ago

Yes I know! But I used yarn here because:

  1. docusaurus force you to install deps with yarn at the first place (please --skip-install should be the default... 😅)
  2. pnpm is not officially supported by docusaurus.

I already tried installing the deps with pnpm too, but same thing happened.

Josh-Cena commented 2 years ago

docusaurus force you to install deps with yarn at the first place (please remove auto install... 😅)

This is because we have far more users that aren't aware of package managers and even an additional npm install step for them is overwhelming😅 I know it's super annoying for you and me, but if you've been helping in the community for a while, you understand it's better if we can do more under the hood. You can use the --skip-install flag if you just want the template.

[PNPM] is not officially supported by docusaurus.

We have an E2E test for installing new projects with PNPM and it had successfully caught a few incompatible changes (most recently #6604), so I'd say it's at least supported for normal use-cases. But for more complicated situations we absolutely recommend Yarn so you can be sure to be on the same page as us.

Josh-Cena commented 2 years ago

BTW, the stack traces are retrievable in the overlay:

ERROR in ./node_modules/@docusaurus/core/lib/client/nprogress.css

Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
TypeError: Cannot read properties of undefined (reading 'config')
    at getTailwindConfig (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/node_modules/.pnpm/tailwindcss@3.0.18_ef48b3b8837f8a23677bffe8f9cd866d/node_modules/tailwindcss/lib/lib/setupTrackingContext.js:81:62)
    at /Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/node_modules/.pnpm/tailwindcss@3.0.18_ef48b3b8837f8a23677bffe8f9cd866d/node_modules/tailwindcss/lib/lib/setupTrackingContext.js:124:92
    at /Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/node_modules/.pnpm/tailwindcss@3.0.18_ef48b3b8837f8a23677bffe8f9cd866d/node_modules/tailwindcss/lib/processTailwindFeatures.js:43:11
    at plugins (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/node_modules/.pnpm/tailwindcss@3.0.18_ef48b3b8837f8a23677bffe8f9cd866d/node_modules/tailwindcss/lib/index.js:20:104)
    at LazyResult.runOnRoot (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/postcss/lib/lazy-result.js:339:16)
    at LazyResult.runAsync (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/postcss/lib/lazy-result.js:393:26)
    at LazyResult.async (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/postcss/lib/lazy-result.js:221:30)
    at LazyResult.then (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/postcss/lib/lazy-result.js:206:17)
    at processResult (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/webpack/lib/NormalModule.js:753:19)
    at /Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/webpack/lib/NormalModule.js:855:5
    at /Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/loader-runner/lib/LoaderRunner.js:399:11
    at /Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/loader-runner/lib/LoaderRunner.js:251:18
    at context.callback (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
    at Object.loader (/Users/joshcena/Desktop/work/Tech/Projects/repros/papyrus-compiler-app/docs/web/node_modules/postcss-loader/dist/index.js:142:7)

[Every other CSS file we have]

It seems some unwanted code is being visited

Josh-Cena commented 2 years ago

@Kiyozz I have concluded that it has nothing to do with PNPM, but rather about your PostCSS config. Because we use PostCSS, the loader will read the postcss.config.js file. However, this seems to be the cause: https://github.com/Kiyozz/papyrus-compiler-app/blob/139-docusaurus/postcss.config.js

I don't have much experience with Tailwind CSS (I know @slorber does :D) So I'd have to see where it goes wrong. I know this config is included in the Tailwind docs.

Edit. This seems to do the trick:

// postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {
      content: ["./src/**/*.{html,js}"],
    },
    autoprefixer: {},
  },
}

I wonder why the tailwind plugin is not reading the tailwind.config.js in this case

Kiyozz commented 2 years ago

Thanks you Joshua.

It feels strange that postcss loader is searching recursively for a postcss config. Does having a postcss config in the template disallow the loader to search recursively?

Josh-Cena commented 2 years ago

It feels strange that postcss loader is searching recursively for a postcss config.

That's typical behavior with most loaders. E.g. Babel loader will recursively look for a babel.config.js afaik.

Does having a postcss config in the template disallow the loader to search recursively?

Adding a docs/web/postcss.config.js with module.exports = {} does seem to fix it. We probably won't add it to the template, but I think it's a good enough solution for your case.

Kiyozz commented 2 years ago

Is this something docusaurus should be aware (maybe in a faq or something?) or is this only for my use case?

Josh-Cena commented 2 years ago

I don't think anyone has stumbled upon it (although I do know a few sites that use Tailwind + Docusaurus, or Docusaurus in a repo that also uses Tailwind) and it's ultimately just a workaround. Preferably, we should be able to fix it, but given my limited knowledge in either PostCSS or Tailwind, I'll let @slorber make the decision

harish-sethuraman commented 2 years ago

I don't think anyone has stumbled upon it

During manual migration I faced the same issue. Not sure why. But when I removed all changes and tried migration for the second time I didn't get the issue. Our repo doesn't use tailwind css. I used yarn both time.

Adding a docs/web/postcss.config.js with module.exports = {} does seem to fix it. We probably won't add it to the template, but I think it's a good enough solution for your case.

I fixed it by creating tailwind.config.js file and adding basic default tailwind config 😄

module.exports = {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}
harish-sethuraman commented 2 years ago

@Kiyozz Do you use M1 mac by any chance?

Kiyozz commented 2 years ago

@Kiyozz Do you use M1 mac by any chance?

Indeed

harish-sethuraman commented 2 years ago

It worked on my intel MacBook pro and throws config error in m1 mac 😅 .

Josh-Cena commented 2 years ago

Meh, I'm M1 as well. Would be interesting to have any non-M1 contributor to investigate

dhushyanth-s commented 2 years ago

Can reproduce on a fresh install on an M1 machine. The commands I ran was

npx create-docusaurus@latest docs classic
cd docs
yarn start

Fixed by following @harish-sethuraman 's advice, creating a tailwind.config.js with default configs in the root of docusaurus folder.

yarn version: 1.22.5 node version: v16.13.2

slorber commented 2 years ago

So the init template (on which Tailwind is not installed) fails to start? Are you sure it's the full repro steps? 🤷‍♂️

harish-sethuraman commented 2 years ago

So the init template (on which Tailwind is not installed) fails to start? Are you sure it's the full repro steps? 🤷‍♂️

Yes I can confirm.

npx create-docusaurus@latest docs classic
cd docs
yarn start

starts throwing errors

TypeError: Cannot read properties of undefined (reading 'config')
client (webpack 5.68.0) compiled with 88 errors
slorber commented 2 years ago

I have an M1 pro and can't reproduce this issue with those 3 commands 🤷‍♂️

harish-sethuraman commented 2 years ago

Do you need any other details? It got replicated when I ran those three steps. Maybe I can help you get the necessary details. Any commands that I can run?

slorber commented 2 years ago

I don't know, try to provide anything that may be relevant and we'll try to reproduce with same env or compare with other users having similar setups

harish-sethuraman commented 2 years ago

Also I was in v16.13.1 node version when this happened

Josh-Cena commented 2 years ago

@slorber You need to have Tailwind installed and configured through postcss.config.js and/or tailwind.config.js in your parent directory.

vnugent commented 2 years ago

I'm having the same issue. The docusarus project works fines as an independent project. The moment I moves it to a subdir under another project with postcss.config.js in the parent dir, docusarus yarn build will fail.

root_project (next.js + tailwind)
   | package.json
   | postcss.config.js. <--- Test: rename this file and the error will go away
   ...
   | --- docs (docusaurus)
         ...

Workaround:

I hope this helps.

nvh95 commented 2 years ago

I have an exact issue and I can provide the reproduction @Josh-Cena, @slorber. Please do as follow (failed on netlify and Macbook Air M1 2020):

git clone https://github.com/nvh95/jest-preview
cd jest-preview
git checkout 706719f3ad4e0810d170f4297312ead9f7e11da9
cd website
npm install
# Build docusaurus site
npm run build

The output:

Toggle Loading PostCSS "tailwindcss" plugin failed: Cannot find module 'tailwindcss' Require stack: - /Users/myname/oss/jest-preview/website/node_modules/postcss-loader/dist/utils.js - /Users/myname/oss/jest-preview/website/node_modules/postcss-loader/dist/index.js - /Users/myname/oss/jest-preview/website/node_modules/postcss-loader/dist/cjs.js - /Users/myname/oss/jest-preview/website/node_modules/webpack/lib/ProgressPlugin.js - /Users/myname/oss/jest-preview/website/node_modules/webpack/lib/index.js - /Users/myname/oss/jest-preview/website/node_modules/@docusaurus/core/lib/webpack/utils.js - /Users/myname/oss/jest-preview/website/node_modules/@docusaurus/core/lib/webpack/base.js - /Users/myname/oss/jest-preview/website/node_modules/@docusaurus/core/lib/webpack/client.js - /Users/myname/oss/jest-preview/website/node_modules/@docusaurus/core/lib/commands/build.js - /Users/myname/oss/jest-preview/website/node_modules/@docusaurus/core/lib/index.js (@/Users/myname/oss/jest-preview/website/src/pages/index.module.css) [ERROR] Client bundle compiled with errors therefore further build is impossible.

If I run npm i at the root of the project, then re-run npm run build inside website, the error looks like this

Toggle TypeError: Cannot read properties of undefined (reading 'config') Generated code for /Users/myname/oss/jest-preview/website/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[7].use[1]!/Users/myname/oss/jest-preview/website/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[7].use[2]!/Users/myname/oss/jest-preview/website/node_modules/@docusaurus/theme-search-algolia/lib/theme/SearchPage/styles.module.css TypeError: Cannot read properties of undefined (reading 'config') -- inner error --

I think somehow, docusaurus traverses to its parent folders and if it sees a postcss.config.js, it uses that file. In this case, that behavior is not expected.

nvh95 commented 2 years ago

Another workaround if your docusaurus site does not use TailwindCSS:

Josh-Cena commented 2 years ago

This is postcss-loader's default behavior. You will see the same result if you have a babel.config.js (which we just happen to already have one by default).

nvh95 commented 2 years ago

This is postcss-loader's default behavior. You will see the same result if you have a babel.config.js (which we just happen to already have one by default).

I see. But is there anything we can do to mitigate this unexpected behavior? As a docusaurus user, I don't want to care about "its parent folder has a postcss.config.js file". A normal user thinks docusaurus folder should be in isolation. For example: I don't even use postcss/ tailwindcss for my docusaurus project, but when I "accidentally" put it as a child folder to a folder contains postcss.config.js, the app fails to build.

Again, if that how postcss-loader behaves, can we do anything to avoid the confusion for some users (who have already had this issue and who are going to have this issue)? Some of my initiatives:

Josh-Cena commented 2 years ago

I think documenting this is fine, because sometimes projects do want to have a monorepo-wide CSS config (not sure if it works anyway). Still waiting for @slorber to decide if there's something obviously wrong with our config (I can't see any), or if this is working as intended and we just need to document it.

nvh95 commented 2 years ago

Yeah. Thank you @Josh-Cena. I think documenting and if possible, trying to catch the error and show some meaningful error messages would be wonderful.

slorber commented 2 years ago

@nvh95 your monorepo has an unusual shape:

IE you are nesting one package within another without very clear package boundaries and no monorepo deps hoisting.

I can't tell if this monorepo setup should always be forbidden/avoided in all cases, but it clearly leads to unexpected behaviors in many situations.

I suggest doing like everyone else: move your core project code to an isolated subfolder, and use Yarn/npm workspaces.

zavbala commented 1 year ago

I'm here for a Sanity Studio V3 adding an empty tailwind.config.js fix the issue.

roypearce commented 1 year ago

Just encountered a similar issue where locally everything builds fine, but for whatever reason in CI (same node version, same yarn version) I get Error: Cannot find module 'autoprefixer'. That is because one level up there is a postcss.config.js file that expects autoprefixer. Adding the postcss.config.js file with module.exports = {} in it did fix it.

Since it seems that nesting docusaurus inside of a directory of an active project is fairly common practice, perhaps docusaurus can try to pre-emptively solve these issues by scanning the parent directory for these common config files and if they exist, create dummy ones?

peiseng commented 1 year ago

Hi, is there any update on this feature?

peiseng commented 1 year ago

I think I found the solution.

According to postcss-loader documentation, we can specify the format in:

["package_name", { parameter_key: "parameter_value" }]

where parameter_key and parameter_value are config and "path/to/tailwindcss.config.json" respectively by referencing to tailwindcss documentation.

Thus, the final code should be:

plugins: [
      async function myPlugin(context, options) {
        return {
          name: "docusaurus-tailwindcss",
          configurePostCss(postcssOptions) {
            // Appends TailwindCSS and AutoPrefixer.
            postcssOptions.plugins.push(['tailwindcss', {config: "apps/{project_name}/taildwind.config.js"}]);
            postcssOptions.plugins.push(require("autoprefixer"));
            return postcssOptions;
          },
        };
      },
    ],
martygo commented 1 year ago

I fix this issue, only install and config tailwindCss, how @Josh-Cena said.