Roots Discourse

Generating AMP Compliant Stylesheets Using Webpack: Postcss and Postcss plugins

Hi!

I’m trying to add the postcss-no-important plugin to remove !important declarations within a compiled stylesheet (working on an AMP version of a site).

I added the plugin as a devdependency using yarn add. Then configured my postcss.config.js file:

  /* eslint-disable */

  const cssnanoConfig = {
     preset: ['default', { discardComments: { removeAll: true } }]
  };

  module.exports = ({ file, options }) => {
    return {
       parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
       plugins: {
         postcss-no-important: true,
         autoprefixer: true,
         cssnano: options.enabled.optimize ? cssnanoConfig : false,
      },
   };
 };

However, when I run yarn run build I keep getting the following error:

Syntax Error: /resources/assets/build/postcss.config.js:11 postcss-no-important: true,
^

SyntaxError: Unexpected token -

And can’t figure out why it’s giving me the error on build?

Any insights would be appreciated! Thank you.

It’s giving you the error because you can’t have - in a key in JavaScript:

plugins: {
         postcss-no-important: true, // you've got two dashes in this key

If you want to do this, you need to quote the key (so it’s treated as a string):

plugins: {
         'postcss-no-important': true, // should work
1 Like

Thank you @alwaysblank that worked! Instead of using the postcss-no-important plugin, I used the postcss-amp plugin instead which adds a few more filters for non-AMP compliant CSS properties.

Right now I’m using a separate postcss.config.js file in resources/assets/build/amp/postcss.config.js.

 /* eslint-disable */
 const cssnanoConfig = {
   preset: ['default', { discardComments: { removeAll: true } }]
};

module.exports = ({ file, options }) => {
  return {
     parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
     plugins: {
       autoprefixer: true,
       cssnano: options.enabled.optimize ? cssnanoConfig : false,
       'postcss-amp': true,
    },
  };
};

I added my AMP stylesheet path in the config.js config.path:

 const config = merge({
   open: true,
   copy: 'images/**/*',
   proxyUrl: 'http://localhost:3000',
   cacheBusting: '[name]_[hash]',
   paths: {
     root: rootPath,
     assets: path.join(rootPath, 'resources/assets'),
     dist: path.join(rootPath, 'dist'),
     amp: path.join(rootPath, 'resources/assets/styles/amp.scss'),
   },
   enabled: {
     sourceMaps: !isProduction,
     optimize: isProduction,
     cacheBusting: isProduction,
     watcher: !!argv.watch,
  },
  watch: [],
 }, userConfig);

In my webpack config I have the following objects in my module rules:

 {
    test: /\.scss$/,
    include: config.paths.assets,
    exclude: config.paths.amp,
    use: ExtractTextPlugin.extract({
      fallback: 'style',
      use: [
        { loader: 'cache' },
        { loader: 'css', options: { sourceMap: config.enabled.sourceMaps } },
        {
          loader: 'postcss', options: {
            config: { path: __dirname, ctx: config },
            sourceMap: config.enabled.sourceMaps,
          },
        },
        { loader: 'resolve-url', options: { sourceMap: config.enabled.sourceMaps } },
        {
          loader: 'sass', options: {
            sourceMap: config.enabled.sourceMaps,
            sourceComments: true,
          },
        },
      ],
    }),
  },
  {
    test: /\.scss$/,
    include: config.paths.amp,
    use: ExtractTextPlugin.extract({
      fallback: 'style',
      use: [
        { loader: 'cache' },
        { loader: 'css', options: { sourceMap: config.enabled.sourceMaps } },
        {
          loader: 'postcss', options: {
            config: { path: __dirname + '/amp', ctx: config },
            sourceMap: config.enabled.sourceMaps,
          },
        },
        { loader: 'resolve-url', options: { sourceMap: config.enabled.sourceMaps } },
        {
          loader: 'sass', options: {
            sourceMap: config.enabled.sourceMaps,
            sourceComments: true,
          },
        },
      ],
    }),
  },

Basically, I’m excluding the AMP stylesheet in the first SCSS pipeline and replicating it, but adding the modified AMP postcss rules in the second.

It seems a bit hacky, and I don’t like how I’m replicating code. I wonder if there’s a better way to address this?

Nevertheless, I’m able to generate AMP compliant stylesheets now. :slight_smile: