简体   繁体   English

Tailwind CSS 类在初始构建 React 应用程序后未更新

[英]Tailwind CSS classes not updating after initial build of react app

I decided to bite the bullet today and upgrade from tailwind v2 to v3 for my react app.我今天决定咬紧牙关,将我的 React 应用程序从 tailwind v2 升级到 v3。 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.升级很顺利,但我现在遇到一个问题,在我运行“npm start”后,在重新编译应用程序时,在开发中添加额外的 tailwind css 类不会被拾取,我知道这是 JIIT 引擎的工作。

I expected tailwind to detect changes and add/remove the desired classes.我希望 tailwind 能够检测到变化并添加/删除所需的类。 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.我尝试将基础 class 从“basis-1/2”更改为“basis-3/4”,但由于我没有在初始构建中包含 class“basis-2/5”,类名出现在 div 之后热重载,但样式表中未加载 class。

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我知道这是顺风特有的问题,因为我使用 chrome 工具进行了调查,并且类名已添加到 div,但该值不在重新编译的样式表中:目标 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.我认为解决方案可能是在开发中包括所有 css 类,并在生产中清除一次,但从研究来看,我认为顺风 css 包已经变得太大而无法在开发中完全加载。

I have also tried matching different file paths in the content array in the tailwind.config.js file but that hasn't helped either.我还尝试在 tailwind.config.js 文件的内容数组中匹配不同的文件路径,但这也没有帮助。

Any help or advice on this is really apricated and happy to try people's suggestions out.任何关于此的帮助或建议都非常有用,并且很乐意尝试人们的建议。

files of interest:感兴趣的文件:

Package.json 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 tailwind.config.js

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

index.js索引.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 postcss.config文件

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

assets/tailwind.css资产/tailwind.css

@import 'tailwindcss/base';

@import 'tailwindcss/components';

@import 'tailwindcss/utilities';

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.在创建一个新的 React 应用程序并并排比较应用程序后,我发现了问题,如果有人遇到类似的问题,我建议您也这样做。

When I was using tailwind V2, I did not have a tailwind config.当我使用顺风 V2 时,我没有顺风配置。 With the upgrade to V3 I ran the command npx tailwindcss init .随着升级到 V3,我运行了命令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.问题是我在 src 文件夹中运行它,所以在上面的顺风配置中,内容匹配路径将不起作用,因为它正在寻找 src 文件夹中已经存在的 src 文件夹。

A second problem pointed out thanks to EdLucas in the comments is postCSS configs are no longer supported.感谢 EdLucas 在评论中指出的第二个问题是不再支持 postCSS 配置。 Even with the change above, if a postCSS file is present it won't work.即使进行了上述更改,如果存在 postCSS 文件,它也将无法工作。 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.对于想知道上面 package.json 中的 tailwindCSS、postCSS 和 autoprefixer 版本的人来说,这是我在工作解决方案中使用的正确版本。

I have had a similar problem and solved it by tweaking the watchers in my gulpfile.我有一个类似的问题,并通过调整我的 gulpfile 中的观察者来解决它。

In my gulpfile, the line that configured the watcher for my Handlebars template looked like this:在我的 gulpfile 中,为我的 Handlebars 模板配置观察程序的行如下所示:

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

This would execute the HBS task when a change is made to my front end code.当我的前端代码发生更改时,这将执行 HBS 任务。 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.但是,它没有执行 CSS 任务,这意味着我在其中导入 Tailwind 的 CSS 文件未正确重新处理。

I solved it by adding the CSS task into the callback of the HBS watcher:我通过将 CSS 任务添加到 HBS 观察者的回调中来解决它:

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

I have been trying to figure out a similar problem for.... HOURS.我一直试图找出一个类似的问题......小时。

Finally, I discovered that the auto-reloading for tailwind classes in JSX only works if the className is a javascript expression, not a JSX attribute constant.最后,我发现 JSX 中顺风类的自动重新加载仅在className是 javascript 表达式而不是 JSX 属性常量时才有效。

So,所以,

<>
    // bad
    <div className="p-5">Won't reload when the className changes</div>

    // good
    <div className={"p-5"}>Will reload when the className changes</div>
</>

I haven't seen this in any documentation, but maybe I missed something.我没有在任何文档中看到这一点,但也许我错过了一些东西。

I found a problem crops up when a react component has some dynamic content and/ or className(s).当 React 组件具有一些动态内容和/或类名时,我发现会出现问题。 Basically neither the build nor start scripts (that come with create-react-app) will include these tailwind classes in the final generated CSS file.基本上,构建脚本和启动脚本(随 create-react-app 一起提供)都不会在最终生成的 CSS 文件中包含这些顺风类。 (Because the basic idea is to minimize the size of the CSS file and not to include unnecessary tailwind CSS classes ie classes that are not explicitly mentioned .) (因为基本思想是最小化 CSS 文件的大小,并且不包括不必要的 tailwind CSS 类,即未明确提及的类。)

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.所以我的解决方案是创建一个Helper.js组件,当我在其他组件中动态生成它们时,它会明确提及我需要的所有顺风类。

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.我没有在应用程序中使用Helper.js组件,也没有从中导入任何内容,但这个文件只是位于src目录中,因此其中提到的 tailwind 类包含在 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: Tailwind state 在https://tailwindcss.com/docs/guides/create-react-app的官方 v3.2.4(写作时)文档中:

Create React App does not support custom PostCSS configurations and is incompatible with many important tools in the PostCSS ecosystem, like postcss-import . Create React App 不支持自定义 PostCSS 配置,并且与 PostCSS 生态系统中的许多重要工具不兼容,例如postcss-import

We highly recommend using Vite, Parcel, Next.js, or Remix instead of Create React App.我们强烈建议使用 Vite、Parcel、Next.js 或 Remix,而不是 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.它们提供同等或更好的开发人员体验,但具有更大的灵活性,让您可以更好地控制 Tailwind 和 PostCSS 的配置方式。

It took me a while to figure that one out.我花了一段时间才弄明白。 Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM