generators/app/postcss.js
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');
  }
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');
  }
Add postcss support to the given webpack base configuration object
@param {String} path The config file name