Skip to content

Commit 2ee6a31

Browse files
author
Andrey Kuzmin
committed
Per file config, context for postcss-config-loader
1 parent 9c19592 commit 2ee6a31

File tree

3 files changed

+118
-36
lines changed

3 files changed

+118
-36
lines changed

README.md

+63-4
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ gulp.task('css', function () {
4949

5050
The second optional argument to gulp-postcss is passed to PostCSS.
5151

52-
This, for instance, may be used to enable custom syntax:
52+
This, for instance, may be used to enable custom parser:
5353

5454
```js
5555
var gulp = require('gulp');
5656
var postcss = require('gulp-postcss');
5757
var nested = require('postcss-nested');
58-
var scss = require('postcss-scss');
58+
var sugarss = require('sugarss');
5959

6060
gulp.task('default', function () {
6161
var plugins = [nested];
62-
return gulp.src('in.css')
63-
.pipe(postcss(plugins, {syntax: scss}))
62+
return gulp.src('in.sss')
63+
.pipe(postcss(plugins, { parser: sugarss }))
6464
.pipe(gulp.dest('out'));
6565
});
6666
```
@@ -105,6 +105,65 @@ return gulp.src('./src/*.css')
105105
.pipe(gulp.dest('./dest'));
106106
```
107107

108+
## Advanced usage
109+
110+
If you want to configure per file basis, you can pass a callback that
111+
receives [vinyl file object](https://github.com/gulpjs/vinyl) and returns
112+
`{ plugins: plugins, options: options }`. For example, when you need to
113+
parse different extensions differntly:
114+
115+
```js
116+
var gulp = require('gulp');
117+
var postcss = require('gulp-postcss');
118+
119+
gulp.task('css', function () {
120+
function callback(file) {
121+
return {
122+
plugins: [
123+
require('postcss-import')({ root: file.dirname }),
124+
require('postcss-modules')
125+
],
126+
options: {
127+
parser: file.extname === '.sss' ? require('sugarss') : false
128+
}
129+
}
130+
}
131+
return gulp.src('./src/*.css')
132+
.pipe(postcss(callback))
133+
.pipe(gulp.dest('./dest'));
134+
});
135+
```
136+
137+
The same result may be achieved with
138+
[`postcss-load-config`](https://www.npmjs.com/package/postcss-load-config),
139+
because it receives `ctx` with the context options and the vinyl file.
140+
141+
```js
142+
var gulp = require('gulp');
143+
var postcss = require('gulp-postcss');
144+
145+
gulp.task('css', function () {
146+
var contextOptions = { modules: true };
147+
return gulp.src('./src/*.css')
148+
.pipe(postcss(contextOptions))
149+
.pipe(gulp.dest('./dest'));
150+
});
151+
```
152+
153+
```js
154+
module.exports = function (ctx) {
155+
var file = ctx.file;
156+
var options = ctx.options;
157+
return {
158+
parser: file.extname === '.sss' ? : 'sugarss' : false,
159+
plugins: {
160+
'postcss-import': { root: file.dirname }
161+
'postcss-modules': options.modules ? {} : false
162+
}
163+
}
164+
})
165+
```
166+
108167
## Changelog
109168

110169
* 6.2.0

index.js

+13-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ 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')
76

87

98
module.exports = withConfigLoader(function (loadConfig) {
@@ -32,11 +31,7 @@ module.exports = withConfigLoader(function (loadConfig) {
3231
, map: file.sourceMap ? { annotation: false } : false
3332
}
3433

35-
loadConfig({
36-
from: options.from
37-
, to: options.to
38-
, map: options.map
39-
})
34+
loadConfig(file)
4035
.then(function (config) {
4136
var configOpts = config.options || {}
4237
// Extend the default options if not protected
@@ -102,20 +97,25 @@ module.exports = withConfigLoader(function (loadConfig) {
10297

10398
function withConfigLoader(cb) {
10499
return function (plugins, options) {
105-
if (typeof plugins === 'undefined') {
106-
return cb(postcssLoadConfig)
107-
} else if (Array.isArray(plugins)) {
100+
if (Array.isArray(plugins)) {
108101
return cb(function () {
109102
return Promise.resolve({
110103
plugins: plugins
111104
, options: options
112105
})
113106
})
107+
} else if (typeof plugins === 'function') {
108+
return cb(function (file) {
109+
return Promise.resolve(plugins(file))
110+
})
114111
} else {
115-
throw new gutil.PluginError(
116-
'gulp-postcss',
117-
'Please provide array of postcss processors!'
118-
)
112+
var postcssLoadConfig = require('postcss-load-config')
113+
return cb(function(file) {
114+
return postcssLoadConfig({
115+
file: file
116+
, options: plugins
117+
})
118+
})
119119
}
120120
}
121121
}

test.js

+42-19
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ it('should respond with error on stream files', function (cb) {
9292

9393
})
9494

95-
96-
it('should throw error if plugins are not array', function () {
97-
assert.throws( function () { postcss('') }, gutil.PluginError )
98-
assert.throws( function () { postcss({}) }, gutil.PluginError )
99-
})
100-
101-
10295
it('should generate source maps', function (cb) {
10396

10497
var init = sourceMaps.init()
@@ -175,8 +168,8 @@ describe('PostCSS Guidelines', function () {
175168
postcssStub.use(plugins)
176169
return postcssStub
177170
}
178-
, 'postcss-load-config': function (args) {
179-
return postcssLoadConfigStub(args)
171+
, 'postcss-load-config': function (ctx) {
172+
return postcssLoadConfigStub(ctx)
180173
}
181174
, 'vinyl-sourcemaps-apply': function () {
182175
return {}
@@ -242,10 +235,46 @@ describe('PostCSS Guidelines', function () {
242235

243236
})
244237

238+
it('should take plugins and options from callback', function (cb) {
239+
240+
var cssPath = __dirname + '/fixture.css'
241+
var file = new gutil.File({
242+
contents: new Buffer('a {}')
243+
, path: cssPath
244+
})
245+
var plugins = [ doubler ]
246+
var callback = sandbox.stub().returns({
247+
plugins: plugins
248+
, options: { to: 'overriden' }
249+
})
250+
var stream = postcss(callback)
251+
252+
postcssStub.process.returns(Promise.resolve({
253+
css: ''
254+
, warnings: function () {
255+
return []
256+
}
257+
}))
258+
259+
stream.on('data', function () {
260+
assert.equal(callback.getCall(0).args[0], file)
261+
assert.equal(postcssStub.use.getCall(0).args[0], plugins)
262+
assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
263+
cb()
264+
})
265+
266+
stream.end(file)
267+
268+
})
269+
245270
it('should take plugins and options from postcss-load-config', function (cb) {
246271

247272
var cssPath = __dirname + '/fixture.css'
248-
var stream = postcss()
273+
var file = new gutil.File({
274+
contents: new Buffer('a {}')
275+
, path: cssPath
276+
})
277+
var stream = postcss({ to: 'initial' })
249278
var plugins = [ doubler ]
250279

251280
postcssLoadConfigStub.returns(Promise.resolve({
@@ -262,21 +291,15 @@ describe('PostCSS Guidelines', function () {
262291

263292
stream.on('data', function () {
264293
assert.deepEqual(postcssLoadConfigStub.getCall(0).args[0], {
265-
from: cssPath
266-
, to: cssPath
267-
, map: false
294+
file: file
295+
, options: { to: 'initial' }
268296
})
269297
assert.equal(postcssStub.use.getCall(0).args[0], plugins)
270298
assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
271299
cb()
272300
})
273301

274-
stream.write(new gutil.File({
275-
contents: new Buffer('a {}')
276-
, path: cssPath
277-
}))
278-
279-
stream.end()
302+
stream.end(file)
280303

281304
})
282305

0 commit comments

Comments
 (0)