React/Tailwindcss modules name obfuscation breaks postcss nesting - reactjs

So after extensive research I am here, I have a difficult to search problem which I'm hoping can be solved.
I've booted up a new project with Vite/ReactJS/Tailwindcss and I'm trying to use postcss to create nested CSS rules, they seem to be partially working but when using the ampersand (as in SCSS) things get a bit weird.
I have a bog standard Button React component with the following Button.module.css:
.Button {
#apply bg-primary;
&--disabled {
#apply opacity-50;
}
}
Styles are applied like so:
import styles from './Button.module.css';
const Button = ({ label, disabled }) => {
return (
<button type="button" className={[
styles.Button,
disabled ? 'Button--disabled' : ''
]}>
{label}
</button>
);
};
export default Button;
postcss.config.cjs:
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},
}
However in the browser the button looks like, note the obfuscated classes:
<button type="button" class="Button _Button_1fcg7_1 Button--disabled">Button</button>
While the (successfully, I note) compiled CSS looks like:
._Button_1fcg7_1 {
--tw-bg-opacity: 1;
background-color: rgb(29 161 242 / var(--tw-bg-opacity))
}
._Button--disabled_1fcg7_1 {
opacity: 0.5
}
Because the class name in the HTML compiles to .Button--disabled and the CSS selector gets obfuscated to ._Button--disabled_1fcg7_1, the styles are never applied. What gives?
Some further info as requested, package.json:
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"dependencies": {
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.3.0",
"postcss-nesting": "^10.1.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.53.0"
},
"devDependencies": {
"#babel/core": "^7.18.6",
"#storybook/addon-actions": "^6.5.9",
"#storybook/addon-essentials": "^6.5.9",
"#storybook/addon-interactions": "^6.5.9",
"#storybook/addon-links": "^6.5.9",
"#storybook/builder-vite": "^0.2.0",
"#storybook/react": "^6.5.9",
"#storybook/testing-library": "^0.0.13",
"#types/react": "^18.0.15",
"#types/react-dom": "^18.0.6",
"#vitejs/plugin-react": "^2.0.0",
"autoprefixer": "^10.4.7",
"babel-loader": "^8.2.5",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.6",
"typescript": "^4.6.4",
"vite": "^3.0.0"
}
}
vite.config.ts:
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
tailwind.config.cjs:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
colors: {
primary: '#1da1f2',
},
}
},
plugins: [],
}

It's funny because different people with similar setups have the opposite problem.
Is there a way to obfuscate TailwindCSS classnames using PostCSS for React project in Vitejs?
I think that your problem comes from another place.
Can you share your package.json, tailwind.config.js, vite.config.js and rollup.config.js (if you have this last file) ?
Maybe you have some settings or packages configured related to obfuscation.
I don't know the vite ecosystem, but there are some packages that generate the behavior you want to avoid:
vite-plugin-tailwind-ofuscar
rollup-plugin-postcss

Related

SVG Next Error You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file

I have an issue with my app, everything was working fine until i ran npm run audit fix force then when i ran my app after this i am getting the error message below related to svg file.
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
i don't understand what went wrong.
Can someone help me, please?
package.json
{
"name": "myskillreactapp",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"#babel/preset-env": "^7.15.8",
"bootstrap": "^5.0.0-beta3",
"bootstrap-dark-5": "^1.1.3",
"font-awesome": "^4.7.0",
"next": "^10.0.4",
"next-images": "^1.8.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-icons": "^4.3.1",
"react-placeholder": "^4.1.0"
},
"devDependencies": {
"babel-plugin-inline-react-svg": "^2.0.1",
"eslint": "7.32.0",
"eslint-config-next": "^0.2.4",
"file-loader": "^6.2.0",
"sass": "^1.43.3"
}
}
next-config.js
const webpack = require('webpack');
module.exports = {
reactStrictMode: true,
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[hash]-[name].[ext]',
},
},
],
},
],
},
//...
};
_app.js
//import 'bootstrap/dist/css/bootstrap.css';
//import '/node_modules/bootstrap/scss/bootstrap.scss';
import '../styles/globals.scss';
import '../styles/Home.module.scss';
import 'font-awesome/css/font-awesome.min.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
The got solved by running npm run audit fix force again and it reverted back to normal. hope it helps someone. Thx
Leo

How to Use React Suite with tailwind css in Next.js?

Description
I want to use React Suite and tailwind so I install tailwind following the installation instructions from the documentation
and it's working fine, but when I install React Suite and add some configuration in the next.config.js file tailwind is no longer working, and React Suite workers well, I think the problem is with this file
I hope you can help me with this problem
Code
the example in code sandbox
_app.js
import React, { useEffect } from 'react'
import 'rsuite/styles/index.less'
import 'assets/styles/globals.css'
import { Provider } from 'react-redux'
import { useStore } from 'redux/store/index'
import { LANGUAGE } from 'redux/store/actionTypes'
function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
}
export default MyApp
tailwind.config
module.exports = {
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
prefix: 'tw-',
}
postcss.config
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
globals.css
#tailwind base;
#tailwind components;
#tailwind utilities;
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans,
Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
next.config.js
I think the problem is here
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
reactStrictMode: true,
webpack(config) {
config.module.rules.push({
test: /\.(le|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
},
{
loader: 'less-loader',
options: {
sourceMap: true,
lessOptions: {
javascriptEnabled: true,
},
},
},
],
})
config.plugins.push(
new MiniCssExtractPlugin({
filename: 'static/css/[name].css',
chunkFilename: 'static/css/[contenthash].css',
}),
)
return config
},
}
package.json
{
"name": "next-starter-code",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"dependencies": {
"axios": "^0.21.4",
"i18next": "^21.2.0",
"next": "11.1.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-i18next": "^11.12.0",
"react-redux": "^7.2.5",
"redux": "^4.1.1",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.3.0",
"rsuite": "^5.0.0",
"sass": "^1.42.1"
},
"devDependencies": {
"autoprefixer": "^10.3.6",
"babel-eslint": "^10.1.0",
"css-loader": "^6.3.0",
"dotenv": "^10.0.0",
"env-cmd": "^10.1.0",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-next": "11.1.2",
"eslint-config-prettier": "^8.3.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^6.1.0",
"eslint-plugin-i18next": "^5.1.2",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^7.0.2",
"less": "^4.1.2",
"less-loader": "^10.0.1",
"lint-staged": "^11.1.2",
"mini-css-extract-plugin": "^2.3.0",
"postcss": "^8.3.8",
"prettier": "^2.4.1",
"pretty-quick": "^3.1.1",
"tailwindcss": "^2.2.16",
"webpack": "^5.57.1"
}
}
Just change the regex from
test: /\.(le|c)ss$/,
to
test: /\^(?!tailwind.css).(le|c)ss$/,
Doing this will exclude tailwind css file while processing with css-loader or less loader and everything starts working the way it should
There might be some visual defects which can be overriden by writing custom css.
Also to keep tailwind the incharge of the styling your components make sure you import tailwind after the rsuite css in the _app.js (or _app.tsx) as below
import "rsuite/dist/rsuite.min.css";
import "tailwindcss/tailwind.css";
import "../styles/styles.css";
I came across the same issue it seems that when you add the webpack config needed to work with NextJS
test: /\.(le|c)ss$/,
This causes to apply css-loader and less-loader to the css files in tailwind's package. So I tried doing this:
test: /\.less$/,
The above did get rid of the error but then it tailwind stoped working.
Here are my styles with tailwind (without rsuite config)
Tailwind CSS Styling
Here are my styles with tailwind (with my modified config)
RSuite overriding Tailwind
I belive that we might need to have a diffrent webpack config that will take care of both .less in RSuite and .css in Tailwind individualy

Use alt with react in ES6

I'm trying to use alt with React and code an Action in ES6 style:
import alt from '../alt';
class LoginActions {
login() {
alert('oi');
}
}
export default alt.createActions(LoginActions);
My .babelrc is using class transformation plugin:
// without options
{
"plugins": ["transform-class-properties"]
}
My package.json is configured with babel and webpack
{
"name": "npm-yarn-babel-webpack",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"babel-core": "6",
"babel-loader": "7",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^1.0.1",
"node-sass": "^4.10.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.25.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
},
"dependencies": {
"alt": "^0.18.6",
"react": "^16.6.3",
"react-dom": "^16.6.3"
},
"scripts": {
"build": "webpack -p",
"dev": "webpack-dev-server --hot --inline"
}
I Have a component Hello World:
import React, { Component } from 'react';
import LoginActions from './LoginActions';
export class HelloWorld extends Component {
render() {
return (
<div className="hello-world">
<h1>Hello World</h1>
</div>
);
}
}
export default HelloWorld;
I'm running as:
yarn run dev
If I do not import LoginActions, it works, when I import, it compiles, but it does not work.
If I a run with react-scripts it show me an error that alt can understand ES6 class definition.
What Am I doing wrong?
Your babel-loader is only configured for .jsx files. You need to configure it for .js file too which alt.js is. To do that use the regex /\.jsx?/
{
test: /\.jsx?/,
use: {
loader: 'babel-loader',
options: { presets: ['react', 'es2015'] }
}
},

Storybook Viewport Addon: Custom Viewports Do Not Build (react)

I built an app using create-react-app. I create custom viewport types to add to my storybook. When I use yarn start everything builds fine and works. But when I build the app the viewports that I globally defined my preview.js file are not loading on the build. It is still the defaults. And for the life of me I can't figure out why. As far as I can tell I set it up the way the documentation explains.
This is my preview.js file
import { configure, addDecorator, addParameters } from '#storybook/react';
import { DocsPage, DocsContainer } from '#storybook/addon-docs/blocks';
import { withA11y } from '#storybook/addon-a11y';
import { GlobalStyle } from '../src/styles/global-styles';
const loaderFn = () => {
const allExports = [];
const styles = require.context('../src/styles', true, /\.stories\.(js|mdx)$/);
const req = require.context('../src/components', true, /\.stories\.(js|mdx)$/);
addDecorator(withA11y, GlobalStyle);
styles.keys().forEach(fname => allExports.push(styles(fname)));
req.keys().forEach(fname => allExports.push(req(fname)));
return allExports;
};
const customViewports = {
phoneSmall: {
name: 'Phone (320px min width)',
styles: {
width: '320px',
height: '667px',
},
},
tabletSmall: {
name: 'Tablet Small & Portrait (600px min width)',
styles: {
width: '600px',
height: '801px',
},
},
tabletLarge: {
name: 'Tablet Large & Landscape (960px min width)',
styles: {
width: '960px',
height: '768px',
},
},
desktop: {
name: 'Desktop (1200px min width)',
styles: {
width: '1200px',
height: '1024px',
},
},
};
configure(loaderFn, module);
addParameters({
docs: {
container: DocsContainer,
page: DocsPage,
},
viewport: { viewports: customViewports },
});
My main.js file
module.exports = {
stories: ['../src/**/*.stories.(js|mdx)'],
addons: [
'#storybook/preset-create-react-app',
'#storybook/addon-knobs/',
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-notes',
'#storybook/addon-storysource',
'#storybook/addon-a11y',
'#storybook/addon-docs',
'#storybook/addon-viewport',
]
}
Package.json
{
"name": "tamman-ui",
"version": "0.1.0",
"private": true,
"dependencies": {
"#storybook/addon-a11y": "^5.3.17",
"#storybook/addon-actions": "^5.3.17",
"#storybook/addon-docs": "^5.3.17",
"#storybook/addon-knobs": "^5.3.17",
"#storybook/addon-links": "^5.3.17",
"#storybook/addon-notes": "^5.3.17",
"#storybook/addon-storyshots-puppeteer": "^5.3.17",
"#storybook/addon-storysource": "^5.3.17",
"#storybook/addon-viewport": "^5.3.17",
"#storybook/addons": "^5.3.17",
"#storybook/preset-create-react-app": "^2.1.0",
"#storybook/react": "^5.3.17",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"autoprefixer": "^9.7.5",
"camel-case": "^4.1.1",
"core-js": "^3.6.4",
"del": "^5.1.0",
"fs": "^0.0.1-security",
"node-sass": "^4.13.1",
"pascal-case": "^3.1.1",
"path": "^0.12.7",
"prop-types": "^15.7.2",
"puppeteer": "^2.1.1",
"react": "^16.12.0",
"react-dom": "^16.13.1",
"react-scripts": "^3.4.1",
"styled-components": "^5.0.1",
"xml2js": "^0.4.23"
},
"scripts": {
"start": "node ./src/components/atoms/Icon/utils/generate-icons.js && react-scripts start",
"build-page": "node ./src/components/atoms/Icon/utils/generate-icons.js && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 9009 -s public",
"build": "yarn build-page && build-storybook -o build/storybook"
},
"eslintConfig": {
"extends": "react-app"
},
"homepage": ".",
"browserslist": [
"since 2010"
],
"devDependencies": {
"babel-loader": "^8.1.0",
"react-is": "^16.12.0"
}
}
Seems to be working fine. Try registering the viewport add-on
// main.js
module.exports = {
...
addons: [
...
'#storybook/addon-viewport/register',
],
]
}
Like the docs suggest.

Font.loadAsync() can't resolve module for custom fonts (React Native & Expo)

My app uses CRNA and Expo, and my issue is that the Font.loadAsync() asynchronous function can't locate a .otf font file in the assets/fonts/ folder in my project directory. I am absolutely sure that the directory and file names are correct. I receive this error.
link to image of my error screen
Here is my code:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Font, AppLoading } from 'expo'
import Root from './js/Root';
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
fontLoaded: false
}
}
async componentDidMount() {
await Font.loadAsync({
"Light": require('./assets/fonts/SemplicitaPro-Light.otf')
})
this.setState({ fontLoaded: true })
}
render() {
if (!this.state.fontLoaded) {
return <AppLoading />
}
return <Root />;
}
}
Here is my package.json:
{
"name": "Zumer",
"version": "0.1.0",
"private": true,
"devDependencies": {
"flow-bin": "^0.40.0",
"jest-expo": "^0.4.0",
"react-native-scripts": "0.0.28",
"react-test-renderer": "16.0.0-alpha.6"
},
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"scripts": {
"start": "react-native-scripts start",
"eject": "react-native-scripts eject",
"android": "react-native-scripts android",
"ios": "react-native-scripts ios",
"test": "node node_modules/jest/bin/jest.js --watch",
"flow": "flow"
},
"packagerOpts": {
"assetExts": ["ttf", "otf"]
},
"jest": {
"preset": "jest-expo",
"tranformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation)"
]
},
"dependencies": {
"#expo/vector-icons": "^4.0.0",
"expo": "^16.0.0",
"native-base": "^2.1.2",
"react": "16.0.0-alpha.6",
"react-native": "^0.43.4",
"react-native-elements": "^0.11.1",
"react-navigation": "^1.0.0-beta.8",
"react-redux": "^5.0.4",
"redux": "^3.6.0",
"redux-observable": "^0.14.1",
"redux-persist": "^4.6.0",
"rxjs": "^5.3.0"
}
}
Could it be that the .otf file format isn't supported by Expo?
I fixed this issue by converting the otf files to ttf
I had a similar issue and I was able to resolve it by removing the quotes around the key that requires the font source.
Before:
await Font.loadAsync({
"Light": require('./assets/fonts/SemplicitaPro-Light.otf')
})
After
await Font.loadAsync({
Light: require('./assets/fonts/SemplicitaPro-Light.otf')
})
And using it in the stylesheet like so
const styles = StyleSheet.create({
text: {
fontFamily: 'Light'
}
});
Everything worked fine after that.

Resources