4

I decided to bite the bullet today and upgrade from tailwind v2 to v3 for my react app. The upgrade went well, but I now have a problem where after I run "npm start", adding additional tailwind css classes in development are not picked up when the app is recompiled which I understand is the job of the JIIT engine.

I expected tailwind to detect changes and add/remove the desired classes. I tried changing the basis class from "basis-1/2" to "basis-3/4" but since I had not included the class "basis-2/5" in the initial build, the classname was present on the div after a hot reload but the class wasnt loaded in the stylesheet.

I know this is a tailwind specific issue as I investigated using chrome tools and the classname was added to the div but the value was not in the recomplied stylesheet: target css class

I thought the solution might be including all css classes while in development and purging them once in production but from researching, I think the tailwind css bundles have become too large to be fully loaded in development.

I have also tried matching different file paths in the content array in the tailwind.config.js file but that hasn't helped either.

Any help or advice on this is really apricated and happy to try people's suggestions out.

files of interest:

Package.json

{
  "name": "personalreactapp",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000/",
  "dependencies": {
    "@emotion/react": "^11.6.0",
    "@emotion/styled": "^11.6.0",
    "@headlessui/react": "^1.4.2",
    "@heroicons/react": "^1.0.5",
    "@mui/icons-material": "^5.1.1",
    "@mui/material": "^5.1.0",
    "@mui/styles": "^5.1.0",
    "@tailwindcss/forms": "^0.4.0",
    "@types/js-cookie": "^3.0.1",
    "axios": "^0.21.4",
    "formik": "^2.2.9",
    "highcharts": "^9.1.1",
    "highcharts-react-official": "^3.0.0",
    "history": "^5.2.0",
    "jquery": "^3.6.0",
    "js-cookie": "^3.0.1",
    "merge": "^1.2.1",
    "oidc-client": "^1.9.0",
    "query-string": "^7.1.1",
    "react": "^17.0.2",
    "react-dom": "^16.0.0",
    "react-hot-toast": "^2.2.0",
    "react-loader-spinner": "^4.0.0",
    "react-redux": "^7.2.6",
    "react-router": "^6.2.1",
    "react-router-bootstrap": "^0.25.0",
    "react-router-dom": "^6.0.2",
    "react-scripts": "5.0.0",
    "react-toastify": "^8.1.0",
    "reactstrap": "^8.4.1",
    "redux-devtools-extension": "^2.13.9",
    "redux-logger": "^3.0.6",
    "redux-persist": "^6.0.0",
    "redux-thunk": "^2.3.0",
    "reselect": "^4.1.2",
    "rimraf": "^2.6.2",
    "styled-components": "^4.3.2",
    "watch": "^1.0.2",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@tailwindcss/postcss7-compat": "^2.2.17",
    "ajv": "^6.9.1",
    "autoprefixer": "^10.4.2",
    "babel-eslint": "^10.1.0",
    "cross-env": "^5.2.0",
    "eslint": "^6.8.0",
    "eslint-config-airbnb": "^19.0.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-react-app": "^5.2.0",
    "eslint-plugin-flowtype": "^4.6.0",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-only-warn": "^1.0.3",
    "eslint-plugin-react": "^7.27.0",
    "nan": "^2.14.1",
    "postcss": "^8.4.6",
    "postcss-cli": "^9.0.2",
    "prettier": "^2.4.1",
    "pretty-quick": "^3.1.1",
    "tailwindcss": "^3.0.23",
    "typescript": "^3.9.10"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "scripts": {
    "start": "rimraf ./build && npm run watch:css && react-scripts start",
    "build": "npm run watch:css && react-scripts build",
    "build:css": "postcss src/assets/tailwind.css -o src/assets/main.css",
    "watch:css": "postcss src/assets/tailwind.css -o src/assets/main.css",
    "test": "cross-env CI=true react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "lint": "eslint ./src/ --max-warnings=0"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

tailwind.config.js

module.exports = {
  content: ['./src/**/*.{js,jsx,ts,tsx}', './src/**/**/*.{js,jsx,ts,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [require('@tailwindcss/forms')],
};

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { Provider } from 'react-redux';
import store from './redux/store';
import { history } from './_helpers/history';
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css';
import './assets/main.css';

const rootElement = document.getElementById('root');

ReactDOM.render(
  <Router history={history}>
    <Provider store={store}>
      <App />
    </Provider>
  </Router>,
  rootElement,
);

registerServiceWorker();

postcss.config

const tailwindcss = require('tailwindcss');
module.exports = {
  plugins: [tailwindcss('./src/tailwind.config.js'), require('autoprefixer')],
};

assets/tailwind.css

@import 'tailwindcss/base';

@import 'tailwindcss/components';

@import 'tailwindcss/utilities';

4
  • Are you using CRA 5? If so, postcss.config flies are not supported. Commented Feb 20, 2022 at 21:51
  • @EdLucas Yea I upgraded react scripts to V5 to get access to postCSS V8. Would you know the alternative to postcss.config files? Commented Feb 20, 2022 at 22:43
  • There's a default postcss setup in CRA5 that includes the autoprefixer: github.com/facebook/create-react-app/blob/… It looks like you still also have Tailwind 2 in your package.json as @tailwindcss/postcss7-compat. Maybe that's confusing things. Commented Feb 20, 2022 at 23:01
  • @EdLucas good spot, I uninstalled @tailwindcss/postcss7-compat but it doesn't seem to be the issue. I commented out the postcss.config file and rebuilt the app and the tailwind css file did not build so I think there is defiantly a dependency on that postcss.config which could be the issue Commented Feb 20, 2022 at 23:19

3 Answers 3

3

After creating a new react app and comparing the apps side by side I found the problem, if anyone is having a similar problem I would recommend doing the same.

When I was using tailwind V2, I did not have a tailwind config. With the upgrade to V3 I ran the command npx tailwindcss init. The problem was I ran it inside the src folder so in the tailwind config above, the content matching paths will not work as its looking for the src folder already inside the src folder.

A second problem pointed out thanks to EdLucas in the comments is postCSS configs are no longer supported. Even with the change above, if a postCSS file is present it won't work. Deleting that file will fix the issue.

For anyone wondering the versions for tailwindCSS, postCSS and autoprefixer in package.json above are the correct versions that I used in the working solution.

Sign up to request clarification or add additional context in comments.

Comments

2

I have had a similar problem and solved it by tweaking the watchers in my gulpfile.

In my gulpfile, the line that configured the watcher for my Handlebars template looked like this:

const hbsWatcher = () => watch(['*.hbs', 'partials/**/*.hbs'], hbs);

This would execute the HBS task when a change is made to my front end code. However, it did not execute the CSS task, which meant that my CSS file in which I was importing Tailwind was not re-processed properly.

I solved it by adding the CSS task into the callback of the HBS watcher:

const hbsWatcher = () => watch(['*.hbs', 'partials/**/*.hbs'], series(hbs, css));

Comments

1

I found a problem crops up when a react component has some dynamic content and/ or className(s). Basically neither the build nor start scripts (that come with create-react-app) will include these tailwind classes in the final generated CSS file. (Because the basic idea is to minimize the size of the CSS file and not to include unnecessary tailwind CSS classes i.e. classes that are not explicitly mentioned.)

So my solution was to create a Helper.js component that explicitly mentions all the tailwind classes that I need when I generate them dynamically in other components.

I do not use the Helper.js component in the application nor import anything from it but this file just sits in the src directory so that the tailwind classes mentioned in it get included in the css.

Tailwind state in the official v3.2.4 (at the time of writitng) documentation at https://tailwindcss.com/docs/guides/create-react-app that:

Create React App does not support custom PostCSS configurations and is incompatible with many important tools in the PostCSS ecosystem, like postcss-import.

We highly recommend using Vite, Parcel, Next.js, or Remix instead of Create React App. They provide an equivalent or better developer experience but with more flexibility, giving you more control over how Tailwind and PostCSS are configured.

It took me a while to figure that one out. Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.