76 lines
2.0 KiB
JavaScript

'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
const cssDialects = [
'/\\.css$/',
'/\\.sass$/',
'/\\.scss$/',
'/\\.less$/',
'/\\.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];
// 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[0];
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'
) {
// Make sure we only parse style based items!
if(cssDialects.indexOf(node.value.raw) !== -1) {
const loaderData = node.parent.properties[1];
loaderData.value.elements[1].value += '!postcss';
}
}
});
// 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');
}
}