Skip to content

Commit 954c3d1

Browse files
committed
PostCSS update and fix
* Added template file for postcss config which provides infrastructure to add postcss plugins * Fixed and improved attachment of the postcss-loader to th webpack config * Updated README regarding postcss usage
1 parent e094c21 commit 954c3d1

File tree

5 files changed

+77
-72
lines changed

5 files changed

+77
-72
lines changed

README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,23 @@ Stateless functional components where introduced in React v0.14. They have a muc
6767
___Note___: You will still be able to set properties for stateless components!
6868

6969
## Adding PostCSS plugins
70-
If you have enabled [PostCSS](https://github.com/postcss/postcss) at generation time, install your PostCSS plugins via npm and *require* it in **postcss** function in *cfg/base.js*.
70+
If you have enabled [PostCSS](https://github.com/postcss/postcss) at generation time, install your PostCSS plugins via npm and *require* it in the **plugins** array in *postcss.config.js*.
7171

7272
Example for autoprefixer:
7373
```bash
7474
cd my-new-project
7575
npm install autoprefixer
7676
```
77-
Require in *cfg/base.js*
77+
Require in *postcss.config.js*
7878
```JavaScript
7979
...
80-
postcss: function () {
81-
return [
80+
module.exports = () => ({
81+
plugins: [
8282
require('autoprefixer')({
8383
browsers: ['last 2 versions', 'ie >= 8']
8484
})
85-
];
86-
}
85+
]
86+
});
8787
...
8888
```
8989

generators/app/index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,14 @@ class AppGenerator extends Generators.Base {
150150
}
151151
}
152152
});
153+
154+
if(this.postcss) {
155+
this.copy('../../generators/app/templates/postcss.config.js', 'postcss.config.js');
156+
}
153157
}
154158

155159
install() {
156160

157-
// Currently buggy!
158161
if(this.postcss) {
159162
const postcss = require('./postcss');
160163
postcss.write(path.join(this.destinationRoot(), 'conf/webpack/Base.js'));

generators/app/postcss.js

+30-23
Original file line numberDiff line numberDiff line change
@@ -20,44 +20,37 @@ module.exports = {
2020
// of the chain. If we have a preprocessor, we will add
2121
// it before the initial loader
2222
const cssDialects = [
23-
'\\.cssmodule\\.css$',
2423
'^.((?!cssmodule).)*\\.css$'
2524
];
2625

26+
const cssModuleDialects = [
27+
'\\.cssmodule\\.css$'
28+
];
29+
2730
const preprocessorDialects = [
28-
'\\.cssmodule\\.(sass|scss)$',
2931
'^.((?!cssmodule).)*\\.(sass|scss)$',
30-
'\\.cssmodule\\.less$',
3132
'^.((?!cssmodule).)*\\.less$',
32-
'\\.cssmodule\\.styl$',
3333
'^.((?!cssmodule).)*\\.styl$'
3434
];
3535

36-
// Prepare postCSS statement for inclusion
37-
const postcssConfig = 'const postcssQuery = { plugins: [] };';
36+
const preprocessorModuleDialects = [
37+
'\\.cssmodule\\.(sass|scss)$',
38+
'\\.cssmodule\\.less$',
39+
'\\.cssmodule\\.styl$'
40+
];
41+
42+
const postcssConfig = 'const postcssQuery = { query: { importLoaders: 1 } };';
3843
const postcssAst = esprima.parse(postcssConfig);
39-
const postcss = postcssAst.body[0];
44+
const postcss = postcssAst.body[0].declarations[0].init.properties[0];
4045

4146
// The postcss loader item to add
42-
const postcssLoaderObject = 'var postcss = [{ loader: \'postcss-loader\', query: postcssQuery }];';
47+
const postcssLoaderObject = 'var postcss = [{ loader: \'postcss-loader\' }];';
4348
const postcssLoaderAst = esprima.parse(postcssLoaderObject);
4449
const postcssLoader = postcssLoaderAst.body[0].declarations[0].init.elements[0];
4550

46-
4751
// Add postcss to the loaders array
4852
walk.walkAddParent(ast, (node) => {
4953

50-
51-
// Add the postcss key to the global configuration
52-
53-
if(
54-
node.type === 'MethodDefinition' &&
55-
node.key.name === 'defaultSettings'
56-
) {
57-
const returnStatement = node.value.body.body[1];
58-
node.value.body.body = [postcss].concat(node.value.body.body);
59-
}
60-
6154
// Parse all property nodes that use a regex.
6255
// This should only be available under module.(pre)loaders
6356
if(
@@ -67,14 +60,28 @@ module.exports = {
6760
typeof node.value.regex !== 'undefined'
6861
) {
6962

63+
// Enable importLoaders on non cssmodule dialacts
64+
if(
65+
cssDialects.indexOf(node.value.regex.pattern) !== -1 ||
66+
preprocessorDialects.indexOf(node.value.regex.pattern) !== -1
67+
) {
68+
node.parent.properties[1].value.elements[1].properties.push(postcss);
69+
}
70+
7071
// Regular css usage
71-
if(cssDialects.indexOf(node.value.regex.pattern) !== -1) {
72+
if(
73+
cssDialects.indexOf(node.value.regex.pattern) !== -1 ||
74+
cssModuleDialects.indexOf(node.value.regex.pattern) !== -1
75+
) {
7276
const loaderData = node.parent.properties[1];
7377
loaderData.value.elements.push(postcssLoader);
7478
}
7579

76-
77-
if(preprocessorDialects.indexOf(node.value.regex.pattern) !== -1) {
80+
// CSS preprocessors
81+
if(
82+
preprocessorDialects.indexOf(node.value.regex.pattern) !== -1 ||
83+
preprocessorModuleDialects.indexOf(node.value.regex.pattern) !== -1
84+
) {
7885
const loaderData = node.parent.properties[1];
7986
const lastElm = loaderData.value.elements.pop();
8087
loaderData.value.elements.push(postcssLoader);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = () => ({
2+
plugins: []
3+
});

test/generators/app/indexTest.js

+34-42
Original file line numberDiff line numberDiff line change
@@ -225,78 +225,70 @@ describe('react-webpack:app with PostCSS support', () => {
225225
]);
226226
});
227227

228-
it('should insert the postcss loader into the style pipes', () => {
228+
it('should insert the postcss loader into the cssmodule style pipes', () => {
229229

230230
assert.fileContent('conf/webpack/Base.js', `{
231231
loader: 'css-loader',
232232
query: cssModulesQuery
233233
},
234-
{
235-
loader: 'postcss-loader',
236-
query: postcssQuery
237-
}`);
238-
239-
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
240-
{
241-
loader: 'postcss-loader',
242-
query: postcssQuery
243-
}`);
234+
{ loader: 'postcss-loader' }`);
244235

245236
assert.fileContent('conf/webpack/Base.js', `{
246237
loader: 'css-loader',
247238
query: cssModulesQuery
248239
},
249-
{
250-
loader: 'postcss-loader',
251-
query: postcssQuery
252-
},
240+
{ loader: 'postcss-loader' },
253241
{ loader: 'sass-loader' }`);
254242

255-
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
256-
{
257-
loader: 'postcss-loader',
258-
query: postcssQuery
243+
assert.fileContent('conf/webpack/Base.js', `{
244+
loader: 'css-loader',
245+
query: cssModulesQuery
259246
},
260-
{ loader: 'sass-loader' }`);
247+
{ loader: 'postcss-loader' },
248+
{ loader: 'less-loader' }`);
261249

262250
assert.fileContent('conf/webpack/Base.js', `{
263251
loader: 'css-loader',
264252
query: cssModulesQuery
265253
},
266-
{
267-
loader: 'postcss-loader',
268-
query: postcssQuery
269-
},
270-
{ loader: 'less-loader' }`);
254+
{ loader: 'postcss-loader' },
255+
{ loader: 'stylus-loader' }`);
256+
});
271257

272-
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
273-
{
274-
loader: 'postcss-loader',
275-
query: postcssQuery
258+
it('should insert the postcss loader into the NON cssmodule style pipes', () => {
259+
260+
assert.fileContent('conf/webpack/Base.js', `{
261+
loader: 'css-loader',
262+
query: { importLoaders: 1 }
276263
},
277-
{ loader: 'less-loader' }`);
264+
{ loader: 'postcss-loader' }`);
278265

279266
assert.fileContent('conf/webpack/Base.js', `{
280267
loader: 'css-loader',
281-
query: cssModulesQuery
268+
query: { importLoaders: 1 }
282269
},
283-
{
284-
loader: 'postcss-loader',
285-
query: postcssQuery
270+
{ loader: 'postcss-loader' },
271+
{ loader: 'sass-loader' }`);
272+
273+
assert.fileContent('conf/webpack/Base.js', `{
274+
loader: 'css-loader',
275+
query: { importLoaders: 1 }
286276
},
287-
{ loader: 'stylus-loader' }`);
277+
{ loader: 'postcss-loader' },
278+
{ loader: 'less-loader' }`);
288279

289-
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
290-
{
291-
loader: 'postcss-loader',
292-
query: postcssQuery
280+
assert.fileContent('conf/webpack/Base.js', `{
281+
loader: 'css-loader',
282+
query: { importLoaders: 1 }
293283
},
284+
{ loader: 'postcss-loader' },
294285
{ loader: 'stylus-loader' }`);
295286
});
296287

297-
it('should append the postcss function to the base config', () => {
298-
299-
assert.fileContent('conf/webpack/Base.js', `const postcssQuery = { plugins: [] };`);
288+
it('should generate the postCSS config', () => {
289+
assert.file([
290+
'postcss.config.js',
291+
]);
300292
});
301293

302294
it('should generate required source files', () => {

0 commit comments

Comments
 (0)