Skip to content

Commit f230d40

Browse files
bmatcukmichael-ciniawsky
authored andcommitted
feat(src/index): support synchronous config loading (rc.sync)
1 parent 497d4f9 commit f230d40

7 files changed

Lines changed: 242 additions & 56 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ module.exports = (ctx) => ({
322322
}
323323
```
324324

325+
### `Async`
326+
325327
```js
326328
const { readFileSync } = require('fs')
327329

@@ -339,6 +341,21 @@ postcssrc(ctx).then(({ plugins, options }) => {
339341
})
340342
```
341343

344+
### `Sync`
345+
346+
```js
347+
const { readFileSync } = require('fs')
348+
349+
const postcss = require('postcss')
350+
const postcssrc = require('postcss-load-config')
351+
352+
const css = readFileSync('index.sss', 'utf8')
353+
354+
const ctx = { parser: true, map: 'inline' }
355+
356+
const { plugins, options } = postcssrc.sync(ctx)
357+
```
358+
342359
<div align="center">
343360
<img width="80" height="80" halign="10" src="https://worldvectorlogo.com/logos/gulp.svg">
344361
</div>

src/index.js

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,42 @@ const loadOptions = require('./options.js')
88
const loadPlugins = require('./plugins.js')
99

1010
/**
11-
* Load Config
11+
* Process the result from cosmiconfig
1212
*
13-
* @method rc
13+
* @param {Object} ctx Config Context
14+
* @param {Object} result Cosmiconfig result
15+
*
16+
* @return {Object} PostCSS Config
17+
*/
18+
const processResult = (ctx, result) => {
19+
let file = result.filepath || ''
20+
let config = result.config || {}
21+
22+
if (typeof config === 'function') {
23+
config = config(ctx)
24+
} else {
25+
config = Object.assign({}, config, ctx)
26+
}
27+
28+
if (!config.plugins) {
29+
config.plugins = []
30+
}
31+
32+
return {
33+
plugins: loadPlugins(config, file),
34+
options: loadOptions(config, file),
35+
file: file
36+
}
37+
}
38+
39+
/**
40+
* Builds the Config Context
1441
*
1542
* @param {Object} ctx Config Context
16-
* @param {String} path Config Path
17-
* @param {Object} options Config Options
1843
*
19-
* @return {Promise} config PostCSS Config
44+
* @return {Object} Config Context
2045
*/
21-
const rc = (ctx, path, options) => {
46+
const createContext = (ctx) => {
2247
/**
2348
* @type {Object}
2449
*
@@ -29,24 +54,35 @@ const rc = (ctx, path, options) => {
2954
cwd: process.cwd(),
3055
env: process.env.NODE_ENV
3156
}, ctx)
57+
58+
if (!ctx.env) {
59+
process.env.NODE_ENV = 'development'
60+
}
61+
62+
return ctx
63+
}
64+
65+
/**
66+
* Load Config
67+
*
68+
* @method rc
69+
*
70+
* @param {Object} ctx Config Context
71+
* @param {String} path Config Path
72+
* @param {Object} options Config Options
73+
*
74+
* @return {Promise} config PostCSS Config
75+
*/
76+
const rc = (ctx, path, options) => {
3277
/**
33-
* @type {String} `process.cwd()`
34-
*
78+
* @type {Object} The full Config Context
3579
*/
36-
path = path ? resolve(path) : process.cwd()
80+
ctx = createContext(ctx)
3781

3882
/**
39-
* @type {Object}
40-
*
41-
* @prop {Boolean} rcExtensions=true
83+
* @type {String} `process.cwd()`
4284
*/
43-
options = Object.assign({
44-
rcExtensions: true
45-
}, options)
46-
47-
if (!ctx.env) {
48-
process.env.NODE_ENV = 'development'
49-
}
85+
path = path ? resolve(path) : process.cwd()
5086

5187
return config('postcss', options)
5288
.search(path)
@@ -55,25 +91,28 @@ const rc = (ctx, path, options) => {
5591
throw new Error(`No PostCSS Config found in: ${path}`)
5692
}
5793

58-
let file = result.filepath || ''
59-
let config = result.config || {}
94+
return processResult(ctx, result)
95+
})
96+
}
6097

61-
if (typeof config === 'function') {
62-
config = config(ctx)
63-
} else {
64-
config = Object.assign({}, config, ctx)
65-
}
98+
rc.sync = (ctx, path, options) => {
99+
/**
100+
* @type {Object} The full Config Context
101+
*/
102+
ctx = createContext(ctx)
66103

67-
if (!config.plugins) {
68-
config.plugins = []
69-
}
104+
/**
105+
* @type {String} `process.cwd()`
106+
*/
107+
path = path ? resolve(path) : process.cwd()
70108

71-
return {
72-
plugins: loadPlugins(config, file),
73-
options: loadOptions(config, file),
74-
file: file
75-
}
76-
})
109+
const result = config('postcss', options).searchSync(path)
110+
111+
if (!result) {
112+
throw new Error(`No PostCSS Config found in: ${path}`)
113+
}
114+
115+
return processResult(ctx, result)
77116
}
78117

79118
/**

src/plugins.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,18 @@ const req = require('import-cwd')
1414
* @return {Function} PostCSS Plugin
1515
*/
1616
const load = (plugin, options, file) => {
17-
if (
18-
options === null ||
19-
options === undefined ||
20-
Object.keys(options).length === 0
21-
) {
22-
try {
17+
try {
18+
if (
19+
options === null ||
20+
options === undefined ||
21+
Object.keys(options).length === 0
22+
) {
2323
return req(plugin)
24-
} catch (err) {
25-
throw new Error(`Loading PostCSS Plugin failed: ${err.message}\n\n(@${file})`)
26-
}
27-
} else {
28-
try {
24+
} else {
2925
return req(plugin)(options)
30-
} catch (err) {
31-
throw new Error(`Loading PostCSS Plugin failed: ${err.message}\n\n(@${file})`)
3226
}
27+
} catch (err) {
28+
throw new Error(`Loading PostCSS Plugin failed: ${err.message}\n\n(@${file})`)
3329
}
3430
}
3531

test/Errors.test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ test('Loading Config - {Error}', () => {
1010
})
1111
})
1212

13+
test('Loading Config - Sync - {Error}', () => {
14+
try {
15+
postcssrc.sync({}, 'test/err')
16+
} catch (err) {
17+
expect(err.message).toMatch(
18+
/^No PostCSS Config found in: (.*)$/
19+
)
20+
}
21+
})
22+
1323
describe('Loading Plugins - {Error}', () => {
1424
test('Plugin - {Type} - Invalid', () => {
1525
return postcssrc({}, 'test/err/plugins').catch((err) => {
@@ -52,6 +62,58 @@ describe('Loading Plugins - {Error}', () => {
5262
})
5363
})
5464

65+
describe('Loading Plugins - Sync - {Error}', () => {
66+
test('Plugin - {Type} - Invalid', () => {
67+
try {
68+
postcssrc.sync({}, 'test/err/plugins')
69+
} catch (err) {
70+
expect(err.message).toMatch(
71+
/^Invalid PostCSS Plugin found at: (.*)\n\n\(@.*\)$/
72+
)
73+
}
74+
})
75+
76+
test('Plugin - {Object}', () => {
77+
try {
78+
postcssrc.sync({}, 'test/err/plugins/object')
79+
} catch (err) {
80+
expect(err.message).toMatch(
81+
/^Loading PostCSS Plugin failed: (.*)\n\n\(@.*\)$/
82+
)
83+
}
84+
})
85+
86+
test('Plugin - {Object} - Options', () => {
87+
try {
88+
postcssrc.sync({}, 'test/err/plugins/object/options')
89+
} catch (err) {
90+
expect(err.message).toMatch(
91+
/^Loading PostCSS Plugin failed: (.*)\n\n\(@.*\)$/
92+
)
93+
}
94+
})
95+
96+
test('Plugin - {Array}', () => {
97+
try {
98+
postcssrc.sync({}, 'test/err/plugins/array')
99+
} catch (err) {
100+
expect(err.message).toMatch(
101+
/^Cannot find (.*)$/
102+
)
103+
}
104+
})
105+
106+
test('Plugin - {Array} - Options', () => {
107+
try {
108+
postcssrc.sync({}, 'test/err/plugins/array/options')
109+
} catch (err) {
110+
expect(err.message).toMatch(
111+
/^Cannot find (.*)$/
112+
)
113+
}
114+
})
115+
})
116+
55117
describe('Loading Options - {Error}', () => {
56118
test('Parser - {String}', () => {
57119
return postcssrc({}, 'test/err/options/parser').catch((err) => {
@@ -77,3 +139,35 @@ describe('Loading Options - {Error}', () => {
77139
})
78140
})
79141
})
142+
143+
describe('Loading Options - Sync - {Error}', () => {
144+
test('Parser - {String}', () => {
145+
try {
146+
postcssrc.sync({}, 'test/err/options/parser')
147+
} catch (err) {
148+
expect(err.message).toMatch(
149+
/^Loading PostCSS Parser failed: (.*)\n\n\(@.*\)$/
150+
)
151+
}
152+
})
153+
154+
test('Syntax - {String}', () => {
155+
try {
156+
postcssrc.sync({}, 'test/err/options/syntax')
157+
} catch (err) {
158+
expect(err.message).toMatch(
159+
/^Loading PostCSS Syntax failed: (.*)\n\n\(@.*\)$/
160+
)
161+
}
162+
})
163+
164+
test('Stringifier - {String}', () => {
165+
try {
166+
postcssrc.sync({}, 'test/err/options/stringifier')
167+
} catch (err) {
168+
expect(err.message).toMatch(
169+
/^Loading PostCSS Stringifier failed: (.*)\n\n\(@.*\)$/
170+
)
171+
}
172+
})
173+
})

test/js.test.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ const postcssrc = require('../src/index.js')
77

88
const { fixture, expected } = require('./utils.js')
99

10-
test('postcss.config.js - {Object} - Load Config', () => {
10+
describe('postcss.config.js - {Object} - Load Config', () => {
1111
const ctx = {
1212
parser: true,
1313
syntax: true
1414
}
1515

16-
return postcssrc(ctx, 'test/js/object').then((config) => {
16+
const expected = (config) => {
1717
expect(config.options.parser).toEqual(require('sugarss'))
1818
expect(config.options.syntax).toEqual(require('sugarss'))
1919
expect(config.options.map).toEqual(false)
@@ -26,6 +26,16 @@ test('postcss.config.js - {Object} - Load Config', () => {
2626

2727
expect(config.file)
2828
.toEqual(path.resolve('test/js/object', 'postcss.config.js'))
29+
}
30+
31+
test('Async', () => {
32+
return postcssrc(ctx, 'test/js/object').then(expected)
33+
})
34+
35+
test('Sync', () => {
36+
const config = postcssrc.sync(ctx, 'test/js/object')
37+
38+
expected(config)
2939
})
3040
})
3141

@@ -60,13 +70,13 @@ test('postcss.config.js - {Object} - Process SSS', () => {
6070
})
6171
})
6272

63-
test('postcss.config.js - {Array} - Load Config', () => {
73+
describe('postcss.config.js - {Array} - Load Config', () => {
6474
const ctx = {
6575
parser: true,
6676
syntax: true
6777
}
6878

69-
return postcssrc(ctx, 'test/js/array').then((config) => {
79+
const expected = (config) => {
7080
expect(config.options.parser).toEqual(require('sugarss'))
7181
expect(config.options.syntax).toEqual(require('sugarss'))
7282
expect(config.options.map).toEqual(false)
@@ -79,6 +89,16 @@ test('postcss.config.js - {Array} - Load Config', () => {
7989

8090
expect(config.file)
8191
.toEqual(path.resolve('test/js/array', 'postcss.config.js'))
92+
}
93+
94+
test('Async', () => {
95+
return postcssrc(ctx, 'test/js/array').then(expected)
96+
})
97+
98+
test('Sync', () => {
99+
const config = postcssrc.sync(ctx, 'test/js/array')
100+
101+
expected(config)
82102
})
83103
})
84104

0 commit comments

Comments
 (0)