CSS class not being applied even when exported react-toolbox - css

I am using react-toolbox and react-css-themr to supply theme. I create my contextTheme and supply it through ThemeProvider. Everything's seems fine. I am using webpack, the styles are exported and loaded in the attribute of my page, so there is no problem with the importing the css.
EDIT: I can clearly see the context theme is loaded to the website, as I can observe RT objects
my contextTheme file looks like this and is named contextTheme.js
export default {
RTAutocomplete: require('./assets/style/themes/autocomplete.module.css'),
RTButton: require('./assets/style/themes/button.module.css')
};
I can see custom theme in tag like this
.autocomplete-module--autocomplete--tESXbPMw {
padding: 0
}
.autocomplete-module--autocomplete--tESXbPMw .autocomplete-module--suggestions--t6ziL7OQ {
background-color: red;
border-color: blue;
border-radius: 0
}
theme provider looks like this
<ThemeProvider theme={contextTheme}>
<Router store={s} history={h}>
{ routes }
</Router>
</ThemeProvider>
resulting html element still has only default style applied, because no style is attached to it.
In case my webpack css config looks like this. I am not sure if that is relevant, but just in case.
{
test: /\.scss|\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
exportGlobals: true,
mode: "local",
auto: undefined,
localIdentName: "[name]--[local]--[hash:base64:8]",
},
sourceMap: shouldUseSourceMap,
}
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
],
sideEffects: true,
},

Related

How to write nested CSS with TailWind in Nuxt?

How to write nested CSS with TailWind in Nuxt?
Tailwind recommends to not use preprocessors like Sass or less and recommends it's better to use postcss-nested and import...
I tried and searched too much to use it I couldn't
I only added this config to add css nesting ability as I searched
build: {
postcss: {
plugins: {
'postcss-import': true,
'tailwindcss/nesting': {},
'postcss-nested': {},
},
},
splitChunks: {
layouts: true
}
},
And this is my tailwind config file codes
module.exports = {
mode: 'jit',
darkMode: true, // or 'media' or 'class'
theme: {
extend: {
},
},
variants: {
extend: {},
},
purge: {
content: [
`components/**/*.{vue,js}`,
`layouts/**/*.vue`,
`pages/**/*.vue`,
`plugins/**/*.{js,ts}`,
`nuxt.config.{js,ts}`
]
},
plugins: [],
}
this is my package.json file I've installed these:
#nuxtjs/tailwindcss - postcss - postcss-import - postcss-nested
Now when I try to write nested CSS I get error
I want to be able to write nested in components and in seprate css files alongside tailwind!
In vue components style section I try to write like this:
<style lang="postcss" scoped>
.test {
color:blue;
.ok{
color:red;
}
}
</style>
But it doesn't work

Webpack localIdentName mismatch on server and client in a React SSR application

I am trying to use Css modules with React SSR and i have added the following webpack config .
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
},{
test:/\.(s*)css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
modules: {
mode: 'local',
localIdentName: "[name]__[local]___[hash:base64:5]"
},
import: true,
importLoaders: true,
}
},
{
loader: "sass-loader",
}
],
},
]
},
this generates the following css files in the dist bundle
.Home\.module__Container___3B08 {
display: flex;
width: 600px;
height: 300px;
border: 2px solid red; }
Where as in my DOM the div has the following style
<div class="Home-module__Container___14QBF">
how do i make this correct ? and why is the webpack config different with the one in the browser
You have to add the CSS Modules configuration in .babelrc file under plugins. Then only the CSS generated will match with the one in your html.
.babelrc
"plugins": [
["react-css-modules", {
"generateScopedName": "[name]__[local]___[hash:base64:5]"
}]
],
Update :
Had to use css-modules-require-hook for server side CSS rendering and generic-names for generating hash in both client and server.
index.js
const hook = require( "css-modules-require-hook" );
const genericNames = require( "generic-names" );
const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
context: process.cwd(),
});
// Scope Generator function.
hook( {
generateScopedName: ( c, path ) => {
return generate( c, path );
},
} );
webpack.config.js
const genericNames = require( "generic-names" );
const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
context: process.cwd(),
});
const getLocalIdent = ( loaderContext, localIdentName, localName ) =>
generate( localName, loaderContext.resourcePath );
.....
{
loader: "css-loader",
options: {
modules: {
getLocalIdent,
},
},
},
For more, check this repo: https://github.com/ajayvarghese/react-ssr/tree/css-modules.
Note: Repo uses updated versions of babel packages.

Why are imported SASS styles being purged by PurgeCSS when using camelCase?

I am trying to combine CSS-modules and PurgeCSS to get module scoping and a light CSS bundle.
I have been able to accomplish this using syntax like styles["my-class"] but would prefer styles.myClass (which works, but gets stripped out for imported SASS within SASS files).
SASS from a local file works as expected, but SASS #imported from node_modules or another file doesn't work with camelCase references.
In the below code, I will get an output like:
.Component--container--AfniF {
margin: 1em;
}
but all the imported SASS that I reference in the component as styles.myClass is purged.
But, when referenced like styles["my-class"] everything works as expected and I get output like:
.Component--my-class--6Mlw4 {
color: purple;
}
.Component--container--AfniF {
margin: 1em;
}
Any ideas?
// otherstyles.scss
.my-class {
color: purple;
}
// Component.scss
#import "otherstyles";
.container {
margin: 1em;
}
///Component.js
import React, { Fragment, useState } from "react";
import classnames from "classnames";
import styles from "./Component.scss";
export default function ({ data }) {
return <div className={classnames([styles.myClass, styles.container])}>
//webpack.config.js
...
{
test: /.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
modules: true,
camelCase: true,
importLoaders: 1,
sourceMap: true,
localIdentName: "[name]--[local]--[hash:base64:5]",
},
},
{
loader: "postcss-loader",
},
{
loader: "#americanexpress/purgecss-loader",
options: {
paths: [path.join(__dirname, "src/**/*.{js,jsx}")],
},
},
{
loader: "sass-loader",
options: {
includePaths,
outputStyle: "expanded",
sourceMap: true,
},
},
],
},

Svelte: Is there a way to make global css variables in scope of svelte components?

I have set my global.css file which I import in index.js
--root {
--main-color: red;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
index.js
import "./global.css";
import App from "./App.svelte";
const app = new App({
target: document.body
});
My webpack setup
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.(html|svelte)$/,
exclude: /node_modules/,
use: {
loader: "svelte-loader",
options: {
emitCss: true,
hotReload: true
}
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: { loader: "style-loader", options: { sourceMap: true } },
use: [
{ loader: "css-loader", options: { sourceMap: true } },
{
loader: "postcss-loader",
options: {
sourceMap: true,
ident: "postcss",
plugins: loader => [
require("postcss-import")({}),
require("postcss-preset-env")(),
require("cssnano")()
]
}
}
]
})
}
]
},
plugins: [new HtmlWebpackPlugin(), new ExtractTextPlugin("styles.css")]
};
Works perfect for setting up global css for the entire app. But I am trying to use the --main-color in my svelte components. Is there a way to inject them down to all the components' css ?
Since I import global.css first, it should work as it emits a file with --root{} first then rest of the component styles.
You can place global styles under /routes/index.svelte file, like the example below:
<style>
:global(:root){
--header-color: purple
}
</style>
And simply use it anywhere like normally how you use CSS variables like so:
h1 {
color: var(--header-color);
}
I was busy with this, trying different webpack settings etc., seeing that the output css should work, I just could not find why it did not work. I wrote the post before trying for one last time, which wasted another hour. I finally found the error.
Instead of using :root{} I have mistyped it --root{}. I have posted it anyways, in case someone is stuck with the same mistake.

MiniCssExtractPlugin is garbling and obfuscating my class names

I am using MiniCssExtractPlugin in my typescript and webpack project.
My webpack config for the MiniCssExtractPlugin looks like
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './src/index.tsx',
mode: "development",
output: {
path: path.resolve(__dirname, "build"),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader"
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
sourceMap: true,
importLoader: 2
}
},
"sass-loader"
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "foo.css",
chunkFilename: "[id].css"
})],
devtool: "source-map",
resolve: {
extensions: [".js", ".ts", ".tsx"]
}
}
Now the scss file in my project has this fragment
h1 {
border-bottom: 3px solid #880055;
display: inline;
}
.container {
font-size: 1.3rem;
}
.is-completed {
text-decoration: line-through;
color: #00ff00;
}
when my application is run using npm start I can see that the heading H1 has a underline of the color 880055. So this means that my scss file was read correctly.
If I go into chrome developer tools and go into network tab and look for CSS. I can see a foo.css being downloaded. If I look into the content of foo.css
It doesn't have my "is-completed" class. instead I see something like
h1 {
border-bottom: 3px solid #880055;
display: inline; }
.pxcHIyOVHeytUeG27u4TO {
font-size: 1.3rem; }
._1Z5_KVJNKd1X2P3HKM63j {
text-decoration: line-through;
color: #00ff00; }
So element classes like h1 are good, but everything else is garbled. What's going on?
When you set modules: true in your CSS config you are telling the css-loader to use CSS-Modules to scope your class names to a particular file.
You can use the localIndentName query paramater in the css-loader options to specify what you want your generated class (identifier) to look like in development and/or in prod. See example below for what solved this for me.
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]-[local]--[hash:base64:5]',
},
},
},
],
},
};
If I were to use the configuration in the example above and the name of the component that I was rendering was called HelloWorld and a class used in that component was .container, if I were to run my app (dev or prod) and inspect the element in the devtools the class on my HelloWorld component appear as follows:
<div class="HelloWorld-container--16ABh"> Hello World </div>
You can play around with what you set as your localIdentName and how many characters of the hash you show.
See the documentation for the localIdentName query param here: https://github.com/webpack-contrib/css-loader#localidentname

Resources