Imported css by className is not worked on react - css

I should use simple css with styled-component.
But, imported css is not applied to component.
It is my webpack.config.ts
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: [
!isProduction && {
loader: 'babel-loader',
options: { plugins: ['react-hot-loader/babel'] },
},
'ts-loader',
].filter(Boolean),
},
// css
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: !isProduction,
importLoaders: 1,
localIdentName: isProduction
? '[hash:base64:5]'
: '[local]__[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-preset-env')({
/* use stage 2 features (defaults) */
stage: 2,
}),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction,
}),
],
},
},
],
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{ test: /\.(a?png|svg)$/, use: 'url-loader?limit=10000' },
{
test: /\.(jpe?g|gif|bmp|mp3|mp4|ogg|wav|eot|ttf|woff|woff2)$/,
use: 'file-loader',
},
],
},
I am importing css like this.
import './chipContainer.css'
import React, { useState } from 'react'
...
And, it is chipContainer.css
.chipContainer{
overflow: scroll;
min-height: 30px !important;
max-height: 100px;
}
Then, it is confirmed className on console.
class="WAMuiChipInput-standard-422 WAMuiChipInput-chipContainer-420 chipContainer"
But, it is not applied.
css defined as an element in the css file, such as body {...}, works fine, but css defined as className does not work.
what is the problem?

Related

3rd -party css not being applied

I'm trying to use react-responsive-carousel library and in order to appear correctly it requires the import of
import 'react-responsive-carousel/lib/styles/carousel.min';
When I load up my app I'm not seeing the styles applied to the component. I'm guessing it had something to do with my webpack configuration but I haven't found a solution yet
webpack.config.common.js
module.exports = {
entry: ['core-js/stable', 'regenerator-runtime/runtime', paths.appIndexJs],
output: {
filename: '[name].[contenthash].js',
path: paths.appBuild,
publicPath: './'
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.scss','.css'],
modules: ['node_modules']
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
filename: 'index.html',
inject: true,
template: paths.appHtml
}),
new ESLintPlugin({
formatter: eslintFormatter,
eslintPath: 'eslint',
resolvePluginsRelativeTo: __dirname
})
],
module: {
rules: [
{
test: /\.(js|ts)x?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
loader: require.resolve('file-loader'),
exclude: [/\.(js|mjs|jsx|ts|tsx|scss)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
}
]
}
}
webpack.config.dev.js
module.exports = merge(commonConfig, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
static: './dist',
port: 3001,
historyApiFallback: true
},
output: {
publicPath: '/'
},
module: {
rules: [
{
test:/\.css$/,
include: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: false
},
},
]
},
{
test:/\.(scss|sass|css)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: {
getLocalIdent: getCSSModuleLocalIdent
}
},
},
{
loader: 'postcss-loader',
options: {
//ident: 'postcss',
postcssOptions: {
plugins: () => [
require('postcss-flextbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3
}),
postcssNormalize()
]
}
}
},
'resolve-url-loader',
'sass-loader'
],
sideEffects: true
},
]
}
})
TestimonialsComponent.tsx
import React from 'react';
import { Carousel } from 'react-responsive-carousel';
import { testimonialsList, Testimonial } from '../Common/precious-testimonials';
import 'react-responsive-carousel/lib/styles/carousel.min.css';
type TestimonialElementProp = {
testimonial: Testimonial
}
const TestimonialElement = ({ testimonial }: TestimonialElementProp) => {
return <div>
<img src={testimonial.Image} />
<p>{testimonial.Quote}</p>
<h5>{testimonial.PersonName}</h5>
<h6>{testimonial.Title}</h6>
</div>
}
export const TestimonialsComponent = () => {
return <Carousel>
{testimonialsList.map((testmol) => {
return <TestimonialElement testimonial={testmol} />
})}
</Carousel>
}
Following the its npm page
Using webpack or parcel with a style loader
import styles from'react-responsive-carousel/lib/styles/carousel.min.css';
usually css files are imported in top level page of your application so that it will be loaded globally
import styles from'react-responsive-carousel/lib/styles/carousel.min.css';
import { Carousel } from 'react-responsive-carousel';
The issue here was that the css-loader was configured to not use the modules option. This meant that the css-loader was not applying the css classes correctly, because the modules option should be set to false when importing 3rd party css.
To fix this, the webpack config should be updated as follows:
module: {
rules: [
{
test:/\.css$/,
include: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: false
},
}
]
}
]
}

Css url() uses two periods before file extension even though it has one

I've noticed that sometimes the css url() has two periods(..) before the file extensions. It still works but doesn't make sense to me. I've seen it a lot of times but never figured out why. Is it because of the #mixin? Is it because of the relative path in the css? Does anyone know why it happens?
The filename does NOT contain two dots. Im seeing this on ElectronJS with React.
In my case I use it like this:
<div class="text"></div>
#mixin file-icon($path) {
background-image: url($path);
background-position: center;
background-repeat: no-repeat;
background-size: 24px 24px;
}
.text {
#include file-icon('./text.svg');
}
My webpack config is this:
{
entry: {...},
output: {...},
plugins: [
...,
new MiniCssExtractPlugin({
filename: 'styles.[contenthash].css',
ignoreOrder: true,
chunkFilename: '[id].[contenthash].css',
}),
],
module: {
rules: [{
test: /\.(js|jsx|ts|tsx)?$/,
use: {
loader: 'babel-loader',
},
}, {
test: /\.css$/,
exclude: /\.lazy\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
}, {
test: /\.lazy\.css$/,
use: [
{
loader: 'style-loader',
options: {
injectType: 'lazyStyleTag',
},
},
'css-loader',
],
}, {
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
}, {
test: /\.mp3$/,
type: 'asset/inline',
}, {
test: /\.(svg|gif)$/,
type: 'asset/resource',
}, {
test: /\.(eot|ttf|woff|woff2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
type: 'asset/resource',
}],
},
node: {
__filename: false,
__dirname: false,
},
target: 'electron-renderer',
devServer: {
port: WEBSERVER_PORT,
},
}
The weird part is that it's not a UI thing when inspecting css. When I use getComputedStyle(element).getPropertyValue('background-image') the returning string includes the two periods.

Vuetify without vue-cli sass/scss conflict

I need to integrate vuetify into a project which can not use vue cli and has the following css/sass webpack config.
{
test: /\.s?[ac]ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {url: false, sourceMap: true}
},
{
loader: 'sass-loader',
options: {sourceMap: true}
}
]
}
Vuetify config from docs
{
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
// webpackImporter: false,
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true
},
prependData: "#import 'src/novosales/variables/scss/vuetifyCustomStyles.scss'"
}
}
]
}
After merging into existing config
{
test: /\.s?[ac]ss$/,
use: [
'vue-style-loader',
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {url: false, sourceMap: true}
},
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sourceMap: true,
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true
},
prependData: "#import 'src/novosales/variables/scss/vuetifyCustomStyles.scss'",
}
}
]
}
I get error
While trying to solve I also got (expected linebreak) error, cant produce it right now.
I found a solution online but thats when using vue cli which is
// vue.config.js
css: {
loaderOptions: {
sass: {
data: '#import "~#/sass/main.scss"',
implementation: require("sass"),
fiber: require("fibers")
}
},
sourceMap: true
},
chainWebpack: config => {
["vue-modules", "vue", "normal-modules", "normal"].forEach((match) => {
config.module.rule('scss').oneOf(match).use('sass-loader')
.tap(opt => Object.assign(opt, { data: `#import '~#/sass/main.scss';` }))
});
}
I cant figure out how to achieve the same in this project and separate sass/scss.
Anyone already using vuetify without vue cli? thanks.

React not importing global css; local comp ok

React is not loading any global css. All local components are able to get its local styled-components. However, the global css is unable to generated to all components.
I've tried different import paths and tried on different file, also require(path). Not getting anything.
src
--modules
----component1
----component2
----asset
---------global.css
--index.js
global.css
.test-class{
font-size: 100px;
color:red;
}
at index.js
import './modules/assets/global.css'
render() {
return (<div className="test-class">Hello World</div>)}
HOWEVER if i use styledcomponents, it works.
Here's my webpack
module.exports = {
entry: ['babel-polyfill', './src/vendor.js', './src/index.js'],
plugins: [
new HTMLWebpackPlugin({
template: 'src/index.html'
}),
new MiniCssExtractPlugin({
filename: isDev ? '[name].css' : '[name].[hash].css',
chunkFilename: isDev ? '[id].css' : '[id].[hash].css'
})
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.ts[x]?$/,
exclude: /node_modules/,
use: ['babel-loader', 'awesome-typescript-loader']
},
{
test: /\.s?[ac]ss$/,
use: [
'style-loader', // : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: false
}
},
{
loader: 'postcss-loader',
options: {
path: '/postcss.config.js',
sourceMap: true
}
}
]
}
]
},
}
You are trying to get the classes from global.css but you are importing app.css in your index.js file. Import the correct file and you are set.
You are importing it correctly:
import './modules/assets/global.css';
Webpack looks good as well, but if you want to be sure just create a rule only for css since you don't seem to be using any scss or similar:
{test: /\.css$/, loader: 'style-loader'},
{
test: /\.css$/,
loader: 'css-loader',
options: {
importLoaders: 1,
modules: false
}
},

Add sass/css modules to typescript react app

In a new project, I need to add scss/css modules to a typescript/react app.
I added "typings-for-css-modules-loader" to the project and webpack.config.dev.js
like so : (here is the entire webpack.config.dev.js)
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('typings-for-css-modules-loader'),
options: {
importLoaders: 1,
modules: true
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},{
test: /\.scss$/,
use: [
require.resolve('style-loader'),
require.resolve('sass-loader'),
{
loader: require.resolve('typings-for-css-modules-loader'),
options: {
namedexport: true,
camelcase: true,
modules: true
}
}
]
},
When i add a test.scss file to my project, the compilation successfully creates a test.scss.d.ts which contains :
export interface ITestScss {
'toto': string;
}
export const locals: ITestScss;
When i try to import this css in my project like so :
import styles from './scss/test.scss';
I get this error :
Module '"/home/cyprien/projets/test/typescript-sass-modules-boilerplate/src/scss/test.scss"' has no default export.
Finally, In the browser, i get this error :
Failed to compile
./src/scss/test.scss
Module build failed:
.toto{
^
Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex"
in /home/cyprien/projets/test/typescript-sass-modules-boilerplate/src/scss/test.scss (line 1, column 1)
You need to use the plugin mini-css-extract-plugin. Here is an example of configuration with TypeScript and SASS SCSS (but without CSS modules neither PostCSS):
// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
mode: "development",
devtool: "source-map",
resolve: {
extensions: [".ts", ".js"]
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: "ts-loader"
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new MiniCssExtractPlugin()
]
}
I hope you'll be able to adapt it.
Found this solution:
webpack config (dev), this is for less :
{
test: /\.modules\.less$/,
use: [{
loader: 'style-loader' // creates style nodes from JS strings
},{
loader: 'typings-for-css-modules-loader',
options:{
modules:true,
namedExport: true,
camelCase: true,
localIdentName:'[path][name]---[local]---[hash:base64:5]'
}
},{
loader: 'less-loader',
options: { javascriptEnabled: true }// compiles Less to CSS
}]
}
then name your less file something.modules.less
import it in the js as so:
import * as styles from './something.modules.less';
and use it like this:
<div className={styles.yourClassName}></div>

Resources