DEV Community

Ranjan Purbey
Ranjan Purbey

Posted on

Use Tailwind CSS v2.0 with Rails

Recently, the folks behind Tailwind CSS released v2.0 🎉🎉
(Well, that was in November 2020, but hey did time even exist in 2020?!)

Checkout the release notes

But unfortunately when you try to add it to your Rails project, Webpack throws the following error (I am assuming you have already setup @rails/webpacker in your project):
Error: Tailwind requires PostCSS 8

Error: PostCSS plugin tailwindcss requires PostCSS 8.
Enter fullscreen mode Exit fullscreen mode

The error message is simply saying that Tailwind v2 depends on PostCSS 8, however the current builds of webpacker use PostCSS 7. To fix this issue we can take one of two approaches:

Easy Method

Well, Tailwind maintainers realized that PostCSS 8, being a recent release itself, is not very widely supported by popular frameworks like Rails. So, they were kind enough to release a PostCSS 7 compatible build for the time being.

All you have to do is

yarn remove tailwindcss
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat
Enter fullscreen mode Exit fullscreen mode

...aaand done!!

The compatibility build supports all of the features as that of the "normal" build. Awesome! Except for one catch though:

If you are working on a decently-sized project, the chances of the Rails version in your application being upgraded anytime soon may be low. And it is probable that the subsequent releases of Tailwind might not come with a compatibility build. So what do we do?

(not-so) Hard Method

Well, won't it be better if we could just bump the PostCSS version in our Rails app? That way we won't have to depend on or worry about a compatibility build.
Let's try

yarn add tailwindcss@^2.0.2 postcss@^8.2.4
./bin/webpack-dev-server
Enter fullscreen mode Exit fullscreen mode

Hmm, same error message? Oh yes, we should also upgrade postcss-loader

yarn add postcss-loader@^4.2.0
./bin/webpack-dev-server
Enter fullscreen mode Exit fullscreen mode

Another error message!!
Error: Invalid options passed to postcss-loader

ValidationError: Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'config'. These properties are valid:
   object { postcssOptions?, execute?, sourceMap?, implementation? }
Enter fullscreen mode Exit fullscreen mode

Here webpack is complaining that postcss-loader was initialized with an invalid option config. In older versions of the loader, config was used to pass PostCSS configuration option. From the error message above, you can probably guess that it has been renamed to postcssOptions. "Dang! I have to edit webpack config now!" was my reaction, but turns out it's not that difficult.
If you look at the contents of your config/webpack/environment.js file, it will look something like this:

const { environment } = require('@rails/webpacker')

module.exports = environment
Enter fullscreen mode Exit fullscreen mode

We change it to remove the config key from postcss-loader options for each file type (css, sass, moduleCss, etc.):

const { environment } = require("@rails/webpacker");

environment.loaders
  .map((rule) => rule.value.use)
  .flat()
  .filter(({ loader }) => loader === "postcss-loader")
  .forEach((item) => {
    if (item.options) {
      item.options.postcssOptions = { from: item.options.config.path };
      delete item.options.config;
    }
  });

module.exports = environment;
Enter fullscreen mode Exit fullscreen mode

Done!! Now webpack should compile your bundle just fine.

Top comments (2)

Collapse
 
greegus profile image
Matúš Duchoň • Edited

Actually, setting from option did break @import rules in my project. I was able to sort it out by omitting it and also disabling the source map generation. Although, this might be a very project-specific issue.


if (item.options) {
  item.options.sourceMap = false
  delete item.options.config
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ranjanpurbey profile image
Ranjan Purbey

Glad you're able to resolve the issue. from option is needed for source map generation and in a rails project defaults to the project root. However more info will be needed to debug the issue if you do need to enable source maps