postcss-modules
postcss-modules copied to clipboard
Use postcss-modules generated css repeated
HI, Q1 I want to use postcss-modules compile my css files, but out of the css generated duplicate.
1. common.css
.row { width : 100%; height : 100px; margin : 0; padding : 0; background-color : #000000; }
2. subCommon.css
.row { composes : row from './components.css'; background-color : #ff0430; }
3. webpack config
{ test : /\.css$/, loader: ExtractTextPlugin.extract("style-loader", ["css-loader?postcss-modules&importLoaders=1&sourceMap", "postcss-loader?parser=postcss-scss"]) }
4. postcss-modules config
postcss: function () { return [ psmodules({ generateScopedName: '[local]_[hash:base64:8]', getJSON : function (cssFileName, json) {} }), // cssnano(nanoConfig), ];
5 Compiled main.css file
.row_3hpoIFeb { width : 100%; height : 2.66667rem; margin : 0; padding : 0; background-color : #000000; } .row_3hpoIFeb { width : 100%; height : 2.66667rem; margin : 0; padding : 0; background-color : #000000; } .row_3D79gLaJ { background-color : #ff0430; }
common.css the row => [row_3hpoIFeb] is compiled twice!
Q2 Postcss-modules and cssnano can not be used together, compile exception!?
I'm getting this same issue. I'm using gulp instead of webpack.
Got the same issue today. But for me after disabling autoreset plugin issue disappeared. Could you post what plugins in which order are you using @lukelarsen @imseanpan?
I'm glad someone responded.
I'm using gulp to process everything. We are also using the Aurelia framework. Here is the file that does the css stuff:
import gulp from 'gulp';
import changedInPlace from 'gulp-changed-in-place';
import sourcemaps from 'gulp-sourcemaps';
import postcss from 'gulp-postcss';
import autoprefixer from 'autoprefixer';
import postcssmodules from 'postcss-modules';
import project from '../aurelia.json';
import {build} from 'aurelia-cli';
import path from 'path';
import { writeFileSync } from 'fs';
export default function processCSS() {
let processors = [
autoprefixer({browsers: ['last 1 version']}),
postcssmodules({
generateScopedName: '[name]__[local]___[hash:base64:5]',
getJSON: function(cssFileName, json) {
var cssName = path.basename(cssFileName, '.css');
var jsonFileName = path.resolve('./src/cssModules/' + cssName + '.css.json');
writeFileSync(jsonFileName, JSON.stringify(json));
}
})
];
return gulp.src(project.cssProcessor.source)
.pipe(changedInPlace({firstPass: true}))
.pipe(sourcemaps.init())
.pipe(postcss(processors))
.pipe(build.bundle());
}
Here is a sample of how the css files are added
<template>
<require from="app.css"></require>
<h1 css-module="header">${message}</h1>
<card value="hi from card"></card>
</template>
I don't see the autoreset
plugin anywhere in my project. I'd be happy to post a zip of my project if it would help to see it all.
i have the same issue, duplicated css classes.
I've just encountered the same issue with a build process that I configured that uses postcss-modules
.
I don't think there is a problem with postcss-modules
, though. In fact, it seems to me that everything is working exactly as expected (and that this issue should be closed).
Here's why: tools such as gulp
process files individually. And if you have a single CSS file that you process with postcss
that composes from another file, one would expect valid output which needs to contain CSS from both files.
But when you pipe it through gulp
or whatever build tool, you're probably sending common.css
through on it's own. And even if you aren't, if you use it to compose something from both a.css
and b.css
, each of those two files are processed on their own and should contain the common.css
module when compiled. One could argue that a flag should exist to disable including the common.css
when files are composed. I guess that'd be a valid approach, but it's possible to work with existing tools to get the same result, so it may not make sense to ask postcss-modules
to maintain that functionality.
To resolve this, you can simply use cssnano
after concatenating your JS. I find this easy to do by using postcss-load-config
(which is actually going to be part of the PostCSS CLI soon).
Here's how with gulp
:
// gulpfile.js
import gulp from 'gulp';
import postcss from 'gulp-postcss';
import postcssrc from 'postcss-load-config';
gulp.task('styles', () => {
const { plugins, options } = await postcssrc();
const { plugins: minPlugins, options: minOptions } =
await postcssrc({ minifier: true });
return gulp.src(['src/**/*.css'])
.pipe(sourcemaps.init())
.pipe(postcss(plugins, options))
.pipe(concat('styles.css'))
.pipe(postcss(minPlugins, minOptions))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/public'));
});
// postcss.config.js
module.exports = (ctx) => {
const plugins = [];
if (ctx.minifier) {
plugins.push(
require('cssnano')({})
);
} else {
plugins.push(
require('postcss-import')(),
require('postcss-cssnext')(),
require('postcss-modules')()
);
}
return { plugins };
};
Thanks for the comments. In my build I don't think cssnano will work. I'm using Aurelia JS and while everything is working properly it outputs the css for each component in its own
Tiny repro here : https://github.com/AlexGalays/repro-webpack-cssloader
Expected: Only two classes in the extracted dist/root.css
Actual: One of the two classes is outputted twice.
Looks like the trigger is for a className to be imported both in JS (to be used as a className string) and CSS (via composes
)
@AlexGalays For now postcss-loader and cssnano will probably help.
@plesiecki Thanks; I had to use optimize-css-assets-webpack-plugin to make it work in my setup, but it should be equivalent.
This behavior seems to be fundamentally different from the original design intention, which seems to have been that composes
would just tack the composed class name onto the export symbol instead of actually pulling in the composed class's style rules. The actual CSS Modules spec underspecifies the behavior of composes
, so it's not clear to me whether there was an intentional change at some point.