postcss-modules icon indicating copy to clipboard operation
postcss-modules copied to clipboard

Use postcss-modules generated css repeated

Open imseanpan opened this issue 8 years ago • 10 comments

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!?

imseanpan avatar Jun 23 '16 13:06 imseanpan

I'm getting this same issue. I'm using gulp instead of webpack.

lukelarsen avatar Sep 23 '16 15:09 lukelarsen

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?

btd avatar Sep 28 '16 13:09 btd

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.

lukelarsen avatar Sep 28 '16 15:09 lukelarsen

i have the same issue, duplicated css classes.

lfilipowicz avatar Dec 12 '16 15:12 lfilipowicz

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

wbyoung avatar Mar 04 '17 00:03 wbyoung

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

lukelarsen avatar Sep 07 '17 20:09 lukelarsen

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 avatar Mar 15 '18 15:03 AlexGalays

@AlexGalays For now postcss-loader and cssnano will probably help.

plesiecki avatar Mar 15 '18 17:03 plesiecki

@plesiecki Thanks; I had to use optimize-css-assets-webpack-plugin to make it work in my setup, but it should be equivalent.

AlexGalays avatar Mar 15 '18 17:03 AlexGalays

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.

blm768 avatar May 05 '22 16:05 blm768