Skip to content

Commit 69e79d4

Browse files
committed
Merge pull request #61 from css-modules/fix-duplicate-rules
Fix duplicate rules
2 parents 882f90f + 8b05764 commit 69e79d4

File tree

6 files changed

+47
-25
lines changed

6 files changed

+47
-25
lines changed

index.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,30 @@ function normalizeManifestPaths (tokensByFile, rootDir) {
7474
return output;
7575
}
7676

77+
function dedupeSources (sources) {
78+
var foundHashes = {}
79+
Object.keys(sources).forEach(function (key) {
80+
var hash = stringHash(sources[key]);
81+
if (foundHashes[hash]) {
82+
delete sources[key];
83+
}
84+
else {
85+
foundHashes[hash] = true;
86+
}
87+
})
88+
}
89+
7790
var cssExt = /\.css$/;
7891

7992
// caches
8093
//
8194
// persist these for as long as the process is running. #32
8295

83-
// keep track of css files visited
84-
var filenames = [];
85-
8696
// keep track of all tokens so we can avoid duplicates
8797
var tokensByFile = {};
8898

89-
// keep track of all source files for later builds: when
90-
// using watchify, not all files will be caught on subsequent
91-
// bundles
92-
var sourceByFile = {};
99+
// we need a separate loader for each entry point
100+
var loadersByFile = {};
93101

94102
module.exports = function (browserify, options) {
95103
options = options || {};
@@ -103,9 +111,10 @@ module.exports = function (browserify, options) {
103111
var jsonOutFilename = options.json || options.jsonOutput;
104112
var sourceKey = cssOutFilename;
105113

106-
// keying our source caches by the name of our output file means we can
107-
// isolate css compilation of seperate bundles that are running in parallel
108-
sourceByFile[sourceKey] = sourceByFile[sourceKey] || {};
114+
var loader = loadersByFile[sourceKey];
115+
if (!loader) {
116+
loader = loadersByFile[sourceKey] = new FileSystemLoader(rootDir, plugins);
117+
}
109118

110119
// PostCSS plugins passed to FileSystemLoader
111120
var plugins = options.use || options.u;
@@ -158,10 +167,6 @@ module.exports = function (browserify, options) {
158167
return through();
159168
}
160169

161-
// collect visited filenames
162-
filenames.push(filename);
163-
164-
var loader = new FileSystemLoader(rootDir, plugins);
165170
return through(function noop () {}, function end () {
166171
var self = this;
167172

@@ -170,11 +175,6 @@ module.exports = function (browserify, options) {
170175

171176
assign(tokensByFile, loader.tokensByFile);
172177

173-
// store this file's source to be written out to disk later
174-
sourceByFile[sourceKey][filename] = loader.finalSource;
175-
176-
compiledCssStream.push(loader.finalSource);
177-
178178
self.queue(output);
179179
self.queue(null);
180180
}, function (err) {
@@ -195,19 +195,19 @@ module.exports = function (browserify, options) {
195195
bundle.emit('css stream', compiledCssStream);
196196

197197
bundle.on('end', function () {
198+
// under certain conditions (eg. with shared libraries) we can end up with
199+
// multiple occurrences of the same rule, so we need to remove duplicates
200+
dedupeSources(loader.sources)
201+
198202
// Combine the collected sources for a single bundle into a single CSS file
199-
var files = Object.keys(sourceByFile[sourceKey]);
200-
var css;
203+
var css = loader.finalSource;
201204

202205
// end the output stream
206+
compiledCssStream.push(css);
203207
compiledCssStream.push(null);
204208

205209
// write the css file
206210
if (cssOutFilename) {
207-
css = files.map(function (file) {
208-
return sourceByFile[sourceKey][file];
209-
}).join('\n');
210-
211211
fs.writeFile(cssOutFilename, css, function (err) {
212212
if (err) {
213213
browserify.emit('error', err);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
._shared__shared {
2+
background: #000;
3+
}
4+
._styles_1__foo {
5+
color: #F00;
6+
}
7+
._styles_2__bar {
8+
background: #BAA;
9+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('./styles-1.css');
2+
require('./styles-2.css');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.shared {
2+
background: #000;
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.foo {
2+
composes: shared from "./shared.css";
3+
color: #F00;
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.bar {
2+
composes: shared from "./shared.css";
3+
background: #BAA;
4+
}

0 commit comments

Comments
 (0)