Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use postcss-modules generated css repeated #32

Open
imseanpan opened this issue Jun 23, 2016 · 10 comments
Open

Use postcss-modules generated css repeated #32

imseanpan opened this issue Jun 23, 2016 · 10 comments

Comments

@imseanpan
Copy link

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

@lukelarsen
Copy link

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

@btd
Copy link

btd commented Sep 28, 2016

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?

@lukelarsen
Copy link

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.

@lfilipowicz
Copy link

i have the same issue, duplicated css classes.

@wbyoung
Copy link

wbyoung commented Mar 4, 2017

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

@lukelarsen
Copy link

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 <style> tag. cssnano is run on each one of those so it doesn't see the duplicates. :(

@AlexGalays
Copy link

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)

@plesiecki
Copy link

plesiecki commented Mar 15, 2018

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

@AlexGalays
Copy link

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

@blm768
Copy link

blm768 commented May 5, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants