Skip to content

Commit e0714ec

Browse files
author
Andrey Kuzmin
committed
Load options and plugins from postcss-load-config
1 parent c13b5a1 commit e0714ec

File tree

3 files changed

+148
-36
lines changed

3 files changed

+148
-36
lines changed

index.js

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@ var postcss = require('postcss')
33
var applySourceMap = require('vinyl-sourcemaps-apply')
44
var gutil = require('gulp-util')
55
var path = require('path')
6+
var postcssLoadConfig = require('postcss-load-config')
67

78

8-
module.exports = function (processors, options) {
9-
10-
if (!Array.isArray(processors)) {
11-
throw new gutil.PluginError('gulp-postcss', 'Please provide array of postcss processors!')
12-
}
9+
module.exports = withConfigLoader(function (loadConfig) {
1310

1411
var stream = new Stream.Transform({ objectMode: true })
1512

@@ -23,29 +20,40 @@ module.exports = function (processors, options) {
2320
return handleError('Streams are not supported!')
2421
}
2522

26-
// Source map is disabled by default
27-
var opts = { map: false }
28-
var attr
29-
30-
// Extend default options
31-
if (options) {
32-
for (attr in options) {
33-
if (options.hasOwnProperty(attr)) {
34-
opts[attr] = options[attr]
35-
}
36-
}
37-
}
38-
39-
opts.from = file.path
40-
opts.to = opts.to || file.path
23+
// Protect `from` and `map` if using gulp-sourcemap
24+
var isProtected = file.sourceMap
25+
? { from: true, map: true }
26+
: {}
4127

42-
// Generate separate source map for gulp-sourcemap
43-
if (file.sourceMap) {
44-
opts.map = { annotation: false }
28+
var options = {
29+
from: file.path
30+
, to: file.path
31+
// Generate a separate source map for gulp-sourcemap
32+
, map: file.sourceMap ? { annotation: false } : false
4533
}
4634

47-
postcss(processors)
48-
.process(file.contents, opts)
35+
loadConfig({
36+
from: options.from
37+
, to: options.to
38+
, map: options.map
39+
})
40+
.then(function (config) {
41+
var configOpts = config.options || {}
42+
// Extend the default options if not protected
43+
for (var opt in configOpts) {
44+
if (configOpts.hasOwnProperty(opt) && !isProtected[opt]) {
45+
options[opt] = configOpts[opt]
46+
} else {
47+
gutil.log(
48+
'gulp-postcss:',
49+
file.relative + '\nCannot override ' + opt +
50+
' option, because it is required by gulp-sourcemap'
51+
)
52+
}
53+
}
54+
return postcss(config.plugins || [])
55+
.process(file.contents, options)
56+
})
4957
.then(handleResult, handleError)
5058

5159
function handleResult (result) {
@@ -89,4 +97,25 @@ module.exports = function (processors, options) {
8997
}
9098

9199
return stream
100+
})
101+
102+
103+
function withConfigLoader(cb) {
104+
return function (plugins, options) {
105+
if (typeof plugins === 'undefined') {
106+
return cb(postcssLoadConfig)
107+
} else if (Array.isArray(plugins)) {
108+
return cb(function () {
109+
return Promise.resolve({
110+
plugins: plugins
111+
, options: options
112+
})
113+
})
114+
} else {
115+
throw new gutil.PluginError(
116+
'gulp-postcss',
117+
'Please provide array of postcss processors!'
118+
)
119+
}
120+
}
92121
}

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323
},
2424
"homepage": "https://github.com/postcss/gulp-postcss",
2525
"dependencies": {
26-
"gulp-util": "^3.0.7",
27-
"postcss": "^5.2.0",
28-
"vinyl-sourcemaps-apply": "^0.2.0"
26+
"gulp-util": "^3.0.8",
27+
"postcss": "^5.2.10",
28+
"postcss-load-config": "^1.1.0",
29+
"vinyl-sourcemaps-apply": "^0.2.1"
2930
},
3031
"devDependencies": {
31-
"es6-promise": "^3.0.2",
32-
"gulp-sourcemaps": "^1.5.1",
33-
"mocha": "^2.2.5",
32+
"es6-promise": "^3.3.1",
33+
"gulp-sourcemaps": "^1.11.0",
34+
"mocha": "^3.2.0",
3435
"proxyquire": "^1.7.4",
3536
"sinon": "^1.17.3"
3637
}

test.js

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,9 @@ it('should respond with error on stream files', function (cb) {
9393
})
9494

9595

96-
it('should throw error if processors are not provided', function (cb) {
97-
assert.throws( function () { postcss() }, gutil.PluginError )
96+
it('should throw error if plugins are not array', function () {
9897
assert.throws( function () { postcss('') }, gutil.PluginError )
9998
assert.throws( function () { postcss({}) }, gutil.PluginError )
100-
cb()
10199
})
102100

103101

@@ -171,13 +169,22 @@ describe('PostCSS Guidelines', function () {
171169
use: function () {}
172170
, process: function () {}
173171
}
172+
var postcssLoadConfigStub
174173
var postcss = proxyquire('./index', {
175-
postcss: function () {
174+
postcss: function (plugins) {
175+
postcssStub.use(plugins)
176176
return postcssStub
177177
}
178+
, 'postcss-load-config': function (args) {
179+
return postcssLoadConfigStub(args)
180+
}
181+
, 'vinyl-sourcemaps-apply': function () {
182+
return {}
183+
}
178184
})
179185

180186
beforeEach(function () {
187+
postcssLoadConfigStub = sandbox.stub()
181188
sandbox.stub(postcssStub, 'use')
182189
sandbox.stub(postcssStub, 'process')
183190
})
@@ -186,7 +193,6 @@ describe('PostCSS Guidelines', function () {
186193
sandbox.restore()
187194
})
188195

189-
190196
it('should set `from` and `to` processing options to `file.path`', function (cb) {
191197

192198
var stream = postcss([ doubler ])
@@ -236,6 +242,82 @@ describe('PostCSS Guidelines', function () {
236242

237243
})
238244

245+
it('should take plugins and options from postcss-load-config', function (cb) {
246+
247+
var cssPath = __dirname + '/fixture.css'
248+
var stream = postcss()
249+
var plugins = [ doubler ]
250+
251+
postcssLoadConfigStub.returns(Promise.resolve({
252+
plugins: plugins
253+
, options: { to: 'overriden' }
254+
}))
255+
256+
postcssStub.process.returns(Promise.resolve({
257+
css: ''
258+
, warnings: function () {
259+
return []
260+
}
261+
}))
262+
263+
stream.on('data', function () {
264+
assert.deepEqual(postcssLoadConfigStub.getCall(0).args[0], {
265+
from: cssPath
266+
, to: cssPath
267+
, map: false
268+
})
269+
assert.equal(postcssStub.use.getCall(0).args[0], plugins)
270+
assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
271+
cb()
272+
})
273+
274+
stream.write(new gutil.File({
275+
contents: new Buffer('a {}')
276+
, path: cssPath
277+
}))
278+
279+
stream.end()
280+
281+
})
282+
283+
it('should not override `from` and `map` if using source maps', function (cb) {
284+
var stream = postcss([ doubler ], { from: 'overriden', map: 'overriden' })
285+
var cssPath = __dirname + '/fixture.css'
286+
postcssStub.process.returns(Promise.resolve({
287+
css: ''
288+
, warnings: function () {
289+
return []
290+
}
291+
, map: {
292+
toJSON: function () {
293+
return {
294+
sources: [],
295+
file: ''
296+
}
297+
}
298+
}
299+
}))
300+
301+
sandbox.stub(gutil, 'log')
302+
303+
stream.on('data', function () {
304+
assert.deepEqual(postcssStub.process.getCall(0).args[1].from, cssPath)
305+
assert.deepEqual(postcssStub.process.getCall(0).args[1].map, { annotation: false })
306+
var firstMessage = gutil.log.getCall(0).args[1]
307+
var secondMessage = gutil.log.getCall(1).args[1]
308+
assert(firstMessage, '/fixture.css\nCannot override from option, because it is required by gulp-sourcemap')
309+
assert(secondMessage, '/fixture.css\nCannot override map option, because it is required by gulp-sourcemap')
310+
cb()
311+
})
312+
313+
var file = new gutil.File({
314+
contents: new Buffer('a {}')
315+
, path: cssPath
316+
})
317+
file.sourceMap = {}
318+
stream.end(file)
319+
})
320+
239321
it('should not output js stack trace for `CssSyntaxError`', function (cb) {
240322

241323
var stream = postcss([ doubler ])

0 commit comments

Comments
 (0)