Working with css classnames and react-virtualized or react-select - reactjs

So i'm trying to integrate both of this modules into my project and i have difficulties in dealing with its CSS part.
My project is using postcss to turn my own css files into "compiled" css files with added classnames to each of them.
Both react-virtualized and react-select have their own css files to define the styling, however i do not understand how i can override them or integrate them into my project.
My webpack css config is the following:
[
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
localIndentName,
sourceMap: true,
modules: true,
importLoaders: 1
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
postcssImport({ path: path.resolve(PATHS.app, './css') }),
postcssCssnext({ browsers: ['> 1%', 'last 2 versions'] }),
postcssReporter({ clearMessages: true })
]
}
}]
{
test: /\.css$/,
use: loaders
}
When i do the following line in my main app.js file, then i get a failed parsing error of the css (Unexpected token).
import 'react-virtualized/styles.css';
The only way i was able to load the CSS styles is using
import '!style-loader!css-loader!./css/unstyled/react-virtualized.css';
Meaning, copy the whole CSS into my own project and importing it without the postcss working.
However, i dont know if this is the best way because its very explicit of working with those modules.
Does anyone has a better solution?

You have 2 options:
Tell react-virtualized what generated class names your CSS is using.
Tell your CSS loader not to transform react-virtualized specific default class names.
For option 1 check out the react-virtualized docs. For example, look at the List component. It accepts a className property that specifies which external CSS class name to append to the outer element. Since you render your own List rows you can also attach custom class names to those elements.
For option 2, use react-virtualized's default class names (also listed in the project docs) and tell your CSS loader not to mangle them by wrapping them in a :global(...) statement (as shown in the docs).

Related

import css does not work for class name with dashes for Webpack 5 and css loader 5

Trying to get a third party library that is importing css to work with my app.
I am using webpack v5 and css-loader v5. Since the upgrade from webpack v4 to v5, the 3rd party library styles are no longer working because css-loader doesn't allow named exports, hence
import('./styles.css').then((styles) => console.log(styles))
will yield something like styles.default.xxx instead of styles.xxx
A workaround would be setting namedExport option to be true in css-loader. This will enable me to access styles.xxx without the default. However if I set namedExport to be true in css-loader, I can no longer import classes with dashes (e.g. "btn-focused" because css-loader will convert it to "btnFocused" and the third party library refers to the styles as styles['btn-focused']). I see an option exportLocalsConvention in css-loader, however this option is restricted to 'camelCaseOnly' or 'dashesOnly' when namedExport is set to true, and both of these options do not help.
Did you try style-loader? Give the following configuration a try! It works in dynamic imports:
use: [
{
loader: 'style-loader',
options: {
esModule: false,
},
},
{
loader: 'css-loader',
options: {
esModule: false,
modules: {},
},
}
]
Feel free to let me know if there is any problem with it :)

Style Loader has been initialised using an options object that does not match the API schema

I am a very new to programming. So read a few articles and trying to configure web-pack for the following purpose.
I'm building a preact widget and the CSS is clashing with parent website. Hence I'm trying to create a shadow DOM and then load css into shadow DOM instead of adding into the document header.
I have created a shadow DOM and I have configured webpack to inject styles into the shadow root like below.
rules: [
// packs SVG's discovered in url() into bundle
{ test: /\.svg/, use: 'svg-url-loader' },
{
test: /\.css$/i,
use: [
{
loader: require.resolve('style-loader'),
options: {
insertInto: function () {
return document.getElementById('#widget-_hw').shadowRoot;
},
},
},
{
// allows import CSS as modules
loader: 'css-loader',
options: {
modules: {
// css class names format
localIdentName: '[name]-[local]-[hash:base64:5]'
},
sourceMap: isDevBuild
}
}
]
But I'm getting the following error
Module build failed (from ./node_modules/style-loader/dist/cjs.js):
ValidationError: Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'insertInto'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }
The error tells you exactly what's wrong: insertInto is not a valid option on style-loader.
insert, which the error message tells you is one of the valid options, is likely what you want.

Can I generate component level css files using RollupJs for my component library?

I'm running into some issues when trying to create a component library with RollupJS.
I'm building a react component library to be used inside other projects. The library uses css-modules for the styling of the components.
I currently have a basic version of my component library, but when I use it in a Gatsby project, I get a FOUC (because the js gets injected into the head with javascript).
This led mo to extract the CSS and inject it into the head of the consuming application, but I don't think this is the way to go.
What I would like to accomplish is that each component exposes its own stylesheet so the consuming application can import only the style of the components it needs.
(An even better approach would be that we only need to import the component we need, and it will provide the CSS to the application, but that is phase 2)
My project structure looks like this
- src
- components
- component_1
* index.js
* styles.module.scss
- component_2
* index.js
* styles.module.scss
To be able to reference the styles of each component separately I (think) I would need an output structure like
- dist
- modules
- components
- component_1
* … (files generated by rollup)
* styles.css
- component_2
* … (files generated by rollup)
* styles.css
I have been fiddling with my rollup setup and got to this point:
The config below gives me one big index CSS file, but depending on how the library will grow, I don’t think it is good practice to always have to include all of the component styles (even those of components that aren’t used)
import babel from "rollup-plugin-babel";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import resolve from "rollup-plugin-node-resolve";
import prettier from "rollup-plugin-prettier";
export default {
input: "src/index.js",
output: [
{
dir: "build/modules",
format: "esm",
exports: "named",
sourcemap: true,
},
{
dir: "build/common",
format: "cjs",
exports: "named",
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
prettier({ parser: "babel" }),
postcss({
modules: true,
extract: true,
}),
babel({
exclude: "node_modules/**",
}),
],
external: ["react", "react-dom"],
preserveModules: true,
};
Does anybody know how I could go about letting rollup create the CSS files on component level instead of on library level?
I've gone through the options that rollup and rollup-plugin-postcss have to offer, but I don't see a solution for this issue.

React : CSS class name import not working

i have a <main> div in my react component and im importing some class name from a class css file, but the class name is not getting integrated to the main div when i try to inspect it in the browser. when i simply use other class names its working like <main className="test"> but importing classes is not working.
This is my component :
import React from 'react';
import Aux from '../../hoc/Aux';
import classes from './Layout.css';
const layout = (props) => (
<Aux>
<div>
Test paragraph
</div>
<main className={classes.Content}>
{props.children}
</main>
</Aux>
);
export default layout;
This is my css
.Content{
color: red;
margin-top: 20px;
}
I did npm run eject command after creation, if there is something to do with the webpack configuration file please help me
( i haven't made any changes there after eject command )
Here is the css part of webpack dev config file
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
}),
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
}),
},
import './Layout.css';
Then use it like a normal CSS
<main className="Content">
You can also use your classes as objects with this format:
In your CSS file:
Wrap your classes and id's with :local(.className)
Example
:local(.Content) { width: 100px; }
In your React Component:
import classes from './stylesheet.css'
<div className={classes.Content}></div>
Actually I've used it like this:
import classes from './Layout.module.css';
As you see in the text of your question:
// using the extension .module.css
You have to configure some staff. follow these steps:
npm run eject run this command inside your project root directory
search cssRegex and add the following lines under use: getStyleLoaders({
modules:true,
localIdentName:'[name]__[local]__[hash:base64:5]'
Enjoy!
Make sure 'npm run eject' run successfully then you can access webpack.config.js file in config folder.
Stop the server.
Go to webpack.config.js
Find cssRegex and update as given in the image
Restart the server
If you're using Windows, don't name file 'Aux' it's reserved name.
Solution is just to name your CSS files as (in your case) Layout.module.css and then import them as such.
You don't need to eject as from the Create React App 2.0 since it uses CSS Modules out of the box.
Don't you need to specify the file's extension like import classes from './layout.css';?
Try to instal style-loader and css-loader packages. Then add to you webpack this:
{
test: /\.css$/,
loaders: [
'style-loader?sourceMap',
'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
]
}
I got if from css-modules documentation and I hope it will help you to achieve what you need.
None of the above solutions worked for me, if you're using a react version with react-scripts#2.0.0 and higher, they probably wouldn't work for you either.
you must used the CSS Modules alongside regular stylesheets using the [name].module.css file naming convention. CSS Modules allows the scoping of CSS by automatically creating a unique classname of the format [filename]_[classname]__[hash].
example Header.module.css
nb: header here can be any name
To use class names like an object you need to do 2 things:
Write import like import * as classes from './Layout.css';
Include typings defenition for your style.
Example for Typescript - create Layout.css.d.ts file with export const Content: string;
Be sure that you define camelCase option for css-loader to resolve dash-classes into camel-case properties that you define in Layout.css.d.ts.
I was also working on a react tutorial and faced same issue.
I updated my webpack.config.js file at line 420 and it was working for me then. Please try it out.
line 420:
localIdentName:'[name][local][hash:base64:5]',
For latest version no need to set
localIdentName: '[name][local][hash:base64:5]', // no need set any where
Just give your css name with postfix like FileName.module.css ex Personal.module.css
Then class name like below filename_classname_randomstring
Personal_Person__3L9tz
it working for me
this works for me
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
the other answers not worked for me
so I used this solution and worked fine
1: run the npm run eject command
2: go to config/webpack.config.js and search for cssRegex
3: use this code in that particular section
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules:{
localIdentName:'[name]__[local]__[hash:base64:5]'
},
}),
Just add the below configuration to config/webpack.config.js after running npm run eject in the command line in the project folder and select yes when propted
I have noticed many reference to test: cssRegex block, though you may not have it in the webpack config.
If the above is your case try to open webpack.config.dev.js and find block starting with test: /\.css$/, (row 160 in my case). Then add the following lines so final result looks like this:
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
},
},
This should enable css modules to work.
Here is the solution:
yarn run eject
Go to the config/webpack.config.js
Update the file as the screenshot.
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use MiniCSSExtractPlugin to extract that CSS
// to a file, but in development "style" loader enables hot editing
// of CSS.
// By default we support CSS Modules with the extension .module.css
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
localIdentName:'[name]__[local]__[hash:base64:5]',
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent
}),
},

react-toolbox css config in webpack 2 not working

I am working with webpack and I have been trying to config react-toolbox library.
I managed to make it work but the css is not loading.
webpack.config.js
You haven't configured your style loader to emit CSS modules
Add this to your style loader
loader: 'style!css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss'
This will turn on CSS modules, and also set it up for allowing postCSS to hook up to it
Remember that this will now treat any .scss or .css file as a locally scoped module, so if you have any separate normal SCSS or CSS that you want to remain global, you will need to add another rule for them
// EDIT
It may be confused using the loader string if your other loader configs are still in that array (as the above string is shorthand to combine them all), try instead separately using config objects...
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
modules: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
postcssNext
]
}
}
]
}
React Toolbox no longer uses SCSS having migrated to PostCSS so I've left that out - if you use it then add that in the same manner

Resources