Webpack compiling CSS into strange classnames - css

I am currently using webpack while developing React app with a NodeJS backend.
I am having trouble with styling the app because it seems webpack trying to do something with my css where it ends up changing the classnames.
For instance in my base.css file I have this:
body {
background: #ECEFF1;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 15px;
line-height: 1.7;
margin: 0 auto;
padding: 30px;
max-width: 980px;
}
.progress {
background-color: #FFECB3;
}
.progress .indeterminate {
background-color: #FFC107;
}
Which when I load the page and look in the head is converted to a <style> div with these classnames:
<style type="text/css">
body {
background: #ECEFF1;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 15px;
line-height: 1.7;
margin: 0 auto;
padding: 30px;
max-width: 980px;
}
.base---progress---1RR8Z {
background-color: #FFECB3;
}
.base---progress---1RR8Z .base---indeterminate---23sZH {
background-color: #FFC107;
}
So progress styles aren't being picked up on the page because they are changed into this format. How can I avoid this or have React change the class names appropriately?
If I removed this from my webpack config:
{
test: /\.css$/,
loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
}
Line it says that it can't find the css file but the path it errors out on is valid.
Webpack config for good measure:
'use strict';
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'eval-source-map',
entry: [
'webpack-hot-middleware/client?reload=true',
path.join(__dirname, 'public/app/main.js')
],
output: {
path: path.join(__dirname, '/dist/'),
filename: '[name].js',
publicPath: '/'
},
plugins: [
new HtmlWebpackPlugin({
template: 'public/app/index.html',
inject: 'body',
filename: 'index.html'
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
"presets": ["react", "es2015", "stage-0", "react-hmre"]
}
}, {
test: /\.json?$/,
loader: 'json'
}, {
test: /\.css$/,
loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
}]
}
};

Your config currently uses css-modules. To disable it
change 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]' to 'style!css' in the loader for css files.

Related

Unable to match font weights with google fonts and react styled components

I'm trying the following style below. The issue is the actual result font-weight is no where close to the mock-up. How can I ensure I get the right style?
https://fonts.google.com/specimenTab?standard-styles#standard-styles
const LogoH1 = styled.span`
text-transform: uppercase;
font-family: 'Montserrat';
font-size: 50px;
font-weight: 900;
letter-spacing: -5px;
`
Design Tool (Adobe XD)
Result
I'm using Gatsby to connect the fonts:
plugins: [
{
resolve: `gatsby-plugin-google-fonts`,
options: {
fonts: [
`Montserrat`,
],
}
}
],
plugins: [
{
resolve: `gatsby-plugin-google-fonts`,
options: {
fonts: [
`Montserrat\:400,500,600,700,800,900`,
],
}
}],

Importing global css custom variables

I'm trying to use webpack with postcss to import a theme-variables.css file that contains my css custom variables.
//theme-variables.css
:root {
--babyBlue: blue;
}
Basically I want any css that imports theme-variable to be able to access these css custom properties and resolve to static values using postcss-css-variables.
//style.css
#import "./theme-variable.css";
div {
display: flex;
color: var(--babyBlue);
}
becomes
//main.css
div {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
color: blue;
}
However I keep getting webpack errors variable --babyBlue is undefined and used without a fallback
main.js ends up looking like this:
:root {
--babyBlue: blue;
}
div {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
color: undefined;
}
Here's my webpack (index.js requires styles.js):
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: { main: "./src/index.js" },
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader",
options: { importLoaders: 1 }
},
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("postcss-css-variables")(),
require("postcss-cssnext")(),
require("autoprefixer")(),
require("postcss-import")()
]
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
})
]
};
Solution:
The postcss-import plugin has to come first HOWEVER the plugins for Postcss-loader does not go in reverse order like webpack loaders do.
This fixes it:
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("postcss-import")()
require("postcss-css-variables")(),
require("postcss-cssnext")(),
require("autoprefixer")(),
]
}

CSS direct descendant not working properly on production build

I suspect this is an issue with webpack, but I cannot seem to get this to work. My only CSS file (main.css) contains the following code:
.numpad > input {
text-align: center;
border: 2px solid blue;
margin: auto;
}
However when I publish the application, the CSS file shows the following:
.numpad {
text-align: center;
border: 2px solid blue;
margin: auto;
}
.numpad > input {
text-align: center;
border: 2px solid blue;
margin: auto;
}
I have searched the entire solution for any sort of duplicate that could be causing the first. It doesn't exist.
My webpack config is as follows:
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
stats: { modules: false },
entry: { 'main': './ClientApp/boot.tsx' },
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].js',
publicPath: 'dist/'
},
devtool: 'inline-source-map',
module: {
rules: [
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
{ test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
{ test: /\.js$/, include: /src/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['env'] } } }
]
},
plugins: [
new CheckerPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
}),
new CleanWebpackPlugin(['dist'])
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('main.css')
])
}];
};
Any ideas for why there is a duplicate being created?

Media Query not working with CSS/Style loader and Webpack3

I am using css-loader and style-loader for my CSS but all media queries are not working. I am using "webpack": "^3.4.1", "css-loader": "^0.28.4" and "style-loader": "^0.18.2".
This is my Webpack configuration:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]-[local]-[hash:base64:6]',
camelCase: true
}
}]
}]
...
plugins: [
new ExtractTextPlugin({
filename: 'style.[chunkhash:6].css',
allChunks: true
})
]
My css file is something like this:
.container{
position: relative;
margin: 30px 15px;
padding: 50px 15px;
background: #fff;
}
#media (max-width: 768px) {
.container{
background: #fbfbfb;
}
}
and I am importing this CSS file in React code like this:
import styles from './Component.css'
try use this code
.container{
position: relative;
margin: 30px 15px;
padding: 50px 15px;
background: #fff;
}
#media only screen and (max-width:768px){
.container{
background: #c00;
}
}
<div class="container">
content her
</div>
I think that the problem is that you declared the ExtractTextPlugin, but you are using css and style loader instead.
Take a look at this setup for reference:
plugins
plugins: [
new ExtractTextPlugin({
filename: "css/bundle.css",
allChunks: true,
disable: process.env.NODE_ENV !== 'production'
}),
]
loader
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader?importLoaders=1'
})
}
This would use ExtractTextPlugin with production builds, and fallback to style-loader when using webpack-dev-server because ETP doesn't support hot reloading.
Feels so silly that I wasted as much time as I did, not getting why I was facing this same issue.
Just wanted to include it here for anyone else's reference as well...
Note, There could be other reasons for this issue as well.
My issue was that I hadn't added the meta tag w/ viewport.
FYR -
<meta name="viewport" content="width=device-width, initial-scale=1" />
Hope this helps.

How can I get grunt-autoprefixer to prefix uncompiled LESS files?

I'm working with LESS and I'd like to run grunt-autoprefixer on my LESS markup WITHOUT compiling LESS, because my LESS is compiled on my CMS automatically.
Is this possible?
Here's my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
concat: {
sqs_template: {
src: ['js/one.js', 'js/two.js'],
dest: 'sqs_template/scripts/app.js',
},
},
autoprefixer: {
options: {
remove: true,
},
multiple_files: {
expand: true,
flatten: true,
src: 'css/*.less',
dest: 'sqs_template/css/',
},
},
watch: {
js: {
files: ['js/**/*.js'],
tasks: ['concat'],
},
css: {
files: ['css/**/*.less'],
tasks: ['autoprefixer'],
},
},
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
};
Here's an example of the LESS I'm trying to prefix:
//------------------------------------*\
// SOME CSS
//------------------------------------*/
// Variables
#site-width: 960px;
#color: #333333;
// Mixins
.some-font {
font-family: sans-serif;
font-size: 1.5rem;
font-weight: bold;
}
.some-container {
display: flex;
max-width: #site-width;
margin: 0 auto;
.some-container-inner {
p {
.some-font;
color: #color;
}
}
}
I would want grunt-autoprefixer to do nothing but prefix my LESS, and put it into the sqs_template folder. Right now, grunt-autoprefixer errors because it doesn't seem to recognize the variables or mixins.
Is this possible?
Thanks!
Instead of autoprefixing, you could use mixins to prefix the needed values yourself. There's LESS-Prefix library that contains mixins for the usual suspects.
As a simple example, if you are using LESS-Prefix (or have a similar mixin yourself), you can just include the mixin file and type the CSS-properties prepended by a .
div {
.box-shadow(0px 0px 10px rgba(255,0,0,.5));
}
which passes the values through this mixin:
.box-shadow(#args) {
-webkit-box-shadow: #args;
box-shadow: #args;
}
and you'll end up with this:
div {
-webkit-box-shadow: 0px 0px 10px rgba(255,0,0,.5);
box-shadow: 0px 0px 10px rgba(255,0,0,.5);
}

Resources