madyankin / postcss-modules

PostCSS plugin to use CSS Modules everywhere
MIT License
1.59k stars 86 forks source link

Use postcss-modules generated css repeated #32

Open imseanpan opened 8 years ago

imseanpan commented 8 years ago

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 commented 8 years ago

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

btd commented 8 years ago

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 commented 8 years ago

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 commented 7 years ago

i have the same issue, duplicated css classes.

wbyoung commented 7 years ago

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 commented 7 years ago

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