Alguém conseguiu executar com sucesso o TailwindCSS 4 com Sass no aplicativo Webpack 5 e React?
Estou tendo alguns problemas de configuração em que não recebo nenhum erro de console, mas o processamento CSS parece estar em conflito no meu aplicativo a ponto de atrapalhar o roteamento.
Toda vez que vou para uma URL diferente, o aplicativo trava. Às vezes, se eu recarregar a página, ele pode renderizar todo o conteúdo. Mas, ao navegar para fora, o mesmo problema acontece: o aplicativo trava e diz "Desculpe, esta página não existe".
É bom ressaltar que esse problema começou a acontecer depois de introduzir o TailwindCSS 4 no aplicativo. O aplicativo nunca usou o Tailwind antes, apenas uma combinação de Material UI React + Reactstrap. Os estilos parecem se aplicar ao atualizar a página atual.
pacote.json
{
"name": "my-app",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node server.js",
"build-manager": "NODE_ENV=production APP_ENV=$npm_config_app_env node --max-old-space-size=13500 ./node_modules/webpack/bin/webpack.js --config ./apps/manager/webpack.prod.js",
"server": "node server.js",
"test": "jest --watch",
"cypress": "npx cypress open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.25.8",
"@babel/preset-env": "^7.25.8",
"@babel/preset-typescript": "^7.25.7",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.13.0",
"@sentry/webpack-plugin": "^2.22.6",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^15.0.7",
"@testing-library/user-event": "^14.5.2",
"@types/react": "~18.2.0",
"@types/react-dom": "~18.2.0",
"@types/react-redux": "^7.1.34",
"autoprefixer": "^10.4.21",
"babel-loader": "^9.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^12.0.2",
"css-loader": "^7.1.2",
"cypress": "^13.15.0",
"cypress-mailisk": "^2.0.1",
"eslint": "^9.13.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-simple-import-sort": "^7.0.0",
"express": "^4.21.1",
"globals": "^15.11.0",
"html-webpack-plugin": "^5.6.2",
"husky": "^9.1.6",
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^15.2.10",
"prettier": "^3.3.3",
"redoc-cli": "^0.13.16",
"sass": "^1.79.5",
"sass-loader": "^16.0.2",
"semantic-ui-react": "^2.1.5",
"style-loader": "^4.0.0",
"svg-inline-loader": "^0.8.2",
"svg-url-loader": "^8.0.0",
"terser-webpack-plugin": "^5.3.10",
"webpack": "^5.95.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^5.1.4",
"webpack-dev-middleware": "^7.4.2",
"webpack-dev-server": "^5.1.0",
"webpack-hot-middleware": "^2.26.1",
"webpack-manifest-plugin": "^5.0.0",
"webpack-merge": "^6.0.1"
},
"dependencies": {
"@babel/eslint-parser": "^7.25.9",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/runtime": "^7.25.7",
"@babel/runtime-corejs2": "^7.25.7",
"@devexpress/dx-react-core": "^4.0.8",
"@devexpress/dx-react-scheduler": "^4.0.8",
"@devexpress/dx-react-scheduler-material-ui": "^4.0.8",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@floating-ui/react": "^0.27.0",
"@gsap/react": "^2.1.1",
"@hello-pangea/dnd": "^16.6.0",
"@mui/icons-material": "^5.15.15",
"@mui/lab": "^5.0.0-alpha.117",
"@mui/material": "^5.15.15",
"@mui/x-date-pickers": "^5.0.15",
"@reduxjs/toolkit": "^2.3.0",
"@sentry/react": "^8.37.1",
"@tailwindcss/postcss": "^4.0.17",
"@tanstack/react-query": "^5.59.15",
"@tanstack/react-query-devtools": "^5.59.15",
"@tanstack/react-virtual": "^3.10.8",
"@tiptap/extension-placeholder": "^2.8.0",
"@tiptap/pm": "^2.8.0",
"@tiptap/react": "^2.8.0",
"@tiptap/starter-kit": "^2.8.0",
"@uidotdev/usehooks": "^2.4.1",
"ace-builds": "^1.36.2",
"ag-grid-community": "^33.0.3",
"ag-grid-enterprise": "^33.0.3",
"ag-grid-react": "^33.0.3",
"array-move": "^2.2.0",
"axios": "^1.7.7",
"big.js": "^6.2.2",
"bootstrap": "^4.6.0",
"chart.js": "^4.4.5",
"classnames": "^2.5.1",
"crypto-browserify": "^3.12.0",
"crypto-es": "^2.1.0",
"debounce-promise": "^3.1.2",
"dompurify": "^3.1.7",
"dotenv-webpack": "^8.1.0",
"formik": "^2.4.6",
"fslightbox-react": "^1.7.6",
"gsap": "^3.12.5",
"html-react-parser": "^5.1.18",
"immutability-helper": "^3.1.1",
"invariant": "^2.2.4",
"jsoncrush": "^1.1.6",
"large-small-dynamic-viewport-units-polyfill": "^0.1.1",
"libphonenumber-js": "^1.11.11",
"lodash.clonedeep": "^4.5.0",
"lodash.flattendeep": "^4.4.0",
"lodash.isequal": "^4.5.0",
"lodash.topath": "^4.5.2",
"mapbox-gl": "^3.7.0",
"microsoft-cognitiveservices-speech-sdk": "^1.41.0",
"mini-css-extract-plugin": "^2.9.2",
"moment": "^2.30.1",
"moment-timezone": "^0.5.23",
"mui-image": "^1.0.7",
"mui-nested-menu": "^3.4.0",
"natural-orderby": "^2.0.3",
"npm": "^10.9.0",
"postcss": "^8.5.3",
"postcss-loader": "^8.1.1",
"postcss-preset-env": "^10.1.5",
"promise-polyfill": "8.3.0",
"promise.allsettled": "^1.0.7",
"query-string": "^9.1.1",
"react": "~18.2.0",
"react-ace": "^12.0.0",
"react-bottom-scroll-listener": "^5.1.0",
"react-chartjs-2": "^5.2.0",
"react-content-loader": "^7.0.2",
"react-datepicker": "^7.5.0",
"react-dom": "~18.2.0",
"react-draggable": "^4.4.6",
"react-dropzone": "^14.2.9",
"react-froala-wysiwyg": "4.3.0",
"react-google-places-autocomplete": "^4.1.0",
"react-google-recaptcha": "^3.1.0",
"react-grid-layout": "^1.5.0",
"react-intersection-observer": "^9.13.1",
"react-loadable": "^5.5.0",
"react-map-gl": "^7.1.7",
"react-markdown": "^9.0.3",
"react-moment": "^1.1.3",
"react-number-format": "^5.4.2",
"react-payment-inputs": "^1.2.0",
"react-pdf": "^9.1.1",
"react-phone-number-input": "^3.4.8",
"react-plaid-link": "^3.6.0",
"react-qr-code": "^2.0.15",
"react-quill": "^2.0.0",
"react-redux": "^9.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "^5.0.1",
"react-select": "^5.8.1",
"react-speech-recognition": "^3.10.0",
"react-spinners": "^0.15.0",
"react-toastify": "^10.0.6",
"react-toggle": "^4.0.2",
"react-virtuoso": "^4.12.0",
"react-zoom-pan-pinch": "^3.6.1",
"reactstrap": "^8.10.1",
"redux": "^5.0.1",
"redux-first-history": "^5.2.0",
"redux-thunk": "^3.1.0",
"regenerator-runtime": "^0.14.1",
"stream-browserify": "^3.0.0",
"styled-components": "^6.1.13",
"tailwindcss": "^4.0.17",
"textarea-caret": "^3.1.0",
"web-speech-cognitive-services": "^7.1.3",
"yup": "^1.4.0"
}
}
postcss.config.js
module.exports = {
plugins: {
'@tailwindcss/postcss': {}
}
};
vento de cauda.css
@import '@rentvine/trellis/variables';
@import 'tailwindcss';
@import '@rentvine/trellis/config';
webpack.common.js
const path = require('path');
const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const Dotenv = require('dotenv-webpack');
const { getAppConfig } = require('./../../rv-build-config');
const appConfig = getAppConfig('manager', process.env.APP_ENV);
module.exports = {
devtool: 'source-map',
entry: {
app: path.resolve(__dirname, './src/index.js')
},
output: {
filename: '[name].bundle.[fullhash].js',
chunkFilename: '[name].bundle.[fullhash].js',
path: path.resolve(__dirname, './../../bin/manager-app'),
publicPath: '/'
},
resolve: {
alias: {
'~': path.resolve(__dirname, 'src'),
Lib: path.resolve(__dirname, '../../lib/node/src'),
ROOT: path.resolve(__dirname, '../../')
},
modules: ['../node_modules/froala-editor/js', 'node_modules'],
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify')
},
extensions: ['.ts', '.js'],
symlinks: false
},
plugins: [
// Load shared environment variables (stored in .env)
new Dotenv(),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Rentvine',
template: path.resolve(__dirname, './src/index.html')
}),
new WebpackManifestPlugin(),
new webpack.DefinePlugin({
...appConfig,
'process.env.PORTAL_TYPE_ID': JSON.stringify(1),
'process.env.API_ROOT': JSON.stringify('/api/manager/'),
'process.env.LOGIN_URL': JSON.stringify('session_manager_LoginUrl')
}),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, './src/assets'),
to: 'assets'
},
{
// move main favicon to root so non-html documents show it ( pdf, img, etc)
from: path.resolve(__dirname, './src/assets/favicon/favicon.ico'),
to: 'favicon.ico'
}
]
}),
new webpack.ProvidePlugin({
FroalaEditor: 'file_name'
}),
new CaseSensitivePathsPlugin()
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, './../../lib/node/src')],
use: 'babel-loader'
},
{
test: /\.ts?/,
exclude: /node_modules/,
include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, './../../lib/node/src')],
use: 'babel-loader'
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
include: path.resolve(__dirname, 'src'),
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.scss$/,
use: [
'style-loader', // creates style nodes from JS strings
{ loader: 'css-loader', options: { url: false } }, // translates CSS into CommonJS
{
// compiles Sass to CSS
loader: 'sass-loader',
options: {
sassOptions: {
// TODO: these should only be temporary until we have time to fix issues
quietDeps: true,
silenceDeprecations: ['color-functions', 'global-builtin', 'import']
}
}
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
type: 'asset/resource'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
type: 'asset/resource'
},
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
mimetype: 'application/font-woff',
type: 'asset'
},
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
mimetype: 'application/font-woff',
type: 'asset'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
mimetype: 'application/octet-stream',
type: 'asset'
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
type: 'asset/resource'
}
]
}
};
TailwindCSS v4 não suporta mais pré-processadores Sass, Less e Stylus. Você está usando Sass, e é por isso que ele não está funcionando.
Você pode usar o TailwindCSS v3 com uma instalação específica da versão ou remover o Sass.
Obsoleto: suporte a pré-processadores
Para mais detalhes:
tailwindlabs/tailwindcss
#15716 por Robin Malfait:A ferramenta de migração não reconhece arquivos .scss - GitHub
tailwindlabs/tailwindcss
#16793 por Philipp Spiess:TailwindCSS v4 por que ignora arquivos .scss - GitHub