Updated functionality related to PostCSS - #307

- bumped postcss and postcss-loader versions
- removed deprecated custom logic related to setting up PostCSS
- updated tests

As communicated in #307 and on the related PR from @stylesuxx on the
template repo we can use PostCSS` more recent config file feature
instead of modifying our config.

If users prompt the PostCSS question with yes, deps for postcss and
postcss-loader are added to their package.json.

The updated tests check that
- postcss and postcss-loader deps are added on PostCSS yes
- postcss and postcss-loader deps are not added on PostCSS no
- postcss.config.js is copied to the project root
This commit is contained in:
sthzg 2016-12-17 00:13:38 +01:00
parent 9c68254178
commit cece8d0401
4 changed files with 36 additions and 150 deletions

View File

@ -154,12 +154,6 @@ class AppGenerator extends Generators.Base {
install() {
// Currently buggy!
if(this.postcss) {
const postcss = require('./postcss');
postcss.write(path.join(this.destinationRoot(), 'conf/webpack/Base.js'));
}
if(!this.options['skip-install']) {
this.installDependencies({ bower: false });
}

View File

@ -1,99 +0,0 @@
'use strict';
const fs = require('fs');
const esprima = require('esprima');
const walk = require('esprima-walk');
const escodegen = require('escodegen');
module.exports = {
/**
* Add postcss support to the given webpack base configuration object
* @param {String} path The config file name
*/
write: function(path) {
const data = fs.readFileSync(path, 'utf8');
const ast = esprima.parse(data);
// List of css dialects we want to add postCSS for
// On regular css, we can add the loader to the end
// of the chain. If we have a preprocessor, we will add
// it before the initial loader
const cssDialects = [
'\\.cssmodule\\.css$',
'^.((?!cssmodule).)*\\.css$'
];
const preprocessorDialects = [
'\\.cssmodule\\.(sass|scss)$',
'^.((?!cssmodule).)*\\.(sass|scss)$',
'\\.cssmodule\\.less$',
'^.((?!cssmodule).)*\\.less$',
'\\.cssmodule\\.styl$',
'^.((?!cssmodule).)*\\.styl$'
];
// Prepare postCSS statement for inclusion
const postcssFunction = 'var postcss = { postcss: function() { return []; } }';
const postcssAst = esprima.parse(postcssFunction);
const postcss = postcssAst.body[0].declarations[0].init.properties[0];
// The postcss loader item to add
const postcssLoaderObject = 'var postcss = [{ loader: \'postcss-loader\'}]';
const postcssLoaderAst = esprima.parse(postcssLoaderObject);
const postcssLoader = postcssLoaderAst.body[0].declarations[0].init.elements[0];
// Add postcss to the loaders array
walk.walkAddParent(ast, (node) => {
// Add the postcss key to the global configuration
if(
node.type === 'MethodDefinition' &&
node.key.name === 'defaultSettings'
) {
const returnStatement = node.value.body.body[1];
returnStatement.argument.properties.push(postcss);
}
// Parse all property nodes that use a regex.
// This should only be available under module.(pre)loaders
if(
node.type === 'Property' &&
node.key.type === 'Identifier' &&
node.key.name === 'test' &&
typeof node.value.regex !== 'undefined'
) {
// Regular css usage
if(cssDialects.indexOf(node.value.regex.pattern) !== -1) {
const loaderData = node.parent.properties[1];
loaderData.value.elements.push(postcssLoader);
}
if(preprocessorDialects.indexOf(node.value.regex.pattern) !== -1) {
const loaderData = node.parent.properties[1];
const lastElm = loaderData.value.elements.pop();
loaderData.value.elements.push(postcssLoader);
loaderData.value.elements.push(lastElm);
}
}
});
// Prepare the final code and write it back
const finalCode = escodegen.generate(ast, {
format: {
indent: {
adjustMultilineComment: true,
style: ' '
}
},
comment: true
});
fs.writeFileSync(path, finalCode, 'utf8');
}
}

View File

@ -163,6 +163,27 @@ describe('react-webpack:app without cssmodules support', () => {
});
});
describe('react-webpack:app without PostCSS support', () => {
let prompts = {};
for(let p of defaultPrompts) {
prompts[p.name] = p.default;
}
prompts.postcss = false;
before(() => {
return beforeLoad(prompts);
});
describe('#createFiles', () => {
it('should not add postcss and postcss-loader deps', () => {
assert.noFileContent('package.json', 'postcss');
assert.noFileContent('package.json', 'postcss-loader');
});
});
});
describe('react-webpack:app with PostCSS support', () => {
let prompts = {};
@ -203,7 +224,14 @@ describe('react-webpack:app with PostCSS support', () => {
'.editorconfig',
'.eslintrc',
'.gitignore',
'.yo-rc.json'
'.yo-rc.json',
]);
});
it('should generate postcss.config.js', () => {
assert.file([
'postcss.config.js'
]);
});
@ -225,48 +253,6 @@ describe('react-webpack:app with PostCSS support', () => {
]);
});
it('should insert the postcss loader into the style pipes', () => {
assert.fileContent('conf/webpack/Base.js', `{
loader: 'css-loader',
query: cssModulesQuery
},
{ loader: 'postcss-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
{ loader: 'postcss-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{
loader: 'css-loader',
query: cssModulesQuery
},
{ loader: 'postcss-loader' },
{ loader: 'sass-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'sass-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{
loader: 'css-loader',
query: cssModulesQuery
},
{ loader: 'postcss-loader' },
{ loader: 'less-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'less-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{
loader: 'css-loader',
query: cssModulesQuery
},
{ loader: 'postcss-loader' },
{ loader: 'stylus-loader' }`);
assert.fileContent('conf/webpack/Base.js', `{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'stylus-loader' }`);
});
it('should append the postcss function to the base config', () => {
assert.fileContent('conf/webpack/Base.js', 'postcss: function () {');
});
it('should generate required source files', () => {
assert.file([
@ -282,6 +268,11 @@ describe('react-webpack:app with PostCSS support', () => {
]);
});
it('should add postcss and postcss-loader deps', () => {
assert.fileContent('package.json', 'postcss');
assert.fileContent('package.json', 'postcss-loader');
});
it('should generate test configuration and basic tests', () => {
assert.file([

View File

@ -45,8 +45,8 @@
"name": "postcss",
"value": "postcss",
"packages": [
{ "name": "postcss", "version": "^5.0.21" },
{ "name": "postcss-loader", "version": "^0.9.1" }
{ "name": "postcss", "version": "^5.2.6" },
{ "name": "postcss-loader", "version": "^1.2.1" }
]
}
]