From 6f3dc4e433857dac621f8511838d8ac94d479c9f Mon Sep 17 00:00:00 2001 From: Alexey Litvinov Date: Wed, 2 Sep 2015 01:54:40 +0300 Subject: [PATCH 1/3] falling demo --- node_modules/cool-styles/bar.css | 4 ++++ node_modules/cool-styles/foo.css | 1 + 2 files changed, 5 insertions(+) create mode 100644 node_modules/cool-styles/bar.css diff --git a/node_modules/cool-styles/bar.css b/node_modules/cool-styles/bar.css new file mode 100644 index 0000000..e86b2fc --- /dev/null +++ b/node_modules/cool-styles/bar.css @@ -0,0 +1,4 @@ +.example +{ + background: #369; +} diff --git a/node_modules/cool-styles/foo.css b/node_modules/cool-styles/foo.css index 65f95db..e584fbf 100644 --- a/node_modules/cool-styles/foo.css +++ b/node_modules/cool-styles/foo.css @@ -1,3 +1,4 @@ .example { color: #F00; + composes: example from './bar.css'; } From 227d222258f0ddc9936bb6cda3531b68f06495ec Mon Sep 17 00:00:00 2001 From: Alexey Litvinov Date: Thu, 10 Sep 2015 02:10:08 +0300 Subject: [PATCH 2/3] using absolute paths for the source files --- src/file-system-loader.js | 27 ++++++++++--------- src/index.js | 2 +- src/parser.js | 6 ++--- test/test-cases.js | 22 +++++++++++---- .../compose-node-module/expected.css | 6 ++++- .../compose-node-module/expected.json | 2 +- 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/file-system-loader.js b/src/file-system-loader.js index 2a3f47d..d1cd037 100644 --- a/src/file-system-loader.js +++ b/src/file-system-loader.js @@ -28,31 +28,34 @@ export default class FileSystemLoader { this.tokensByFile = {}; } - fetch( _newPath, relativeTo, _trace ) { + fetch( _newPath, sourcePath, _trace ) { let newPath = _newPath.replace( /^["']|["']$/g, "" ), trace = _trace || String.fromCharCode( this.importNr++ ) + return new Promise( ( resolve, reject ) => { - let relativeDir = path.dirname( relativeTo ), - rootRelativePath = path.resolve( relativeDir, newPath ), - fileRelativePath = path.resolve( path.join( this.root, relativeDir ), newPath ) + let filename = path.resolve( path.dirname( sourcePath ), newPath ); - // if the path is not relative or absolute, try to resolve it in node_modules if (newPath[0] !== '.' && newPath[0] !== '/') { try { - fileRelativePath = require.resolve(newPath); + filename = require.resolve( newPath ) + } + catch (e) { + return void reject(e) } - catch (e) {} } - const tokens = this.tokensByFile[fileRelativePath] + const tokens = this.tokensByFile[filename] if (tokens) { return resolve(tokens) } - fs.readFile( fileRelativePath, "utf-8", ( err, source ) => { - if ( err ) reject( err ) - this.core.load( source, rootRelativePath, trace, this.fetch.bind( this ) ) + fs.readFile( filename, "utf-8", ( err, source ) => { + if ( err ) { + return void reject( err ) + } + + this.core.load( source, filename, trace, this.fetch.bind( this ) ) .then( ( { injectableSource, exportTokens } ) => { this.sources[trace] = injectableSource - this.tokensByFile[fileRelativePath] = exportTokens + this.tokensByFile[filename] = exportTokens resolve( exportTokens ) }, reject ) } ) diff --git a/src/index.js b/src/index.js index f5994ef..1cdd35d 100644 --- a/src/index.js +++ b/src/index.js @@ -14,7 +14,7 @@ export default class Core { let parser = new Parser( pathFetcher, trace ) return postcss( this.plugins.concat( [parser.plugin] ) ) - .process( sourceString, { from: "/" + sourcePath } ) + .process( sourceString, { from: sourcePath } ) .then( result => { return { injectableSource: result.css, exportTokens: parser.exportTokens } } ) diff --git a/src/parser.js b/src/parser.js index 536e9cd..5ed9f11 100644 --- a/src/parser.js +++ b/src/parser.js @@ -51,16 +51,16 @@ export default class Parser { exportNode.removeSelf() } - fetchImport( importNode, relativeTo, depNr ) { + fetchImport( importNode, sourcePath, depNr ) { let file = importNode.selector.match( importRegexp )[1], depTrace = this.trace + String.fromCharCode(depNr) - return this.pathFetcher( file, relativeTo, depTrace ).then( exports => { + return this.pathFetcher( file, sourcePath, depTrace ).then( exports => { importNode.each( decl => { if ( decl.type == 'decl' ) { this.translations[decl.prop] = exports[decl.value] } } ) importNode.removeSelf() - }, err => console.log( err ) ) + } ) } } diff --git a/test/test-cases.js b/test/test-cases.js index c6adcff..2268acc 100644 --- a/test/test-cases.js +++ b/test/test-cases.js @@ -5,6 +5,10 @@ import fs from "fs" import path from "path" import FileSystemLoader from "../src/file-system-loader" +import PostcssLocal from "postcss-modules-local-by-default" +import PostcssExtract from "postcss-modules-extract-imports" +import PostcssScope from "postcss-modules-scope" + let normalize = ( str ) => { return str.replace( /\r\n?/g, "\n" ); } @@ -14,6 +18,14 @@ const pipelines = { "cssi": [] } +const getPlugins = rootDir => { + return [ + PostcssLocal, + PostcssExtract, + new PostcssScope({rootDir: rootDir}) + ]; +} + Object.keys( pipelines ).forEach( dirname => { describe( dirname, () => { let testDir = path.join( __dirname, dirname ) @@ -21,9 +33,9 @@ Object.keys( pipelines ).forEach( dirname => { if ( fs.existsSync( path.join( testDir, testCase, "source.css" ) ) ) { it( "should " + testCase.replace( /-/g, " " ), done => { let expected = normalize( fs.readFileSync( path.join( testDir, testCase, "expected.css" ), "utf-8" ) ) - let loader = new FileSystemLoader( testDir, pipelines[dirname] ) + let loader = new FileSystemLoader( testDir, pipelines[dirname] || getPlugins(testDir) ) let expectedTokens = JSON.parse( fs.readFileSync( path.join( testDir, testCase, "expected.json" ), "utf-8" ) ) - loader.fetch( `${testCase}/source.css`, "/" ).then( tokens => { + loader.fetch( path.join( testDir, testCase, "source.css" ) ).then( tokens => { assert.equal( loader.finalSource, expected ) assert.equal( JSON.stringify( tokens ), JSON.stringify( expectedTokens ) ) } ).then( done, done ) @@ -41,10 +53,10 @@ describe( 'multiple sources', () => { if ( fs.existsSync( path.join( testDir, testCase, "source1.css" ) ) ) { it( "should " + testCase.replace( /-/g, " " ), done => { let expected = normalize( fs.readFileSync( path.join( testDir, testCase, "expected.css" ), "utf-8" ) ) - let loader = new FileSystemLoader( testDir, pipelines[dirname] ) + let loader = new FileSystemLoader( testDir, pipelines[dirname] || getPlugins(testDir) ) let expectedTokens = JSON.parse( fs.readFileSync( path.join( testDir, testCase, "expected.json" ), "utf-8" ) ) - loader.fetch( `${testCase}/source1.css`, "/" ).then( tokens1 => { - loader.fetch( `${testCase}/source2.css`, "/" ).then( tokens2 => { + loader.fetch( path.join( testDir, testCase, "source1.css" ) ).then( tokens1 => { + loader.fetch( path.join( testDir, testCase, "source2.css" ) ).then( tokens2 => { assert.equal( loader.finalSource, expected ) const tokens = Object.assign({}, tokens1, tokens2); assert.equal( JSON.stringify( tokens ), JSON.stringify( expectedTokens ) ) diff --git a/test/test-cases/compose-node-module/expected.css b/test/test-cases/compose-node-module/expected.css index 0667b94..1d3c5e1 100644 --- a/test/test-cases/compose-node-module/expected.css +++ b/test/test-cases/compose-node-module/expected.css @@ -1,4 +1,8 @@ -._compose_node_module_cool_styles_foo__example { +._node_modules_cool_styles_bar__example +{ + background: #369; +} +._node_modules_cool_styles_foo__example { color: #F00; } ._compose_node_module_source__foo { diff --git a/test/test-cases/compose-node-module/expected.json b/test/test-cases/compose-node-module/expected.json index a57448c..1f397c3 100644 --- a/test/test-cases/compose-node-module/expected.json +++ b/test/test-cases/compose-node-module/expected.json @@ -1,3 +1,3 @@ { - "foo": "_compose_node_module_source__foo _compose_node_module_cool_styles_foo__example" + "foo": "_compose_node_module_source__foo _node_modules_cool_styles_foo__example _node_modules_cool_styles_bar__example" } From fa22e232f6d3aadb788b5d28996c745c8f2d3b65 Mon Sep 17 00:00:00 2001 From: Alexey Litvinov Date: Thu, 10 Sep 2015 02:15:13 +0300 Subject: [PATCH 3/3] fork for the demo --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ecec1f9..1f58432 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "dependencies": { "postcss": "^4.1.11", "postcss-modules-extract-imports": "^0.0.5", - "postcss-modules-local-by-default": "^0.0.9", - "postcss-modules-scope": "^0.0.8" + "postcss-modules-local-by-default": "^0.0.9" }, "devDependencies": { "babel": "^5.5.4", @@ -21,6 +20,8 @@ "mocha": "^2.2.5" }, "scripts": { + "preinstall": "rm -rf node_modules/postcss-modules-scope", + "postinstall": "git clone https://github.com/sullenor/postcss-modules-scope.git node_modules/postcss-modules-scope && cd node_modules/postcss-modules-scope && git checkout absolute-paths && npm i", "lint": "eslint src", "build": "babel --out-dir lib src", "autotest": "chokidar src test -c 'npm test'",