gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.22k stars 10.33k forks source link

Gatsby 4 + Tailwind with CSS Modules #33688

Closed stevensacks closed 2 years ago

stevensacks commented 2 years ago

Preliminary Checks

Description

Gatsby 4 has a bug with Tailwind and css modules. This did not happen in Gatsby 3.

If you write a custom class in your tailwind.css and then try to reference it in a *.modules.css file in a component, Gatsby 4 crashes during the build process.

You can reproduce it in the minimal test repo I have created.

Here's the error output:

⠇ Building development bundle
<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/Users/steven/Development/gatsby-tailwind-issue/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[9].oneOf[0].use[0]!/Users/steven/Development/gatsby-tailwind-issue/node_modules/gatsby-plugin-postcss/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[9].oneOf[0].use[1]!/Users/steven/Development/gatsby-tailwind-issue/src/pages/styles.module.css': No serializer registered for SyntaxError

 ERROR 

Module build failed (from ./node_modules/gatsby-plugin-postcss/node_modules/postcss-loader/dist/cjs.js):
SyntaxError

(2:5) /Users/steven/Development/gatsby-tailwind-issue/src/pages/styles.module.css The `base-title` class does not exist. If `base-title` is a custom class, make sure it is defined within a `@layer` directive.

  1 | .title {
> 2 |     @apply base-title;
    |     ^
  3 | 
  4 |     text-shadow: 1px 1px 2px green;

  ModuleBuildError: Module build failed (from ./node_modules/gatsby-plugin-postcss/node_modules/postcss-loader/dist/cjs.js):
  SyntaxError
  (2:5) /Users/steven/Development/gatsby-tailwind-issue/src/pages/styles.module.css The `base-title` class does not exist. If `base-title` is a custom class, make sure it is defined within a `@layer` directive.
    1 | .title {
  > 2 |     @apply base-title;
      |     ^
    3 | 
    4 |     text-shadow: 1px 1px 2px green;

  - NormalModule.js:748 processResult
    [gatsby-tailwind-issue]/[webpack]/lib/NormalModule.js:748:19

  - NormalModule.js:850 
    [gatsby-tailwind-issue]/[webpack]/lib/NormalModule.js:850:5

  - LoaderRunner.js:399 
    [gatsby-tailwind-issue]/[loader-runner]/lib/LoaderRunner.js:399:11

  - LoaderRunner.js:251 
    [gatsby-tailwind-issue]/[loader-runner]/lib/LoaderRunner.js:251:18

  - LoaderRunner.js:124 context.callback
    [gatsby-tailwind-issue]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:102 Object.loader
    [gatsby-tailwind-issue]/[gatsby-plugin-postcss]/[postcss-loader]/dist/index.js:102:7

Reproduction Link

https://github.com/sklawren/gatsby-tailwind-issue

Steps to Reproduce

  1. Write a custom class in tailwind.css
  2. apply that custom class in a *.module.css file
  3. run Gatsby 4

Expected Result

That it compiles correctly

Actual Result

Crashes Gatsby

Environment

System:
    OS: macOS 11.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.18.0 - ~/.nvm/versions/node/v14.18.0/bin/node
    Yarn: 1.22.15 - /usr/local/bin/yarn
    npm: 6.14.15 - ~/.nvm/versions/node/v14.18.0/bin/npm
  Languages:
    Python: 3.9.7 - /usr/local/opt/python3/libexec/bin/python
  Browsers:
    Chrome: 95.0.4638.54
    Firefox: 93.0
    Safari: 15.0
  npmPackages:
    gatsby: ^4.0.1 => 4.0.1 
    gatsby-cli: ^4.0.0 => 4.0.0 
    gatsby-plugin-postcss: ^5.0.0 => 5.0.0

Config Flags

No flags

DennisKraaijeveld commented 2 years ago

Forked and tried to use my setup. I am using Gatsby V4 and Tailwind, but I am using SCSS in combination with some module.scss files and everything works like expected. I can apply the custom classes directly inside of my .jsx files and also use them in my module.scss file.

So I forked this project and start to use scss instead of css. All the custom classes started to work directly inside of the .jsx files, so maybe that is some helpful information. The only thing I did not get to work, in contrast to my project, is using those classes inside the .module.scss file. Maybe this has something to do with an extra plugin I am using. My package.json:

"dependencies": {
    "@fontsource/montserrat": "^4.5.1",
    "@headlessui/react": "^1.4.0",
    "@heroicons/react": "^1.0.4",
    "@loadable/component": "^5.15.0",
    "@loadable/server": "^5.15.1",
    "@loadable/webpack-plugin": "^5.15.1",
    "@reach/rect": "^0.16.0",
    "@sendgrid/mail": "^7.4.7",
    "@shopify/shopify-api": "^1.4.1",
    "@sindresorhus/slugify": "^2.1.0",
    "@tailwindcss/aspect-ratio": "^0.3.0",
    "@tailwindcss/forms": "^0.3.3",
    "@tailwindcss/typography": "^0.4.1",
    "debounce": "^1.2.1",
    "embla-carousel-react": "^5.0.1",
    "focus-trap-react": "^8.8.2",
    "framer-motion": "^4.1.17",
    "gatsby": "^4.0.0",
    "gatsby-plugin-anchor-links": "^1.2.1",
    "gatsby-plugin-chatwoot": "^1.1.0",
    "gatsby-plugin-gatsby-cloud": "^4.0.0",
    "gatsby-plugin-gdpr-cookies": "^2.0.6",
    "gatsby-plugin-google-analytics": "^4.0.0",
    "gatsby-plugin-image": "^2.0.0",
    "gatsby-plugin-loadable-components-ssr": "^3.4.0",
    "gatsby-plugin-lodash": "^5.0.0",
    "gatsby-plugin-manifest": "^4.0.0",
    "gatsby-plugin-page-progress": "^2.2.1",
    "gatsby-plugin-preconnect": "^1.2.1",
    "gatsby-plugin-react-helmet": "^5.0.0",
    "gatsby-plugin-react-helmet-canonical-urls": "^1.4.0",
    "gatsby-plugin-remove-serviceworker": "^1.0.0",
    "gatsby-plugin-robots-txt": "^1.6.10",
    "gatsby-plugin-sass": "^5.0.0",
    "gatsby-plugin-sharp": "^4.0.0",
    "gatsby-plugin-sitemap": "^5.0.0",
    "gatsby-source-filesystem": "^4.0.0",
    "gatsby-source-prismic": "^5.0.0",
    "gatsby-source-shopify": "^6.0.0",
    "gatsby-transformer-sharp": "^4.0.0",
    "isomorphic-fetch": "^3.0.0",
    "js-cookie": "^3.0.1",
    "lodash": "^4.17.21",
    "prismic-dom": "^2.2.6",
    "prismic-reactjs": "^1.3.4",
    "query-string": "^7.0.1",
    "rc-slider": "^9.7.2",
    "react": "^17.0.2",
    "react-cookie-consent": "^6.3.0",
    "react-dom": "^17.0.2",
    "react-helmet": "^6.1.0",
    "react-hook-form": "^7.16.1",
    "react-hook-recaptcha": "^1.0.4",
    "react-icons": "^4.2.0",
    "react-keyed-flatten-children": "^1.3.0",
    "sass": "^1.36.0",
    "shopify-buy": "^2.11.0",
    "slugify": "^1.6.0",
    "swr": "^1.0.1",
    "unfetch": "^4.2.0",
    "urql": "^2.0.4"
  },
  "devDependencies": {
    "@iconify/icons-ion": "^1.1.2",
    "@iconify/react": "^3.0.1",
    "@loadable/babel-plugin": "^5.13.2",
    "autoprefixer": "^10.3.1",
    "babel-preset-gatsby": "^2.0.0",
    "gatsby-plugin-perf-budgets": "^0.0.18",
    "gatsby-plugin-postcss": "^5.0.0",
    "gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.25",
    "postcss": "^8.3.6",
    "postcss-import": "^14.0.2",
    "stylelint": "^14.0.0",
    "stylelint-config-recommended-scss": "^5.0.0",
    "stylelint-order": "^5.0.0",
    "stylelint-scss": "^4.0.0",
    "tailwindcss": "^2.2.7"
  }
stevensacks commented 2 years ago

The other closed issue was unrelated to this one.

stevensacks commented 2 years ago

This issue does not occur with Gatsby 2 or 3, it does not occur with Storybook in the same project (which is using Webpack 5 and PostCSS 8).

It’s something specific with Gatsby 4 and PostCSS or CSS Modules.

stevensacks commented 2 years ago

Hi, it's been about a month so I'm checking in to see how this is going since I'm still blocked from upgrading to Gatsby 4.

LekoArts commented 2 years ago

Hi!

With Adam's comment (https://github.com/tailwindlabs/tailwindcss/issues/5989#issuecomment-1002297586) in mind and the given documentation here (https://tailwindcss.com/docs/functions-and-directives#using-apply-with-per-component-css) I'll close this. I have to agree, that we wouldn't want to make the changes that would enable this use case. I can't pinpoint the exact update we did that would have changed this behavior, probably a dependency update or a change in our webpack config -- anyway, I think the last paragraph in the docs is a good advice:

Honestly though the best solution is to just not do weird stuff like this at all. Use Tailwind’s utilities directly in your markup the way they are intended to be used, and don’t abuse the @apply feature to do things like this and you will have a much better experience.