Css of node-modules - css

I am using css modules in my react application. After setting modules:true inwebpack.config.js, I am able to get css from files which I created in my src folder. I am importing some components from node-modules. But the css of components present in node-modules is not getting applied.
I also tried importing css of node-modules using import 'path'; but it didnt work.
If I set modules:false, css of node-modules is getting applied and css of files in src folder is not getting applied.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
},
}
],
},
],
},
};

This might be due to the node module you are using may not be following module syntax. I mean they might be setting classes directly with a string instead of using like style.someClassName. So, you need 2 entries in your rules 1 for your stuff and 1 for node modules.
for ex:
module.exports = {
module: {
rules: [{
test: /\.css$/,
exclude: /node_modules/,
use: [{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
},
}
],
}, {
test: /\.css$/,
include: /node_modules/,
use: [{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: false,
},
}
],
}],
},
};

Related

How can I load CSS styles using Webpack in React app?

I am having an issue with my React app. I have added Webpack and it is compiling successfully but, at the moment of serving the content, the app shows no styles at all.
This is what I have so far in my webpack.config.js file:
const path = require('path');
const BUILD_DIR = path.resolve(__dirname + '/public/build');
const APP_DIR = path.resolve(__dirname + '/src');
// This is the main configuration object.
// Here, you write different options and tell Webpack what to do
module.exports = {
experiments: {
asyncWebAssembly: true,
topLevelAwait: true,
layers: true // optional, with some bundlers/frameworks it doesn't work without
},
resolve: {
extensions: ['', '.js', '.jsx', '.css']
},
// Path to your entry point. From this file Webpack will begin its work
entry: [APP_DIR + '/index.js', APP_DIR + '/index.css', APP_DIR + '/App.css'],
// Path and filename of your result bundle.
// Webpack will bundle all JavaScript into this file
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
// Default mode for Webpack is production.
// Depending on mode Webpack will apply different things
// on the final bundle. For now, we don't need production's JavaScript
// minifying and other things, so let's set mode to development
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true,
},
},
{ loader: 'sass-loader' },
{ loader: 'postcss-loader' }
],
},
]
}
};
Is there anything I am missing to get my css to work? I only have two files, located at /src: App.css and index.css. None of them seem to be loaded and I have no errors in the console.
rules: [
{
test: /\.js|jsx$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.(sass|scss|less|css)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
loader: 'file-loader'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader',
]
},
{
test: /\.css$/,
use: [
{
loader: 'url-loader',
options: {
limit: false
}
}
]
}
]

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
}
},

Inlining CSS NodeJS Server

I've recently gotten into the server side of NodeJS and I've noticed that importing styles and automatic in-lining no longer works. When I keep my SCSS file imported, my server is unable to start and can't parse it. Does anyone know how to restore the regular frontend behavior for css inlines.
I initially imported my SCSS via import styles from '../css/style.scss'; and it worked perfectly and inlined itself in the HTML document.
I'm using webpack to compile my SCSS into hashed CSS.
My config:
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
require('babel-register');
module.exports = {
entry: './src/js/app.js',
output: {
path: __dirname + "/src/js/",
filename: 'app.bundle.js'
},
mode: 'development',
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
extractComments: true
}),
new OptimizeCssAssetsPlugin({}),
new CompressionPlugin()
]
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{loader: "style-loader"},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: 'ko_[sha1:hash:hex:3]'
}
},
{
loader: "sass-loader"
}
]
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['react', 'es2015']
}
},
{
test: /\.js?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['react', 'es2015']
}
}
]
},
};
Error I get now when loading inline styles via JS

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>

How can I compile and load the pure CSS in ReactJS with webpack?

I am using a simple CSS based template for a ReactJS application with webpack module and not able to connect the CSS after compilation.
My webpack configuration looks like this...
var rucksack = require('rucksack-css')
var webpack = require('webpack')
var path = require('path')
module.exports = {
context: path.join(__dirname, './src'),
entry: {
css : './public/assets/css/main.css',
jsx: './index.js',
html: './public/index.html',
vendor: [
'react',
'react-dom',
'react-redux',
'react-router',
'react-router-redux',
'redux'
]
},
output: {
path: path.join(__dirname, './static'),
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.html$/,
loader: 'file?name=[name].[ext]'
},
{
test: /\.css$/,
include: /src/,
loaders: [
'style-loader',
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]',
'postcss-loader'
]
},
{
test: /\.css$/,
exclude: /src/,
loader: 'style!css'
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: [
'react-hot',
'babel-loader'
]
},
],
},
resolve: {
extensions: ['', '.js', '.jsx']
},
postcss: [
rucksack({
autoprefixer: true
})
],
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development') }
})
],
devServer: {
contentBase: './src',
hot: true
}
}
and relative path for my css file is 'src/public/assets/css/main.css'.
Is there any way to use pure traditional CSS without changing it to the react based CSS-in-JS ?
I keep the CSS as a seprate thing, i use gulp or grunt to make things easyer then include the files as your base html
You could use the extract-text-webpack-plugin to pull your css out of your JS files. I believe the general best practice is to use the 'CSS-in-JS' (as you mentioned it) while working in development to benefit from hot-reloading. And then using the plugin above to build for production.
Also, it seems as though your config file has some redundancy.
{
test: /\.css$/,
include: /src/,
loaders: [
'style-loader',
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]',
'postcss-loader'
]
},
{
test: /\.css$/, // <--- this test seems redunant. Perhaps remove it.
exclude: /src/,
loader: 'style!css'
},

Resources