Search code examples
cssruby-on-railssass

css-bundling gem + Tailwind CSS with ActiveAdmin


I've been trying the new Rails solution without webpacker, but using css-bundling and js-bundling. css-bundling comes with some "pre-choices" like TailwindCSS.

When you install it, links the build css step in the asset pipeline with the command in the package.json, like this in the package.json:

"build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css"

This works properly.

Now comes the question. I'm using the ActiveAdmin gem, that creates the active_admin.scss file with the following code:

@import "active_admin/mixins";
@import "active_admin/base";

Problem is, if I try to compile this CSS using TailwindCSS as preprocessor, it is unable to find the imports:

tailwindcss --postcss -i app/assets/stylesheets/active_admin.sass.scss -o active_admin.css --trace-warnings
(node:52651) UnhandledPromiseRejectionWarning: Error: Failed to find 'active_admin/mixins'
  in [
    .../app/assets/stylesheets
  ]
    at .../node_modules/postcss-import/lib/resolve-id.js:35:13
    at async LazyResult.runAsync (.../tailwindcss/peers/index.js:57896:11)
(Use `node --trace-warnings ...` to show where the warning was created)

So I assume that is unable to find the needed CSS located in the gems. The question is: Do you know how can I tell css-bundling to locate the CSS in different places? I assume also that sprockets is smart enough to do it, but I don't know how to deal with css-bundling + build:css command in the package.json

Thanks!


Solution

  • This answer may be incomplete or completely worthless, and definitely feels like something I would not want to maintain, but the steps below seemed to be the path to making this work:

    Note: I'm using Bootstrap instead of Tailwind, but it should be somewhat the same.

    1. Install the npm-run-all package for running multiple scripts:

    yarn add npm-run-all

    1. File setups:
    // package.json
    
      "scripts": {
        "build:js": "npm-run-all --parallel \"build:js:* {@}\" --",
        "build:js:application": "esbuild app/javascript/application.js --bundle --sourcemap --outfile=app/assets/builds/application.js",
        "build:js:active_admin": "esbuild app/javascript/active_admin.js --bundle --sourcemap --outfile=app/assets/builds/active_admin.js",
        "build:css": "npm-run-all --parallel \"build:css:* {@}\" --",
        "build:css:application": "sass ./app/assets/stylesheets/application.bootstrap.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules",
        "build:css:active_admin": "sass ./app/assets/stylesheets/active_admin/active_admin.scss ./app/assets/builds/active_admin.css --no-source-map --load-path=node_modules"
      }
    
    // packages/jquery.js
    
    import jquery from 'jquery';
    window.jQuery = jquery;
    window.$ = jquery;
    
    // app/javascript/active_admin.js
    
    import './packages/jquery.js' // position for hoisting
    import '@activeadmin/activeadmin/app/assets/javascripts/active_admin/base.js';
    
    // app/assets/stylesheets/active_admin/active_admin.scss
    
    @import "@activeadmin/activeadmin/src/scss/mixins";
    @import "@activeadmin/activeadmin/src/scss/base";
    
    
    # Procfile.dev
    
    web: bin/rails server -p 3000
    js: yarn build:js --watch
    css: yarn build:css --watch