Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
var gulp = require('gulp');
var path = require('path');

var BUILD_CONFIGS = [
'./test/webpack-default.config',
'./test/webpack-explicit-plugins.config',
'./test/webpack-with-packs.config',
'./test/webpack-incorrect-using-packs.config',
'./test/webpack-custom-parser.config'
];

gulp.task('clean', function (done) {
var fs = require('fs-extra');
fs.remove(path.join(__dirname, 'build'), done);
Expand All @@ -17,12 +25,17 @@ gulp.task('lint', function () {
.pipe(eslint.failAfterError());
});

gulp.task('build', ['clean'], function () {
var webpack = require('webpack-stream');
return gulp.src('')
.pipe(webpack(require('./test/webpack.config')))
.pipe(gulp.dest('build/'));
});
BUILD_CONFIGS
.forEach(function (configFile) {
gulp.task(configFile, ['clean'], function () {
var webpack = require('webpack-stream');
return gulp.src('')
.pipe(webpack(require(configFile)))
.pipe(gulp.dest('build/'));
});
});

gulp.task('build', BUILD_CONFIGS);

gulp.task('test', ['build'], function () {
var mocha = require('gulp-mocha');
Expand Down
145 changes: 68 additions & 77 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var loaderUtils = require('loader-utils');
var postcss = require('postcss');
var assign = require('./lib/assign');
var getConfiguration = require('./lib/configuration');

function PostCSSLoaderError(error) {
Error.call(this);
Expand All @@ -25,90 +27,79 @@ module.exports = function (source, map) {
var file = this.resourcePath;
var params = loaderUtils.parseQuery(this.query);

var opts = {
from: file,
to: file,
map: {
inline: params.sourceMap === 'inline',
annotation: false
var options = this.options.postcss;
var pack = params.pack;
var loader = this;
var callback = this.async();

getConfiguration(options, pack, function (err, config) {
if (err) {
callback(err);
return;
}
};

if ( typeof map === 'string' ) map = JSON.parse(map);
if ( map && map.mappings ) opts.map.prev = map;
var plugins = config.plugins;
var exec = config.exec;

var options = this.options.postcss;
if ( typeof options === 'function' ) {
options = options.call(this, this);
}
var opts = assign({}, config.options, {
from: file,
to : file,
map: {
inline: params.sourceMap === 'inline',
annotation: false
}
});

var plugins;
var exec;
if ( typeof options === 'undefined' ) {
plugins = [];
} else if ( Array.isArray(options) ) {
plugins = options;
} else {
plugins = options.plugins || options.defaults;
opts.stringifier = options.stringifier;
opts.parser = options.parser;
opts.syntax = options.syntax;
exec = options.exec;
}
if ( params.pack ) {
plugins = options[params.pack];
if ( !plugins ) {
throw new Error('PostCSS plugin pack is not defined in options');
}
}
if ( typeof map === 'string' ) map = JSON.parse(map);
if ( map && map.mappings ) opts.map.prev = map;

if ( params.syntax ) {
opts.syntax = require(params.syntax);
}
if ( params.parser ) {
opts.parser = require(params.parser);
}
if ( params.stringifier ) {
opts.stringifier = require(params.stringifier);
}
if ( params.exec ) {
exec = params.exec;
}
if ( params.syntax ) {
opts.syntax = require(params.syntax);
}
if ( params.parser ) {
opts.parser = require(params.parser);
}
if ( params.stringifier ) {
opts.stringifier = require(params.stringifier);
}
if ( params.exec ) {
exec = params.exec;
}

var loader = this;
var callback = this.async();
if ( params.parser === 'postcss-js' || exec ) {
source = loader.exec(source, loader.resource);
}

if ( params.parser === 'postcss-js' || exec ) {
source = this.exec(source, this.resource);
}
// Allow plugins to add or remove postcss plugins
if ( loader._compilation ) {
plugins = loader._compilation.applyPluginsWaterfall(
'postcss-loader-before-processing',
[].concat(plugins),
params
);
} else {
loader.emitWarning(
'this._compilation is not available thus ' +
'`postcss-loader-before-processing` is not supported'
);
}

// Allow plugins to add or remove postcss plugins
if ( this._compilation ) {
plugins = this._compilation.applyPluginsWaterfall(
'postcss-loader-before-processing',
[].concat(plugins),
params
);
} else {
loader.emitWarning(
'this._compilation is not available thus ' +
'`postcss-loader-before-processing` is not supported'
);
}
postcss(plugins).process(source, opts)
.then(function (result) {
result.warnings().forEach(function (msg) {
loader.emitWarning(msg.toString());
});

postcss(plugins).process(source, opts)
.then(function (result) {
result.warnings().forEach(function (msg) {
loader.emitWarning(msg.toString());
});
callback(null, result.css, result.map ? result.map.toJSON() : null);
return null;
})
.catch(function (error) {
if ( error.name === 'CssSyntaxError' ) {
callback(new PostCSSLoaderError(error));
} else {
callback(error);
}
});
var resultMap = result.map ? result.map.toJSON() : null;
callback(null, result.css, resultMap);
return null;
})
.catch(function (error) {
if ( error.name === 'CssSyntaxError' ) {
callback(new PostCSSLoaderError(error));
} else {
callback(error);
}
});
});
};
20 changes: 20 additions & 0 deletions lib/assign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = Object.assign || function (target) {
'use strict';
// We must check against these specific cases.
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}

var output = Object(target);
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index];
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};
27 changes: 27 additions & 0 deletions lib/configuration/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var parseOptions = require('./parse_options');
var loadConfig = require('postcss-load-config');

function loadConfigurationFromRc(pack, callback) {
if ( pack ) {
callback(new Error('PostCSS plugin pack is supported ' +
'only when config is passed explicitly'));
return;
}

loadConfig()
.then(function (config) {
callback(null, { options: config.options, plugins: config.plugins });
})
.catch(function (err) {
callback(err);
});
}

module.exports = function getConfiguration(options, pack, callback) {
if ( typeof options === 'undefined' ) {
loadConfigurationFromRc(pack, callback);
return;
}

parseOptions(options, pack, callback);
};
41 changes: 41 additions & 0 deletions lib/configuration/parse_options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
function getPluginsFromOptions(options, pack) {
var plugins;

if ( typeof options === 'undefined') {
plugins = [];
}
else if ( Array.isArray(options) ) {
plugins = options;
} else {
plugins = options.plugins || options.defaults;
}

if ( pack ) {
plugins = options[pack];
if ( !plugins ) {
throw new Error('PostCSS plugin pack is not defined in options');
}
}

return plugins;
}

module.exports = function parseOptions(options, pack, callback) {
var exec = options && options.exec;

if ( typeof options === 'function' ) {
options = options.call(this, this);
}

var plugins = getPluginsFromOptions(options, pack);
var opts = {};

if ( typeof options !== 'undefined' ) {
opts.stringifier = options.stringifier;
opts.parser = options.parser;
opts.syntax = options.syntax;
}

callback(null, { options: opts, plugins: plugins, exec: exec });
}

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"repository": "postcss/postcss-loader",
"dependencies": {
"loader-utils": "^0.2.16",
"postcss": "^5.2.0"
"postcss": "^5.2.0",
"postcss-load-config": "^1.0.0-alpha4"
},
"devDependencies": {
"eslint-config-postcss": "2.0.2",
Expand All @@ -21,7 +22,8 @@
"gulp-mocha": "3.0.1",
"fs-extra": "0.30.0",
"chai": "3.5.0",
"gulp": "3.9.1"
"gulp": "3.9.1",
"sugarss": "^0.1.6"
},
"scripts": {
"test": "gulp"
Expand Down
7 changes: 7 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var config = {
plugins: {}
}

config.plugins[require.resolve(__dirname + '/test/support/plugins/blue')] = false;

module.exports = config
14 changes: 0 additions & 14 deletions test/plugins/red.js

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions test/support/cases/sugar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a
color: black
File renamed without changes.
20 changes: 20 additions & 0 deletions test/support/plugins/red.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
var warning = false;

module.exports = function (options) {
var alpha = options.alpha || '1.0';

return {
postcss: function (css, result) {
if (!warning) {
result.warn('Test red warning');
warning = true;
}

css.walkDecls(function (decl) {
if (decl.value === 'blue') {
decl.value = 'rgba(255, 0, 0, ' + alpha + ')';
}
});
}
};
};
12 changes: 12 additions & 0 deletions test/test-custom-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var expect = require('chai').expect;

describe('postcss-loader', function () {

context('when config defines syntax function', function () {
it('processes sugarss', function () {
var css = require('!raw-loader!../!' +
'./support/cases/sugar.css');
expect(css).to.eql('a\n color: rgba(255, 0, 0, 0.1)\n');
});
});
});
Loading