Specifying Paths for View Components in a Gem Utilizing Tailwind CSS in `tailwind.config.js`

75 views Asked by At

I'm developing a gem that acts as a library of view components integrated with Tailwind CSS. In this project, there's a crucial tailwind.config.js file where I specify the paths for building the tags used in the components. Here's a sample configuration:

module.exports = {
  content: [
    './app/views/**/*.html.erb',
    './app/helpers/**/*.rb',
    './app/assets/stylesheets/**/*.css',
    './app/javascript/**/*.js',
    './app/components/**/*.rb'
  ]
}

My question revolves around determining the correct path to include for the gem's view components. Would it be something like my_gem/app/components/**/*.rb?

Additionally, I'm curious if there's a method to automate the addition of this path information upon installing the gem?

2

There are 2 answers

2
Ben On

Gem.loaded_specs['your_gem_name'].full_gem_path sounds like a good starting point to investigate into

The idea is to be able to read process.env.YOUR_GEM_COMPONENTS_PATH within tailwind.config.js, so there might be some tweaking to do around it.

ENV['YOUR_GEM_COMPONENTS_PATH'] = Rails.root.join(
  Gem.loaded_specs['your_gem_name'].full_gem_path,
  "app", "components"
)

vite_rails provides a similar use case (engine link), this is how it is defined in the parent app, and how it is consumed in the vite config

1
Alex On

You could merge your gem config with main app config, just need to fix relative paths:

// tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  content: [
    './public/*.html',
    './app/helpers/**/*.rb',
    './app/javascript/**/*.js',
    './app/views/**/*.{erb,haml,html,slim}'
  ],
  // ...
}

const path = require('path');
const execSync = require('child_process').execSync;

const gemName = "my_gem";
const gemPath = execSync(`bin/bundle show ${gemName}`, { encoding: 'utf-8' }).trim();
const gemConfig = require(path.resolve(gemPath, 'tailwind.config.js'));

gemConfig.content.forEach(contentPath => {
  const absolutePath = path.resolve(gemPath, contentPath);
  module.exports.content.push(absolutePath);
});

Based on this answer by @Torsten:
https://stackoverflow.com/a/74737193/207090