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

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

Related

webpack not getting seperate css file for extract text plugin

Hi everyone I am using web-pack to try to replace a gulp build that was overly complicated. but was running into some issues when it came to the Css. We are using sass. We also have a project structure that has the sass files right by each of the the angular component so that means for every class there is a separate folder. Currently our gulp magically goes into the folders and downloads the sass.
But I can't get the extract-text-webpack-plugin to output me a separate Css file the source I am using for trying to do this is.
https://itnext.io/sharing-sass-resources-with-sass-resources-loader-and-webpack-ca470cd11746
here is my code
const config = {
entry: {
'app': './app/app.js',
// 'vendor': './src/vendor.module.js'
},
devtool: 'source-map',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist/dev')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: [ 'ng-annotate-loader', 'babel-loader' ]
},
// for fixing of loading bootstrap icon files
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
options: {
name: './fonts/[name].[ext]'
}
},
{
test: /\.(eot|ttf)$/,
loader: 'file-loader',
options: {
name: './fonts/[name].[ext]'
}
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
attrs: [ 'attrs=false' ]
}
},
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
filename: path.resolve(__dirname, 'dist/dev') + 'app.css',
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
},
{
loader: 'sass-resources-loader',
options: {
resources: require(path.join(process.cwd(), './app/appscss.js'))
}
}
]
}),
},
/* ,
{
test: /\.(scss)$/,
use: ExtractTextWebpackPlugin.extract({
use: [
{
loader: "css-loader",
options: {
minimize: true
}
},
{
loader: "sass-loader"
}
]
})
} */
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
comments: false,
sourceMap: true,
}),
new ExtractTextWebpackPlugin('app.css', {
allChunks: true
}),
new webpack.DefinePlugin({
GULP_REPLACE_ENV_URL: JSON.stringify(environementUrl())
})
],
devServer: {
port: 5000,
contentBase: path.resolve(__dirname, 'dist/dev'),
historyApiFallback: true,
// needed since we set api to something other than host
// http://flummox-engineering.blogspot.com/2017/10/webpack-dev-server-invalid-host-header-host-0.0.0.0-not-working-npm-dev-server.html
disableHostCheck: true
}
};
module.exports = config;
Any help would be much appreciated.

React-filepond external CSS is not being applied. I suspect it's a webpack issue

This is beating my head in. I'm using react-filepond module in my react app, but the external CSS is not being applied. The module works but has no style. I suspect it's a loader issue in webpack but I'm still learning webpack and probably missed something. Thanks!
Here are the imports as per react-filepond:
import { FilePond } from 'react-filepond';
import 'filepond/dist/filepond.css'; // located in node_modules
Here's my webpack.config.js.
I'm using webpack 3.12.0
const path = require('path');
const autoprefixer = require('autoprefixer');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
chunkFilename: '[id].js',
publicPath: '/'
},
resolve: {
extensions: ['.js', 'jsx', '.css']
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: ['react']
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
browsers: [
"> 1%",
"last 2 versions"
]
})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: 'url-loader?limit=8000&name=images/[name].[ext]'
}
]
},
devServer: {
historyApiFallback: true
},
plugins: [
new htmlWebpackPlugin({
template: __dirname + '/src/index.html',
inject: 'body',
filename: 'index.html'
})
]
};
I found the solution for others wondering about this.
Issue: I am using CSS modules in react (note the line modules:true in the configuration of my css-loader in my webpack-config.js
The external react module I was trying to use does NOT use CSS modules.
Solution:
create a second rule for external CSS. Thus I have one for my CSS (as in the source above) and then I added this rule:
{
/* External CSS from node_modules */
test: /\.css$/,
include: /node_modules/,
loader: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
},
}
]
},
Most importantly, I did NOT turn on CSS Modules
And then, in my other CSS rule, I added:
exclude: /node_modules/,

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

Webpack: extract css to its own bundle

I'm using webpack on a project. I use style-loader so I can import "my.css".
The css gets bundled with the javascript and will be rendered in a <style> tag when component mount, ok.
However, I would like to keep that import syntax and make webpack build a css bundle for every entry point.
So webpack output should be [name].bundle.js AND [name].bundle.css.
Is this something I can achieve ?
var config = {
entry: {
'admin': APP_DIR + '/admin.entry.jsx',
'public': APP_DIR + '/public.entry.jsx'
},
output: {
path: BUILD_DIR,
filename: '[name].bundle.js'
},
resolve: {
extensions: ['.js', '.jsx', '.json']
},
plugins: [],
devtool: 'cheap-source-map',
module: {
loaders: [{
test: /(\/index)?\.jsx?/,
include: APP_DIR,
loader: 'babel-loader'
},
{
test: /\.scss$/,
loaders: [
'style-loader',
'css-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: ['./src/styles/constants.scss']
},
}
]
}
],
}
};
along with this babel.rc:
{
"presets" : ["es2015", "react"],
"plugins": ["transform-decorators-legacy", "babel-plugin-root-import"]
}
Yes, you need to use extract-text-webpack-plugin. You might want to do it only on your production config. Config looks like this:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin('style.css')
//if you want to pass in options, you can do so:
//new ExtractTextPlugin({
// filename: 'style.css'
//})
]
}

PostCSS & Webpack configuration

I'm really disheartened, because I can't find any useful resource on the subject.
I merely want to watch my .css files, use post css' plugins to transform them and finally export them to my /public folder as I already do with my .jsx files
Here's my web pack configuration
const path = require('path');
const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: path.resolve('src/index.jsx'),
output: {
path: path.resolve('public'),
filename: 'bundle.js'
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
devServer: {
publicPath: "/",
contentBase: "./public"
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}, {
loader: 'postcss-loader',
options: {
plugins: function() {
return [require('lost'), require('postcss-cssnext'), require('postcss-import')]
}
}
}
]
})
}, {
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
],
exclude: /(node_modules|bower_components)/
}
]
},
plugins: [new ExtractTextPlugin("main.css")]
}
I assume you are using webpack2
If you want your css file dumped out separately, you would need ExtractTextPlugin. Here is my css loader which works
I define the post css plugins right within the webpack config, because then it stays in one place. Hope this helps:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
...
...
module.exports = {
...
...
module: {
rules: [
...
...
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract(
{ fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
modules: true,
localIdentName:'[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
plugins: function() {
return [
require('autoprefixer')
]
}
}
},
]
})
},
}
Maybe your plugins are incorrectly created.
Try
return [require('lost')(), require('postcss-cssnext')(), require('postcss-import')()]
(Note the () to invoke the plugin creation).
Also are you actually using import/require() to include your css? If not you should, no magic stuff will glob your css :)

Resources