React multiple css loaders in webpack - reactjs

I am using react-bootstrap and css modules. In my webpack.config.js i am able to run my bootstrap.css with this config:
{ test: /\.css$/, loader: "style-loader!css-loader" }
However my css modules should have this setup:
{
test: /\.css$/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
]
}
How do I combine them to make it work for css modules and react-bootstrap

You might keep both loaders: one for global CSS (like Bootstrap) and the other for CSS modules.
In order to avoid conflicts between loaders with same test property, use webpack's rules include and exclude properties:
{
test: /\.css$/,
loader: "style-loader!css-loader",
include: [
/* Paths to Bootstrap and further global CSS only */
]
},
{
test: /\.css$/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName[path]___[name]__[local]___[hash:base64:5]'
],
include: [
/* eg. Paths to your source directory */
]
}

Related

How to load single css file in webpack instead of multiple files from node_modules

This is working code but it's loaded all .css file from node_modules
module: {
rules: [
{
test: /\.css$/i,
use: ["css-loader"]
}
]
}
I want load only one css file form node modules that is require in one of .js file?
i.e. file path : node_modules\package_name\dist\style\123.css.
Add in an exclude statement to your rule for the node_modules folder
module: {
rules: [
{
test: /\.css$/,
use: ["css-loader"],
exclude: /node_modules/,
}
]
}

CSS Modules not working with 3rd party package react-spinkit

I am trying to utilize the react-spinkit package for my React.js web application. Within this application I have opted to use CSS modules. When I made the switch to CSS modules, I noticed that the spinner component that I created was not rendering. I am sure this has to do with the fact that I am now using CSS modules. Currently my webpack.config.js file looks something like this:
module.exports = {
//other configurations...
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
loader: 'style-loader!css-loader? modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
}
]
}
}
I believe that I need to set a rule for regular css to be compiled by the css-loader. However, I am not aware of how to combine a rule so that the css-loader can use both css modules and regular css. Any help would be appreciated.
try having your config look like this in that section:
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]

Using Webpack with SASS and PostCSS in Angular2

Init
Im trying to use webpack with the sass-loader and the postcss-loader. I already tried different solutions but nothing worked like I want it to.
I tried the solution from Angular 2 Starter Pack with the raw-loader and the sass-loader, but than the postcss-loader didnt work.
Code
Angular 2 Component
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
// styles: [
// require('./app.component.scss')
// ]
})
Webpack module loader
{
test: /\.scss$/,
loaders: ['to-string-loader', 'css-loader', 'postcss-loader', 'resolve-url-loader', 'sass-loader']
}
Problem
With these code lines everything works but the styles are added in the <head> tag within the <style> tag. At some point I would have hundreds of style lines which I want to avoid.
If I change my loader code to this:
loader: ExtractTextPlugin.extract('to-string-loader', 'css-loader', 'postcss-loader', 'resolve-url-loader', 'sass-loader?sourceMap')
and add this to the webpack config
plugins: [
new ExtractTextPlugin('style.css')
]
it results in an error
Uncaught Error: Expected 'styles' to be an array of strings.
The style.css is actually linked in the html code.
Im searching for a solution which allows me to use sass, postcss and a single .css file.
I just ran into this issue and figured out a solution. I'm pretty sure its the "to-string-loader". The dev config below is working for me using Webpack 4 and Angular 7. It allows a global stylesheet (Tailwind CSS in my case) alongside component styles. Hot module replacement is also working for editing both entries.
entry: {
app: './src/main',
styles: './src/assets/styles/styles'
},
resolve: {
extensions: ['.ts', '.tsx', '.mjs', '.js', '.scss'],
},
module: {
rules: [
{
// Process the component styles
exclude: path.resolve(__dirname, 'src/assets/styles/styles'),
test: /\.(scss)$/,
use: [
{ loader: 'raw-loader' }, // Load component css as raw strings
{
loader: 'postcss-loader', // Process Tailwind CSS
options: {
sourceMap: 'inline',
}
},
{
loader: 'sass-loader', // Compiles Sass to CSS
},
]
},
{
// Process the global tailwind styles
include: path.resolve(__dirname, 'src/assets/styles/styles'),
test: /\.(scss)$/,
use: [
{
loader: 'style-loader', // Allow for HMR
},
{
loader: 'postcss-loader', // Process Tailwind CSS
options: {
sourceMap: 'inline',
}
},
{
loader: 'sass-loader', // Compiles Sass to CSS
},
]
},
]
},
The style-loader will extract the styles into the head at runtime, and allow for HMR. In your prod config, you can use css-loader alongside MiniCssExtractPlugin to extract and inject the global styles as a .css file into the head:
{
// Process the global tailwind styles
include: path.resolve(__dirname, 'src/assets/styles/styles'),
test: /\.(scss)$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-loader' },
{
loader: 'postcss-loader', // Process Tailwind CSS
options: {
sourceMap: false,
}
},
{
loader: 'sass-loader', // Compiles Sass to CSS
},
]
},

Add Sass (.scss) to ejected create-react-app config

I want to add .scss support in my app, which was created using create-react-app.
I did eject npm run eject and installed necessary dependencies: npm install sass-loader node-sass --save-dev
Inside config/webpack.config.dev.js I added to the loaders this snippet:
{
test: /\.scss$/,
include: paths.appSrc,
loaders: ["style", "css", "scss"]
},
So the beginning of the loaders array now look like so:
loaders: [
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel',
query: require('./babel.dev')
},
// "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 a plugin to extract that CSS to a file, but
// in development "style" loader enables hot editing of CSS.
{
test: /\.css$/,
loader: 'style!css!postcss'
},
// LOAD & COMPILE SCSS
{
test: /\.scss$/,
include: paths.appSrc,
loaders: ["style", "css", "scss"]
},
Now in my jsx when I try to import scss file:
import './assets/app.scss';
I get an error:
Uncaught Error: Cannot find module "./assets/app.scss"
So my config must be wrong as I'm not able to load .scss files. How to adjust config to load .scss files in ejected create-react-app?
Check the first loader, first it get all the files and it excludes the other loaders files
loaders: [
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.json$/,
/\.svg$/
],
loader: 'url',
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
so adding
/\.sass$/,
/\.scss$/,
to exclude, seems that fixed the same problem I had :D
When trying to integrate sass into empty react project I used this article. The solution presented there did not work and received the similar error as in the subject.
In my case replacing style-loader with require.resolve('style-loader') helped:
{
test: /\.scss$/,
include: paths.appSrc,
loaders: [require.resolve('style-loader'), require.resolve('css-loader'), require.resolve('sass-loader')]
},
OK, I found the solution - changed from this:
{
test: /\.scss$/,
include: paths.appSrc,
loaders: ["style", "css", "scss"]
},
to this:
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
And now my .scss files are loading!!
You probably have to use
include: paths.appSrc,
option to enable webpack hot-reload. So you config snippet could looks like
{
test: /\.scss$/,
include: paths.appSrc,
loaders: ['style', 'css', 'sass']
},
as per Latest Configuration [CRA]
::webpack.config.dev.js::
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
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$/,
loaders: [
require.resolve("style-loader"), // creates style nodes from JS strings
require.resolve("css-loader"), // transl ates CSS into CommonJS
require.resolve("sass-loader") // compiles Sass to CSS
]
},
Check this loader settings for the latest versions.
{
test: /\.scss$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"sass-loader" // compiles Sass to CSS
]
}

Using webpack with 'react-hot', 'babel-loader'

I have a webpack.config with loaders like this:
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loaders: [ 'react-hot', 'babel-loader' ]
},
{
exclude: /node_modules/,
loader: 'eslint-loader',
test: /\.js$/
}
],
I exclude node_modules because other ways react-hot would get in trouble saying things like this
My problem is that: by excluding node_module, a private npm package that needs babel-loader, would not be loaded into the bundle.
How can I manage excluding for each loader?
You can use the include property for the loader instead of exclude. For example:
loaders: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, "app/src"),
// some module in node_modules folder
],
loaders: [ 'react-hot', 'babel-loader' ]
},
...
],
Note that both webpack and react-hot-loader recommend using include over exclude whenever possible.

Resources