platanus / activeadmin_addons

Extends ActiveAdmin to enable a set of great optional UX improving add-ons
MIT License
763 stars 288 forks source link

Brokenness with jsbundling-rails? #403

Closed MrJoy closed 1 year ago

MrJoy commented 2 years ago

I've got an app on Rails 7 using Propshaft, jsbundling-rails, and cssbundling-rails. It took some herculean effort to get as far as making jQuery / jQuery-UI available to ArcticAdmin (and possibly ActiveAdmin_Addons -- I don't recall), but I am stuck on getting the plugin's NPM module to see Select2.

I'm using the --inject option to esbuild to inject jQuery and jQuery-UI but the same trick doesn't seem to work for Select2.

Specifically, my package.json looks like this:

{
  "name": "core",
  "private": "true",
  "scripts": {
    "build:js:dev": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --inject:./app/javascript/hacks/jquery.js",
    "build": "esbuild app/javascript/*.* --bundle --outdir=app/assets/builds --minify --inject:./app/javascript/hacks/jquery.js",
    "build:css:dev": "sass ./app/assets/stylesheets/entrypoints:./app/assets/builds --source-map --load-path=node_modules",
    "build:css": "sass ./app/assets/stylesheets/entrypoints:./app/assets/builds --no-source-map --load-path=node_modules"
  },
  "dependencies": {
    "@activeadmin/activeadmin": "^2.13.0",
    "@fortawesome/fontawesome-free": "^5.0.0",
    "activeadmin_addons": "^1.0.0",
    "arctic_admin": "^4.0.1",
    "chart.js": "^3.7.1",
    "chartkick": "^4.1.1",
    "graphiql": "1.8.9",
    "graphql": "^16.1.0",
    "graphql-ws": "^5.8.2",
    "punycode": "^2.1.1",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "esbuild": "^0.14.39",
    "sass": "^1.52.0"
  }
}

And the jquery hack looks like this:

export { default as $ } from 'jquery';
export { default as jQuery } from 'jquery';

import "../vendor/jquery-ui-1.12.1.min.js";

I tried vendoring select2 and importing it the same way, to no avail.

Of course, this all is very much a fairly ugly kludge but I'm not aware of any other way to make things work.

Perhaps you're better situated to get things working under a Propshaft+cssbundling+jsbundling world?

joker-777 commented 2 years ago

@MrJoy Hi, I also use prophaft and jsbundling-rails but for me, it already fails because it expects sprockets to exist. How did you fix this?

/usr/local/bundle/gems/sprockets-rails-3.4.2/lib/sprockets/railtie.rb:110:in block in <class:Railtie>': Expected to find a manifest file inapp/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)

MrJoy commented 2 years ago

I've forked the repo to remove the Sprockets dependency. https://github.com/FasterBetter/activeadmin_addons_nosprockets

So, it seems there's a bit more that's needed to make this work with Propshaft besides what I've discovered. It seems like getting this all sorted out will help add longevity to ActiveAdmin_addons.

joker-777 commented 2 years ago

@MrJoy Yes, that's what I also now did. For me, it actually works now, at least the select2 fields I've been using. I haven't tested all features though, e.g. icons and color picket.

MrJoy commented 2 years ago

What did you do to get select2 to work? I have been unable to figure out how to make it happen.

joker-777 commented 2 years ago

@MrJoy We use propshaft with jsbundling-rails and webpack. There is a activeadmin_addons npm package which you can install and include. It also provides the CSS. It is documented here for webpacker but also applies for the just mentioned setup.

MrJoy commented 2 years ago

Yeah, that's what I was doing and just not having any luck.

MrJoy commented 2 years ago

Specifically, when I try that, I wind up with this from cssbundler:

12:49:50 css.1     | Error: Can't find stylesheet to import.
12:49:50 css.1     |   ╷
12:49:50 css.1     | 1 │ @import 'select2';
12:49:50 css.1     |   │         ^^^^^^^^^
12:49:50 css.1     |   ╵
12:49:50 css.1     |   activeadmin_addons/src/stylesheets/all.scss 1:9           @import
12:49:50 css.1     |   app/assets/stylesheets/entrypoints/active_admin.scss 1:9  root stylesheet

And, in the browser console when loading up a page:

Uncaught TypeError: import_jquery.default.fn.select2 is undefined
    <anonymous> nested-select.js:1
    <anonymous> active_admin-15f5b399337c37d72457eb2acb943c285a27f33a.js:40128
[nested-select.js:1](http://localhost:5000/node_modules/activeadmin_addons/src/inputs/nested-select.js)
    <anonymous> nested-select.js:1
    <anonymous> active_admin-15f5b399337c37d72457eb2acb943c285a27f33a.js:40128

My JS bundle entrypoint is:

import Rails from "@rails/ujs";

Rails.start();

import "@activeadmin/activeadmin";

// N.B. We can't load this because it chokes trying to find Select2 and I have yet to figure out
// how to solve that.  Injecting it doesn't seem to work.  Importing it doesn't work.  Gahhh!
import "activeadmin_addons";

import "arctic_admin";

import "chartkick/chart.js";

And my CSS bundle entrypoint is:

@import "activeadmin_addons/src/stylesheets/all";

@import "arctic_admin/src/scss/main";

@import "../active_admin/monkeypatches";
@import "../active_admin/ux";
@import "../active_admin/widgets";

$fa-font-path: ".";
@import "@fortawesome/fontawesome-free/scss/fontawesome";
@import "@fortawesome/fontawesome-free/scss/solid";

To get this far, I had to inject jQuery into the bundle forcibly, as you can see in the actual ticket body.

No matter what I do, I can't get it to find select2.

MrJoy commented 2 years ago

Part of the issue seems to be import paths. For the CSS, the correct import statement seems to be @import "select2/dist/css/select2";, not @import "select2". So I guess sass isn't mapping things the same way Sprockets did and I'm not sure how to correct that.

On the JS side, I have absolutely no idea what's going on, or how to correct it. Forcibly injecting Select2 alongside jQuery/jQuery-UI seems like it should work, but it just... doesn't.

MrJoy commented 2 years ago

@joker-777 Can you give your package.json, active_admin.scss, and active_admin.js files for comparison?

MrJoy commented 2 years ago

One further issue I'm running into using dart-sass is this:

@import 'jquery-datetimepicker/build/jquery.datetimepicker.min.css';

It's not liking the .css at the end, and leaving the import in the resulting CSS. Hrm.

joker-777 commented 2 years ago

@MrJoy We have the select2 package installed separately of activeadmin-addons and we use the imports-loader as well

imports_loaders.js

module.exports = { 
  jquery_plugins_loader: {
    test: /jquery\.|activeadmin/,
    use: [
      {   
        loader: "imports-loader",
        options: {
          type: "commonjs",
          imports: [
            "single jquery jQuery",
            "single jquery $"
          ]   
        }   
      }   
    ]   
  },  
  select2_loader: {
    test: /select2/,
    use: [
      {   
        loader: "imports-loader",
        options: {
          type: "commonjs",
          imports: ["single jquery jQuery"]
        }   
      }   
    ]   
  }
}

webpack.config.js

const {
  jquery_plugins_loader,
  select2_loader
} = require("./imports_loaders")

module.exports = { 
  ...
  module: {
    rules: {
      select2_loader,
      jquery_plugins_loader
    }
  }
  ...
}
MrJoy commented 2 years ago

So basically, you're using Webpack, not ESBuild. Gotcha.

joker-777 commented 2 years ago

Yes, that's what I said, no?

We use propshaft with jsbundling-rails and webpack

joker-777 commented 2 years ago

We would love to use esbuild but it doesn't support dynamic chungs so well yet.

MrJoy commented 2 years ago

Yes, that's what I said, no?

We use propshaft with jsbundling-rails and webpack

You did indeed, and I misread it. My bad.

For us, the lack of dynamic chunks is a non-issue as our front-end is a Next.js app with its own build/deploy process and the Rails asset pipeline is only used for the admin system. In our situation, giving up select2 is preferable to dealing with webpack again. That, and switching to this new arrangement let me drop 915 transitive dependencies which makes it eaier to manage license compliance and supply chain security. As such, I'm not terribly inclined to explore the webpack route at this time. I will keep it in mind, in case I encounter other issues. Thank you for the details.

joker-777 commented 2 years ago

Thanks, Next.js looks definitely very interesting.

difernandez commented 1 year ago

Hi all, we released a new v2 beta, which, among other things, removes select2 and sprockets support, so we’ll be closing this issue. You can see more details here. Feel free to try it and open a new issue if you find anything there.