Gridsome: Configuring PostCSS to work with TailwindCSS

Created on 13 Oct 2018  路  22Comments  路  Source: gridsome/gridsome

Hi!

Awesome project - been playing with it for the last hour and super impressed! 馃憦

I am trying to use TailwindCSS with gridsome. I have tried the following approaches but neither are working (the CSS file doesn't run through PostCSS)

1) add a postcss key to package.json:

"postcss": {
    "plugins": {
      "tailwindcss": "./tailwind.js",
      "autoprefixer": {}
    }
  }

2) Add a .postcssrc.js or postcss.config.js file in root:

const tailwindcss = require('tailwindcss')

module.exports = {
  "plugins": [
    require('tailwindcss')('tailwind.js'),
    require('autoprefixer')(),
  ]
}

Neither are working.

Solution 1 is what works with vue-cli 3.

Is there a different way to achieve this? Is chainwebpack the way to do it?

Thanks in advance 馃帀

Most helpful comment

Looking good!!

I think you are adding you own postcss-loader for .css files which picks up your config. But you can also modify the existing rule with the following code. It will look for a tailwind.js file on root in your project.

chainWebpack: config => {
  config.module
    .rule('css') // or sass, scss, less, postcss, stylus
    .oneOf('normal') // or module
      .use('postcss-loader')
        .tap(options => {
          options.plugins.push(tailwindcss('./tailwind.js'))
          return options
        })
},

We are going to make this easier :)

All 22 comments

Thank you :)

Looks like the postcss-loader isn't picking up your config because gridsome is adding the autoprefixer plugin. The plan is to have a postcss option in gridsome.config.js, but the option is not implemented yet. We can consider not adding custom postcss options in the webpack config, and take full advantage of the postcss-load-config module instead. But for now you can add options with chainWebpack. The rule name is postcss-loader.

Woooo! I got it working.

I probably did it totally wrong and did some damage, but for now it allows me to run my CSS through PostCSS :)

Here's what I added to my gridsome.config.js file. Please know this code is probably not the proper implementation, but it got me where I wanted for my weekend fun project..

chainWebpack: config => {
  config.module
    .rule('postcss-loader')
    .test(/\.css$/)
    .use(["tailwindcss", "autoprefixer"])
    .loader('postcss-loader')
},

image

Looking good!!

I think you are adding you own postcss-loader for .css files which picks up your config. But you can also modify the existing rule with the following code. It will look for a tailwind.js file on root in your project.

chainWebpack: config => {
  config.module
    .rule('css') // or sass, scss, less, postcss, stylus
    .oneOf('normal') // or module
      .use('postcss-loader')
        .tap(options => {
          options.plugins.push(tailwindcss('./tailwind.js'))
          return options
        })
},

We are going to make this easier :)

Ah, I was super close - I played with the .tap() options modifier but couldn't find the right syntax / chain order.

Thanks for that, much cleaner solution! I will try it and then close the issue! 馃榿

Works beautifully! Thanks you 馃帀

question about using 'chainWebpack', is this overriding gridsome default postcss ? seems no more autoprefixer when using

It should keep autoprefixer if you push your own plugins to options.plugins without overriding it.

When using code posted in your comment : https://github.com/gridsome/gridsome/issues/9#issuecomment-429655559, i dont see any css prefixed in the output css after build :/
EG:

display: flex;

By default, did i need to add .browserslistrc or something ?

@Devportobello That's probably because autoprefixer is the first plugin inside the array.

@hacknug Damn, so i need to reorder to keep autoprefixer in the last call ?

@Devportobello I guess so although you could also do something like this if you don't wanna get rid of whatever is already there (right now it's just Autoprefixer but I guess there could be other things at some point or in some projects):

chainWebpack: config => {
  config.module
    .rule('postcss') // css, sass, scss, less, postcss, stylus
    .oneOf('normal') // normal, module
    .use('postcss-loader')
    .tap(options => {
      options.plugins.unshift(...[
        require('postcss-import'),
        require('tailwindcss')(config.tailwind),
      ])

      if (process.env.NODE_ENV === 'production') {
        options.plugins.push(...[
          require('@fullhuman/postcss-purgecss')(config.purgecss),
        ])
      }

      return options
    })
},

Hi,

firstly I would like to thank you for this amazing tool that you created!

I am trying to get everything up and running with Tailwind and Purgecss. The example that @hacknug provided is partially working. If I leave it like it is, it will purge css, but Tailwind does not seem to work.

If I change .rule('postcss') to .rule('css) Tailwind does work, but can not run build.

I don't have much experience with Webpack and I would be really thankful for a working example (maybe a whole Gridsome repo).

@Jurero123 .rule('language') will let webpack know which type of files to look for. I like writing postCSS on files with the .pcss extension to make sure no one expects that CSS to work without processing it somehow first. You can use css if that's the extension of the file where you have your Tailwind directives.

You can see the extensions that will match for your config here: https://github.com/gridsome/gridsome/blob/ffb29eee33477b68d0b14d9e42d445c0e807ccb0/gridsome/lib/webpack/createBaseConfig.js#L131-L141

@hacknug thank for a prompt reply.

Ok, that part is now working fine, but I am still getting errors related to Purgecss, but I guess I will have to take some time and dive into Webpack / Postcss.

What kind of errors? So you have a public repo we can take a look at? I have almost no experience with webpack but everything's working fine for me here: https://github.com/hacknug/klayaya

Thank for sharing the repo. I will take a look before bothering you any more with this. :+1:

UPDATE: the only difference was in "purgcecss.config.js". Now it simply works! Thanks a lot! I really appreciate it!

Ahhhhhhh. I know what might be the issue. Having purgcecss.config.js worked for me just like having purgecss' config directly inside chainWebpack. Having the config in a variable and referencing that wouldn't work for some reason. Didn't bothered debugging since this solved my issue but maybe it'd be a good idea to open an issue if it really is one.

Is that what you were doing? (having the config object in a variable outside chainWebpack)

To be honest I tried so many things that I am not sure anymore what I was trying. And my first commit was just after I got it to work by comparing it to your project.

This is how I use PurgeCSS:

  1. Install purgecss with npm install purgecss
  2. Create purgecss.config.js in the root of project and add to it:
module.exports = {
  content: [
    './dist/**/*.html',
    './dist/assets/js/*.js'
  ],
  css: [
    './dist/assets/css/*.css'
  ],
  rejected: true
}
  1. Add next script into package.json: "purgecss": "node_modules/purgecss/bin/purgecss --config ./purgecss.config.js --out ./dist/assets/css"
  2. Modify build script: "build": "gridsome build && npm run purgecss"

For me works perfectly for deleting unused CSS of fontawesome library, but also should work with other packages. Reduced one of .css bundles size from 60K to 8K.

Woooo! I got it working.

I probably did it totally wrong and did some damage, but for now it allows me to run my CSS through PostCSS :)

Here's what I added to my gridsome.config.js file. Please know this code is probably not the proper implementation, but it got me where I wanted for my weekend fun project..

chainWebpack: config => {
  config.module
    .rule('postcss-loader')
    .test(/\.css$/)
    .use(["tailwindcss", "autoprefixer"])
    .loader('postcss-loader')
},

image

Hey @simonswiss, would you consider posting that little starter as a repo?

Hey, still need some help. I'm trying to add some plugins to postCSS, however the processor is not compiled well.

gridsome.config.js

const postcssPlugins = [
    require('postcss-mixins'),
    require('autoprefixer'),
    require('postcss-nesting'),
    require('postcss-custom-media'),
    require('postcss-hexrgba'),
    require('postcss-automath')
]

module.exports = {
    siteName: 'gridsome-postcss',
    plugins: [],
    chainWebpack: config => {
        config.module
                    .rule('postcss-loader')
                    .oneOf('normal')
                    .test(/\.css$/)
                    .use(postcssPlugins)
                    .loader('postcss-loader')
    }
}

postcss.config.js

const config = {
    plugins: [
        require('postcss-mixins'),
        require('autoprefixer'),
        require('postcss-nesting'),
        require('postcss-hexrgba'),
        require('postcss-automath'),
        require('postcss-critical-split')({
            'output': process.env.ENV === 'production' ? 'rest' : 'input',
            'startTag': 'defer:start',
            'endTag': 'defer:end',
            'blockTag': 'defer'
        })
    ]
}

module.exports = config

@khoipro not sure if you solved or not but ideally you'll either push or unshift postcss plugins to whatever's already on Gridsome's config like shown here: https://github.com/brandonpittman/gridsome-plugin-tailwindcss/blob/master/gridsome.server.js#L27-L42

Was this page helpful?
0 / 5 - 0 ratings