Setup new rails app with tailwind

by msypniewski511 in Ruby for Rails

Start new app

rails new app_name -T  -d postgresql --css=tailwind --javascript=esbuild
cd app_name
rails db:create

Configure Tailwind

yarn add postcss-import
touch postcss.config.js

postcss.config.js

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer')
  ]
}

app/assets/stylesheets/application.tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Add tailwind forms:

yarn add @tailwindcss/forms
if not exist: touch tailwind.config.js

tailwind.config.js

module.exports = {
  mode: 'jit',
  content: [
    './app/views/**/*.html.erb',
    './app/helpers/**/*.rb',
    './app/assets/stylesheets/**/*.css',
    './app/javascript/**/*.js',
  ],
  theme: {
    extend: {},
  },
  plugins: [require('@tailwindcss/forms')],
}

ESBuild config

Add chokidar to enable watching and automatically refreshing.

yarn add chokidar -D
touch esbuild.config.js

esbuild.config.js

#!/usr/bin/env node

const esbuild = require('esbuild')
const path = require('path')

// Add more entrypoints, if needed
const entryPoints = [
  "application.js",
]
const watchDirectories = [
  "./app/javascript/**/*.js",
  "./app/views/**/*.html.erb",
  "./app/assets/stylesheets/*.css",
  "./app/assets/stylesheets/*.scss"
]

const config = {
  absWorkingDir: path.join(process.cwd(), "app/javascript"),
  bundle: true,
  entryPoints: entryPoints,
  outdir: path.join(process.cwd(), "app/assets/builds"),
  sourcemap: true
}

async function rebuild() {
const chokidar = require('chokidar')
const http = require('http')
const clients = []

http.createServer((req, res) => {
  return clients.push(
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      "Access-Control-Allow-Origin": "*",
      Connection: "keep-alive",
    }),
  );
}).listen(8082);

let result = await esbuild.build({
  ...config,
  banner: {
    js: ' (() => new EventSource("http://localhost:8082").onmessage = () => location.reload())();',
  },
})

chokidar.watch(watchDirectories).on('all', (event, path) => {
  if (path.includes("javascript")) {
    result.rebuild()
  }
  clients.forEach((res) => res.write('data: update\n\n'))
  clients.length = 0
});
}

if (process.argv.includes("--rebuild")) {
  rebuild()
} else {
  esbuild.build({
    ...config,
    minify: process.env.RAILS_ENV == "production",
  }).catch(() => process.exit(1));
}

bin/dev script

package.json

"scripts": {
  "build": "node esbuild.config.js",
  "build:css": "tailwindcss --postcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css"
},

Procfile.dev

web: bin/rails server -p 3000
js: yarn build --watch
css: yarn build:css --watch

CableReady, StimulusReflex, and Mrujs

bundle add stimulus_reflex
yarn add stimulus_reflex

0 Replies


Leave a replay

To replay you need to login. Don't have an account? Sign up for one.