Skip to content

Commit e94a1fb

Browse files
committed
Merge pull request css-modules#2 from css-modules/source-order-failing-test
Source order failing test
2 parents 381e4d1 + 1e15f28 commit e94a1fb

File tree

11 files changed

+77
-15
lines changed

11 files changed

+77
-15
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"dependencies": {
1010
"postcss": "^4.1.11",
11-
"postcss-modules-extract-imports": "0.0.1",
11+
"postcss-modules-extract-imports": "0.0.2",
1212
"postcss-modules-local-by-default": "0.0.7",
1313
"postcss-modules-scope": "0.0.3"
1414
},
@@ -17,7 +17,7 @@
1717
"babel-eslint": "^3.1.9",
1818
"babelify": "^6.1.2",
1919
"chokidar-cli": "^0.2.1",
20-
"eslint": "^0.21.2",
20+
"eslint": "^0.22.1",
2121
"mocha": "^2.2.5"
2222
},
2323
"scripts": {

src/file-system-loader.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,51 @@ import Core from './index.js'
22
import fs from 'fs'
33
import path from 'path'
44

5+
// Sorts dependencies in the following way:
6+
// AAA comes before AA and A
7+
// AB comes after AA and before A
8+
// All Bs come after all As
9+
// This ensures that the files are always returned in the following order:
10+
// - In the order they were required, except
11+
// - After all their dependencies
12+
const traceKeySorter = ( a, b ) => {
13+
if ( a.length < b.length ) {
14+
return a < b.substring( 0, a.length ) ? -1 : 1
15+
} else if ( a.length > b.length ) {
16+
return a.substring( 0, b.length ) <= b ? -1 : 1
17+
} else {
18+
return a < b ? -1 : 1
19+
}
20+
};
21+
522
export default class FileSystemLoader {
623
constructor( root ) {
724
this.root = root
8-
this.sources = []
25+
this.sources = {}
926
this.seenPaths = new Set()
27+
this.importNr = 0
1028
}
1129

12-
fetch( _newPath, relativeTo ) {
13-
let newPath = _newPath.replace( /^["']|["']$/g, "" )
30+
fetch( _newPath, relativeTo, _trace ) {
31+
let newPath = _newPath.replace( /^["']|["']$/g, "" ),
32+
trace = _trace || String.fromCharCode( this.importNr++ )
1433
return new Promise( ( resolve, reject ) => {
1534
let rootRelativePath = path.resolve( path.dirname( relativeTo ), newPath ),
1635
fileRelativePath = this.root + rootRelativePath
1736

1837
fs.readFile( fileRelativePath, "utf-8", ( err, source ) => {
1938
if ( err ) reject( err )
20-
Core.load( source, rootRelativePath, this.fetch.bind( this ) )
39+
Core.load( source, rootRelativePath, trace, this.fetch.bind( this ) )
2140
.then( ( { injectableSource, exportTokens } ) => {
22-
this.sources.push( injectableSource )
41+
this.sources[trace] = injectableSource
2342
resolve( exportTokens )
2443
}, reject )
2544
} )
2645
} )
2746
}
47+
48+
get finalSource() {
49+
return Object.keys( this.sources ).sort( traceKeySorter ).map( s => this.sources[s] )
50+
.join( "" )
51+
}
2852
}

src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export default {
1818
scope
1919
],
2020

21-
load( sourceString, sourcePath, pathFetcher ) {
22-
let parser = new Parser( pathFetcher )
21+
load( sourceString, sourcePath, trace, pathFetcher ) {
22+
let parser = new Parser( pathFetcher, trace )
2323

2424
return postcss( this.plugins.concat( [parser.plugin] ) )
2525
.process( sourceString, { from: "/" + sourcePath } )

src/parser.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
const importRegexp = /^:import\((.+)\)$/
22

33
export default class Parser {
4-
constructor( pathFetcher ) {
4+
constructor( pathFetcher, trace ) {
55
this.pathFetcher = pathFetcher
66
this.plugin = this.plugin.bind( this )
77
this.exportTokens = {}
88
this.translations = {}
9+
this.trace = trace
910
}
1011

1112
plugin( css, result ) {
@@ -17,7 +18,7 @@ export default class Parser {
1718
let imports = []
1819
css.each( node => {
1920
if ( node.type == "rule" && node.selector.match( importRegexp ) ) {
20-
imports.push( this.fetchImport( node, css.source.input.from ) )
21+
imports.push( this.fetchImport( node, css.source.input.from, imports.length ) )
2122
}
2223
} )
2324
return imports
@@ -41,9 +42,10 @@ export default class Parser {
4142
exportNode.removeSelf()
4243
}
4344

44-
fetchImport( importNode, relativeTo ) {
45-
let file = importNode.selector.match( importRegexp )[1]
46-
return this.pathFetcher( file, relativeTo ).then( exports => {
45+
fetchImport( importNode, relativeTo, depNr ) {
46+
let file = importNode.selector.match( importRegexp )[1],
47+
depTrace = this.trace + String.fromCharCode(depNr)
48+
return this.pathFetcher( file, relativeTo, depTrace ).then( exports => {
4749
importNode.each( decl => {
4850
if ( decl.type == 'decl' ) {
4951
this.translations[decl.value] = exports[decl.prop]

test/test-cases.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe( "test-cases", () => {
1818
let loader = new FileSystemLoader( testDir )
1919
let expectedTokens = JSON.parse( fs.readFileSync( path.join( testDir, testCase, "expected.json" ), "utf-8" ) )
2020
loader.fetch( `${testCase}/source.css`, "/" ).then( tokens => {
21-
assert.equal( loader.sources.join( "" ), expected )
21+
assert.equal( loader.finalSource, expected )
2222
assert.equal( JSON.stringify( tokens ), JSON.stringify( expectedTokens ) )
2323
} ).then( done, done )
2424
} );
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.b {
2+
extends: d from "./d.css";
3+
color: #bbb;
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.c {
2+
color: #ccc;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.d {
2+
color: #ddd;
3+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
._multiple_dependencies_d__d {
3+
color: #ddd;
4+
}
5+
6+
._multiple_dependencies_b__b {
7+
color: #bbb;
8+
}
9+
10+
._multiple_dependencies_c__c {
11+
color: #ccc;
12+
}
13+
14+
._multiple_dependencies_source__a {
15+
color: #aaa;
16+
}
17+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"a": "_multiple_dependencies_source__a _multiple_dependencies_b__b _multiple_dependencies_d__d _multiple_dependencies_c__c"
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.a {
2+
extends: b from "./b.css";
3+
extends: c from "./c.css";
4+
color: #aaa;
5+
}
6+

0 commit comments

Comments
 (0)