├── .gitignore ├── .travis.yml ├── LICENCE ├── README.md ├── index.js ├── package.json └── test ├── badsource.scss ├── body.css ├── expected.css ├── precedence └── body.css ├── source.scss └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | - "0.11" 5 | - "0.10" 6 | - "iojs" 7 | - "iojs-v1.0.4" 8 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Fetch! 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node Sass CSS importer [![Build Status](https://travis-ci.org/fetch/node-sass-css-importer.svg?branch=master)](https://travis-ci.org/fetch/node-sass-css-importer) [![npmjs](https://badge.fury.io/js/node-sass-css-importer.svg)](https://www.npmjs.com/package/node-sass-css-importer) 2 | 3 | The Node Sass CSS Importer allows you to import a CSS file into Sass. Just like the [Sass CSS importer](https://github.com/chriseppstein/sass-css-importer). 4 | 5 | ## Stylesheet Syntax 6 | 7 | The `.css` extension triggers special behavior in Sass so you cannot 8 | import a file with a CSS extension. To work around this, you must use a 9 | special prefix on the import string and omit the extension. 10 | 11 | ```scss 12 | @import "CSS:some_folder/some_css_file" 13 | ``` 14 | 15 | ## Installation 16 | 17 | ``` 18 | npm install node-sass-css-importer --save[-dev] 19 | ``` 20 | 21 | ## Usage 22 | 23 | ```js 24 | var sass = require('node-sass') 25 | , CssImporter = require('node-sass-css-importer')({ 26 | import_paths: ['app/assets/stylesheets', 'app/assets/components'] 27 | }); 28 | 29 | sass.renderSync({ 30 | file: 'source.scss', 31 | importer: [CssImporter] 32 | }); 33 | 34 | ``` 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | , path = require('path'); 3 | 4 | module.exports = function(options) { 5 | options = options || {import_paths: []}; 6 | 7 | var import_paths 8 | , import_paths_len; 9 | 10 | return function(url, prev, done) { 11 | if (url.slice(0, 4) !== 'CSS:') { 12 | return done(); 13 | } 14 | 15 | import_paths = options.import_paths.slice(); 16 | if (fs.existsSync(prev)) { 17 | import_paths.unshift(path.dirname(prev)); 18 | } 19 | import_paths_len = import_paths.length; 20 | 21 | if (import_paths_len === 0) { 22 | return done(); 23 | } 24 | 25 | var css_path = url.slice(4) + '.css' 26 | , css_filepath, i = 0, import_path; 27 | 28 | for (; i < import_paths_len; ++i) { 29 | import_path = import_paths[i]; 30 | css_filepath = path.join(import_path, css_path); 31 | if (fs.existsSync(css_filepath)) { 32 | fs.readFile(css_filepath, function(err, data) { 33 | if (err) { 34 | return done(err); 35 | } 36 | done({contents: data.toString()}); 37 | }); 38 | return; 39 | } 40 | } 41 | return done(new Error('Specified CSS file not found! ("' + css_path + '" referenced from "' + prev + '")')); 42 | }; 43 | }; 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-sass-css-importer", 3 | "version": "0.0.3", 4 | "description": "css importer for node-sass", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test/test.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git@github.com:fetch/node-sass-css-importer.git" 12 | }, 13 | "keywords": [ 14 | "node", 15 | "sass", 16 | "css", 17 | "import" 18 | ], 19 | "author": "Koen Punt ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/fetch/node-sass-css-importer/issues" 23 | }, 24 | "homepage": "https://github.com/fetch/node-sass-css-importer", 25 | "devDependencies": { 26 | "node-sass": "^3.3.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/badsource.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 10px; 3 | } 4 | 5 | @import "CSS:doesntexist"; 6 | -------------------------------------------------------------------------------- /test/body.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | } 4 | -------------------------------------------------------------------------------- /test/expected.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 10px; } 3 | 4 | body { 5 | padding: 10px; } 6 | -------------------------------------------------------------------------------- /test/precedence/body.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /test/source.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 10px; 3 | } 4 | 5 | @import "CSS:body"; 6 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | , path = require('path') 3 | , assert = require('assert'); 4 | 5 | var node = require('node-sass') 6 | , cssImporter = require('../'); 7 | 8 | node.render({ 9 | file: path.join(__dirname, 'source.scss'), 10 | importer: cssImporter({import_paths: [path.join(__dirname, 'precedence')]}) 11 | }, function(err, actual) { 12 | assert.equal(err, null); 13 | fs.readFile(path.join(__dirname, 'expected.css'), function(err, expected) { 14 | assert.equal(err, null); 15 | assert.equal(actual.css.toString(), expected.toString()); 16 | }); 17 | }); 18 | 19 | node.render({ 20 | data: 'html{font-size: 10px}@import "CSS:body";', 21 | importer: cssImporter({import_paths: [__dirname]}) 22 | }, function(err, actual) { 23 | assert.equal(err, null); 24 | fs.readFile(path.join(__dirname, 'expected.css'), function(err, expected) { 25 | assert.equal(err, null); 26 | assert.equal(actual.css.toString(), expected.toString()); 27 | }); 28 | }); 29 | 30 | node.render({ 31 | file: path.join(__dirname, 'badsource.scss'), 32 | importer: cssImporter({import_paths: [__dirname]}) 33 | }, function(err, actual) { 34 | assert.notEqual(err, null); 35 | assert.equal(err.message.slice(0, 29), 'Specified CSS file not found!'); 36 | }); 37 | 38 | node.render({ 39 | data: 'html{font-size: 10px}@import "CSS:doesntexist";', 40 | importer: cssImporter({import_paths: [__dirname]}) 41 | }, function(err, actual) { 42 | assert.notEqual(err, null); 43 | assert.equal(err.message.slice(0, 29), 'Specified CSS file not found!'); 44 | }); 45 | --------------------------------------------------------------------------------