Profile picture Schedule a Meeting
c a n d l a n d . n e t

Upgrading Rails Webpacker and TailwindCSS

Dusty Candland | | cloudsh, webpack, webpacker, rails, rails6, tailwindcss

In my continuing effort to consolidate technologies used in my projects I'm changing an existing Rails app to use Webpacker and TailwindCSS, and away from Bootstrap.

These are the steps I took to get TailwindCSSv2 working. Add webpack to Rails 5 covers the whole process, including moving existing JS and CSS files to Webpacker.

Install & Setup

Add to Gemfile

gem "webpacker", "~> 5.0"
bundle install
bin/rails webpacker:install

Remove .postcssrc.yml if it exists! Wasted hours wondering why @tailwind wasn't being processed because this file was loading and not postcss.config.js.

rm .postcssrc.yml

Set extract_css to true in config/webpacker.yml

Install latest packages, included PostCSS8. This will cause a small issue later, but it has an easy fix.

yarn add autoprefixer postcss postcss-cssnext postcss-loader@4.2.0 tailwindcss
yarn upgrade

Add tailwind.config.js to the project root

module.exports = {
  purge: [
    './app/**/*.html',
    './app/**/*.html.slim',
    './app/**/*.html.erb',
    './app/**/*.js'
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
}

Might be good to include helpers in the purge config

Update postcss.config.js with Tailwind & Autoprefixer.

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}

Integrate into the application

Add application.css in /app/javascript/css/application.css

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

Import the application.css file in app/javascript/packs/application.js.

import '../css/application.css'

Fix this error related to PostCSS8, actually related to the upgraded postcss-cssloader needed to support PostCSS8.

    ERROR in ./app/javascript/css/application.css (./node_modules/css-loader/dist/cjs.js??ref--5-1!./node_modules/postcss-loader/dist/cjs.js??ref--5-2!./app/javascript/css/application.css)
    Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
    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? }
config/webpack/environment.js
    ...

To fix that error, change the config/webpack/environment.js to this:

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

function hotfixPostcssLoaderConfig (subloader) {
  const subloaderName = subloader.loader
  if (subloaderName === 'postcss-loader') {
    if (subloader.options.postcssOptions) {
      console.log(
        '\x1b[31m%s\x1b[0m',
        'Remove postcssOptions workaround in config/webpack/environment.js'
      )
    } else {
      subloader.options.postcssOptions = subloader.options.config
      delete subloader.options.config
    }
  }
}

environment.loaders.keys().forEach(loaderName => {
  const loader = environment.loaders.get(loaderName)
  loader.use.forEach(hotfixPostcssLoaderConfig)
})

module.exports = environment

Run bin/webpack to make sure everything is happy.

Add the packs to the HTML head tag.

= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'

References

TailwindCSS Installation Docs

Use Tailwind CSS v2 with Rails

Rails Webpacker Upgrade

Rails Webpacker

Webmentions

These are webmentions via the IndieWeb and webmention.io. Mention this post from your site: