css-modules / css-modulesify

A browserify plugin to load CSS Modules
MIT License
403 stars 47 forks source link

Multiple browserify instances get mixed up #76

Closed tjallingt closed 8 years ago

tjallingt commented 8 years ago

Probably related to #57.

I have a bit strange setup with gulp and browserify but I would still expect the following to work:

// build whole app
gulp.task('build', ['build-screen', 'build-remote']);

// calls browserify to compile jsx files for the screen
gulp.task('build-screen', function() {
    bundle('screen');
});

// calls browserify to compile jsx files for the remote
gulp.task('build-remote', function() {
    bundle('remote');
});

function bundle(entry) {
    return browserify({ 
        entries: entry,
        extensions: ['.jsx'],
        basedir: './src',
    })
    .plugin(modulesify, {
        rootDir: './src',
        output: './static/css/' + entry + '.css',
    })
    .transform(babelify.configure({ presets: ["es2015", "react", "stage-0"] }))
    .bundle()
    .pipe(source(entry))
    .pipe(rename({ extname: '.js' }))
    .pipe(gulp.dest('./static/js'));
}

Instead of doing the expected (outputting 'screen.css' and 'remote.css' with their respective contents) it dumps all the css (for both instances) in 'remote.css' and produces an empty 'screen.css'.

When using the css stream like so:

function bundle(entry) {
    return browserify({ 
        entries: entry,
        extensions: ['.jsx'],
        basedir: './src',
    })
    .plugin(modulesify, {
        rootDir: './src',
    })
    .transform(babelify.configure({ presets: ["es2015", "react", "stage-0"] }))
    .bundle()
    .on('css stream', function (css) {
        css.pipe(fs.createWriteStream( './static/css/' + entry +'.css'));
    })
    .pipe(source(entry))
    .pipe(rename({ extname: '.js' }))
    .pipe(gulp.dest('./static/js'));

It outputs all of the imported css to both files instead of only the relevant css.

I hope you can tell me what (if anything) I'm doing wrong :smile:

tjallingt commented 8 years ago

Found the source of the issue: https://github.com/css-modules/css-modulesify/blob/master/index.js#L145-L149

If there are multiple loadersByFile the current loader will be the one that is called last, therefore Cmify will use the last added loader, this can be fixed relatively easily by adding the sourcekey to the Cmify opts and adding: var loader = loadersByFile[this.opts.sourcekey] to inside the flush method.

I will create a pull request shortly.