commit
d59befea89
|
@ -1,6 +1,9 @@
|
|||
# Gulp Sass Changelog
|
||||
|
||||
## v2.0.0-alpha.1
|
||||
### March 26, 2015
|
||||
* **New** Added `renderSync` option that can be used through `sass.sync()`
|
||||
|
||||
### March 24, 2015
|
||||
* **Change** Updated to `node-sass` 3.0.0-alpha.1
|
||||
* **New** Added support for `gulp-sourcemaps` including tests
|
||||
|
|
18
README.md
18
README.md
|
@ -10,11 +10,10 @@ npm install gulp-sass --save-dev
|
|||
|
||||
# Basic Usage
|
||||
|
||||
Something like this:
|
||||
Something like this will compile your Sass files:
|
||||
|
||||
```javascript
|
||||
var gulp = require('gulp');
|
||||
var gutil = require('gulp-util');
|
||||
var sass = require('gulp-sass');
|
||||
|
||||
gulp.task('sass', function () {
|
||||
|
@ -24,6 +23,19 @@ gulp.task('sass', function () {
|
|||
});
|
||||
```
|
||||
|
||||
You can also compile synchronously, doing something like this:
|
||||
|
||||
```javascript
|
||||
var gulp = require('gulp');
|
||||
var sass = require('gulp-sass');
|
||||
|
||||
gulp.task('sass', function () {
|
||||
gulp.src('./scss/*.scss')
|
||||
.pipe(sass.sync().on('error', sass.logError))
|
||||
.pipe(gulp.dest('./css'));
|
||||
});
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
Pass in options just like you would for [`node-sass`](https://github.com/sass/node-sass#options); they will be passed along just as if you were using `node-sass`.
|
||||
|
@ -42,7 +54,7 @@ gulp.src('./scss/*.scss')
|
|||
.pipe(gulp.dest('./css'));
|
||||
```
|
||||
|
||||
By default, [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps) writes the source maps inline in the compiled CSS files. To write them to a separate file, specify a relative file path in the `sourcemaps.write()` function.
|
||||
By default, [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps) writes the source maps inline in the compiled CSS files. To write them to a separate file, specify a path relative to the `gulp.dest()` destination in the `sourcemaps.write()` function.
|
||||
|
||||
```javascript
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
|
|
79
index.js
79
index.js
|
@ -1,3 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
var gutil = require('gulp-util');
|
||||
var through = require('through2');
|
||||
var assign = require('object-assign');
|
||||
|
@ -10,12 +12,13 @@ var PLUGIN_NAME = 'gulp-sass';
|
|||
//////////////////////////////
|
||||
// Main Gulp Sass function
|
||||
//////////////////////////////
|
||||
var gulpSass = function gulpSass(options) {
|
||||
'use strict';
|
||||
|
||||
var gulpSass = function gulpSass(options, sync) {
|
||||
return through.obj(function(file, enc, cb) {
|
||||
var opts,
|
||||
callback;
|
||||
filePush,
|
||||
errorM,
|
||||
callback,
|
||||
result;
|
||||
|
||||
if (file.isNull()) {
|
||||
return cb(null, file);
|
||||
|
@ -36,33 +39,77 @@ var gulpSass = function gulpSass(options) {
|
|||
opts.omitSourceMapUrl = true;
|
||||
}
|
||||
|
||||
callback = function(error, obj) {
|
||||
if (error) {
|
||||
return cb(new gutil.PluginError(
|
||||
PLUGIN_NAME, error.message + ' ' + gutil.colors.cyan('line ' + error.line) + ' in ' + gutil.colors.magenta(error.file)
|
||||
));
|
||||
}
|
||||
//////////////////////////////
|
||||
// Handles returning the file to the stream
|
||||
//////////////////////////////
|
||||
filePush = function filePush(sassObj) {
|
||||
// Build Source Maps!
|
||||
if (obj.map) {
|
||||
applySourceMap(file, JSON.parse(obj.map.toString()));
|
||||
if (sassObj.map) {
|
||||
applySourceMap(file, JSON.parse(sassObj.map.toString()));
|
||||
}
|
||||
|
||||
file.contents = obj.css;
|
||||
file.contents = sassObj.css;
|
||||
file.path = gutil.replaceExtension(file.path, '.css');
|
||||
|
||||
cb(null, file);
|
||||
};
|
||||
|
||||
sass.render(opts, callback);
|
||||
//////////////////////////////
|
||||
// Handles error message
|
||||
//////////////////////////////
|
||||
errorM = function errorM(error) {
|
||||
var relativePath = path.relative(process.cwd(), error.file),
|
||||
message = '';
|
||||
|
||||
message += gutil.colors.underline(relativePath) + '\n';
|
||||
message += gutil.colors.gray(' ' + error.line + ':' + error.column) + ' ';
|
||||
message += error.message;
|
||||
|
||||
return cb(new gutil.PluginError(
|
||||
PLUGIN_NAME, message
|
||||
));
|
||||
};
|
||||
|
||||
if (sync !== true) {
|
||||
//////////////////////////////
|
||||
// Async Sass render
|
||||
//////////////////////////////
|
||||
callback = function(error, obj) {
|
||||
if (error) {
|
||||
return errorM(error);
|
||||
}
|
||||
filePush(obj);
|
||||
};
|
||||
|
||||
sass.render(opts, callback);
|
||||
}
|
||||
else {
|
||||
//////////////////////////////
|
||||
// Sync Sass render
|
||||
//////////////////////////////
|
||||
try {
|
||||
result = sass.renderSync(opts);
|
||||
|
||||
filePush(result);
|
||||
}
|
||||
catch(error) {
|
||||
return errorM(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
// Sync Sass render
|
||||
//////////////////////////////
|
||||
gulpSass.sync = function sync(options) {
|
||||
return gulpSass(options, true);
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
// Log errors nicely
|
||||
//////////////////////////////
|
||||
gulpSass.logError = function logError(error) {
|
||||
'use strict';
|
||||
|
||||
gutil.log(gutil.colors.red('[' + PLUGIN_NAME + '] ') + error.message);
|
||||
};
|
||||
|
||||
|
|
13
test/lint.js
13
test/lint.js
|
@ -10,11 +10,6 @@ var report;
|
|||
|
||||
describe('code style guide', function() {
|
||||
it('index.js should follow our lint style guide', function(done) {
|
||||
cli = new eslint.CLIEngine({
|
||||
'rules': {
|
||||
'strict': [ 2, 'function' ]
|
||||
}
|
||||
});
|
||||
report = cli.executeOnFiles(['index.js']);
|
||||
if (report.errorCount > 0 || report.warningCount > 0) {
|
||||
console.log(formatter(report.results));
|
||||
|
@ -26,11 +21,6 @@ describe('code style guide', function() {
|
|||
});
|
||||
|
||||
it('test/main.js should follow our lint style guide', function(done) {
|
||||
cli = new eslint.CLIEngine({
|
||||
'rules': {
|
||||
'strict': [ 2, 'global' ]
|
||||
}
|
||||
});
|
||||
report = cli.executeOnFiles(['test/main.js']);
|
||||
if (report.errorCount > 0 || report.warningCount > 0) {
|
||||
console.log(formatter(report.results));
|
||||
|
@ -44,8 +34,7 @@ describe('code style guide', function() {
|
|||
it('test/lint.js should follow our lint style guide', function(done) {
|
||||
cli = new eslint.CLIEngine({
|
||||
'rules': {
|
||||
'no-console': 0,
|
||||
'strict': [ 2, 'global' ]
|
||||
'no-console': 0
|
||||
}
|
||||
});
|
||||
report = cli.executeOnFiles(['test/lint.js']);
|
||||
|
|
140
test/main.js
140
test/main.js
|
@ -19,7 +19,7 @@ var createVinyl = function createVinyl(filename, contents) {
|
|||
});
|
||||
};
|
||||
|
||||
describe('gulp-sass', function() {
|
||||
describe('gulp-sass -- async compile', function() {
|
||||
it('should pass file when it isNull()', function(done) {
|
||||
var stream = sass();
|
||||
var emptyFile = {
|
||||
|
@ -119,7 +119,7 @@ describe('gulp-sass', function() {
|
|||
var stream = sass();
|
||||
|
||||
stream.on('error', function(err) {
|
||||
err.message.indexOf('property "font" must be followed by a \':\'').should.equal(0);
|
||||
err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
||||
done();
|
||||
});
|
||||
stream.write(errorFile);
|
||||
|
@ -154,3 +154,139 @@ describe('gulp-sass', function() {
|
|||
stream.write(sassFile);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gulp-sass -- sync compile', function() {
|
||||
it('should pass file when it isNull()', function(done) {
|
||||
var stream = sass.sync();
|
||||
var emptyFile = {
|
||||
'isNull': function () {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
stream.on('data', function(data) {
|
||||
data.should.equal(emptyFile);
|
||||
done();
|
||||
});
|
||||
stream.write(emptyFile);
|
||||
});
|
||||
|
||||
it('should emit error when file isStream()', function (done) {
|
||||
var stream = sass.sync();
|
||||
var streamFile = {
|
||||
'isNull': function () {
|
||||
return false;
|
||||
},
|
||||
'isStream': function () {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
stream.on('error', function(err) {
|
||||
err.message.should.equal('Streaming not supported');
|
||||
done();
|
||||
});
|
||||
stream.write(streamFile);
|
||||
});
|
||||
|
||||
it('should compile a single sass file', function(done) {
|
||||
var sassFile = createVinyl('mixins.scss');
|
||||
var stream = sass.sync();
|
||||
stream.on('data', function(cssFile) {
|
||||
should.exist(cssFile);
|
||||
should.exist(cssFile.path);
|
||||
should.exist(cssFile.relative);
|
||||
should.exist(cssFile.contents);
|
||||
String(cssFile.contents).should.equal(
|
||||
fs.readFileSync(path.join(__dirname, 'expected/mixins.css'), 'utf8')
|
||||
);
|
||||
done();
|
||||
});
|
||||
stream.write(sassFile);
|
||||
});
|
||||
|
||||
it('should compile multiple sass files', function(done) {
|
||||
var files = [
|
||||
createVinyl('mixins.scss'),
|
||||
createVinyl('variables.scss')
|
||||
];
|
||||
var stream = sass.sync();
|
||||
var mustSee = files.length;
|
||||
var expectedPath = 'expected/mixins.css';
|
||||
|
||||
stream.on('data', function(cssFile) {
|
||||
should.exist(cssFile);
|
||||
should.exist(cssFile.path);
|
||||
should.exist(cssFile.relative);
|
||||
should.exist(cssFile.contents);
|
||||
if (cssFile.path.indexOf('variables') !== -1) {
|
||||
expectedPath = 'expected/variables.css';
|
||||
}
|
||||
String(cssFile.contents).should.equal(
|
||||
fs.readFileSync(path.join(__dirname, expectedPath), 'utf8')
|
||||
);
|
||||
mustSee--;
|
||||
if (mustSee <= 0) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
files.forEach(function (file) {
|
||||
stream.write(file);
|
||||
});
|
||||
});
|
||||
|
||||
it('should compile files with partials in another folder', function(done) {
|
||||
var sassFile = createVinyl('inheritance.scss');
|
||||
var stream = sass.sync();
|
||||
stream.on('data', function(cssFile) {
|
||||
should.exist(cssFile);
|
||||
should.exist(cssFile.path);
|
||||
should.exist(cssFile.relative);
|
||||
should.exist(cssFile.contents);
|
||||
String(cssFile.contents).should.equal(
|
||||
fs.readFileSync(path.join(__dirname, 'expected/inheritance.css'), 'utf8')
|
||||
);
|
||||
done();
|
||||
});
|
||||
stream.write(sassFile);
|
||||
});
|
||||
|
||||
it('should handle sass errors', function(done) {
|
||||
var errorFile = createVinyl('error.scss');
|
||||
var stream = sass.sync();
|
||||
|
||||
stream.on('error', function(err) {
|
||||
err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
||||
done();
|
||||
});
|
||||
stream.write(errorFile);
|
||||
});
|
||||
|
||||
it('should work with gulp-sourcemaps', function(done) {
|
||||
var sassFile = createVinyl('inheritance.scss');
|
||||
|
||||
// Expected sources are relative to file.base
|
||||
var expectedSources = [
|
||||
'includes/_cats.scss',
|
||||
'inheritance.scss'
|
||||
];
|
||||
|
||||
var stream;
|
||||
|
||||
sassFile.sourceMap = '{' +
|
||||
'"version": 3,' +
|
||||
'"file": "scss/subdir/multilevelimport.scss",' +
|
||||
'"names": [],' +
|
||||
'"mappings": "",' +
|
||||
'"sources": [ "scss/subdir/multilevelimport.scss" ],' +
|
||||
'"sourcesContent": [ "@import ../inheritance;" ]' +
|
||||
'}';
|
||||
|
||||
stream = sass.sync();
|
||||
stream.on('data', function(cssFile) {
|
||||
should.exist(cssFile.sourceMap);
|
||||
assert.deepEqual(cssFile.sourceMap.sources, expectedSources);
|
||||
done();
|
||||
});
|
||||
stream.write(sassFile);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue