We've moved discussions to Discord

flatpickr on Heroku (npm dependency Hell)

Jeff Helman
  • flatpickr works fine in my local environment, but it fails (sielently) when I deploy to Heroku.

I would like to blame Heroku deployment nuances, but I had a similar problem when I first started refactoring my app to use the latest version of Jumpstart Pro a couple of weeks ago (and I'm finding nothing out there on SO or elsewhere about this), so I think it is me.

On my local (Mac) environment, when I (manually) merged my app features into the latest Jumpstart Pro template, flatpickr functionality (silently) stopped working. I ended up re-installing flatpickr, but that installation process was failing, so (after Google reminded me how) I ended up doing the nuclear option: rm -rf node_modules && npm install  to be able to get flatpickr installed. 
  • I have had to resort to that before, so I'm sure I'm doing something wrong, re: not getting "global access" working with my npm installs.

Anyway, all of that, plus verifying that my application.js in the new template had this:
import flatpickr from "flatpickr"
require("flatpickr/dist/flatpickr.css")
... resulted in flatpickr finally working as expected (matching how I was using it with an older version of Jumpstart Pro).

Deploying all these updates to Heroku has resulted in the same (silent) failures of flatpickr I saw in my local environment. Plowing through Heroku docs (which seem pretty sparse about dependencies), I verified that flatpickr is listed in package.json (as the Heroku docs specified).

I don't see anything in my Heroku deployment logs about package.json being processed (i.e., as opposed to the detailed log info about the Gemfile being processed), so I'm not getting any help there.

I will be very grateful for any help here.
Chris Oliver
Jumpstart Pro actually uses Flatpicker in the administrate.js pack to add it to the admin. You can import it in your application.js too. You can see how it's included in date_time_picker.js We're not loading the css file and it works just fine for me in production.

Rails compiles webpack assets as part of the "rails assets:precompile" step when deploying to production, so if it's in your webpack stuff, it will compile during the deploy.
Chris Oliver
Also I should point out that we're using the asset pipeline for the flatpicker CSS with Administrate, so it wouldn't include the CSS in the webpack output.
Jeff Helman
Thanks,  Chris Oliver .  I'll take another look at that.
Ugurcan Kaya
I got it to work doing this:

- create a new stimulus controller and add the code from "/javascript/administrate/components/date_time_picker.js" to this new controller
- Add flatpickr CSS to the asset pipeline
- Use an input field with data-type and controller attribute

  <%= f.text_field :date,
            controller: 'flatpickr',
            class: 'form-control input',
            data: {
              type: 'datetime',
            }
            %>
Jeff Helman
Gaaaaaaaah!!! After struggling through the byzantine (and outdated, conflicting) AWS instructions to get S3 configured for my avatars (and laughing as Jason shared similar struggles on the latest Remote Ruby podcast), I then spent the next  [too many to admit] hours researching this again.

After studying Rails docs about the asset pipeline, I re-watched "How to use Javascript via Webpacker in Rails 6," to confirm that my Flatpickr configuration pretty much exactly matches what is shown in that episode:
app/javacsript/packs/application.js:
...

import flatpickr from 'flatpickr'
// require("flatpickr/dist/flatpickr.css") COMMENTED OUT AFTER ADDING TO APPLICATION.CSS

document.addEventListener("turbolinks:load", () => {
  flatpickr("[data-behavior='flatpickr']", {
    altInput: true,
    altFormat: "F j, Y",
    dateFormat: "Y-m-d",
  })
})

Looking at Jumpstart Pro on GitLab, I noticed this in app/assets/stylesheets/administrate/application.scss:
@import "flatpickr/dist/flatpickr.css";
... so I dropped that into my (previously empty) app/assets/stylesheets/application.css and commented out the require("flatpickr/dist/flatpickr.css") in application.js, as shown above.

This all works great locally, and it builds without errors on Heroku--just like the original configuration I started with when application.js had that require("flatpickr/dist/flatpickr.css") not commented out.

However, flatpickr is ignored by the Heroku build when I use it there. Here's that part of my _form partial:
<div class="field">
    <%= form.label :transaction_date %>
    <%= form.text_field :transaction_date, data: {behavior: "flatpickr"}, class: "form-control" %>
  </div>
This usage pattern in _form obviously matches the configuration shown in application.js--or it couldn't be working locally.

I'm tempted to try the suggestion of  Ugurcan Kaya  to configure a Stimulus controller, but I think that conquering this configuration is central to my understanding of the basic Webpacker/asset pipeline/dependency management flow. 
Jeff Helman
Bump to  Chris Oliver   ... any thoughts? This is blocking me in production (Heroku). Thanks!
Chris Oliver
Jeff Helman Sorry, I'm a bit busy with the holidays so I haven't been following as closely as normal.

So you're saving you have missing CSS for flatpicker in production? If so, then it's likely that they're being stripped out by PurgeCSS when it minifies everything for production. You can add classes to the exceptions array so that they stay included. That's almost certainly what's going on.
Jeff Helman
Many thanks, Chris Oliver .  I'll check that out. I really appreciate your response tonight!
Jose Lopes
I have the same problem, I removed purgecss (with yarn remove) and postcss-purgecss (manually from package.json) and it worked.
If you have html elements with classes being generated by javascript, like dual-listbox, you will definitely have problems with purgeCSS. 
must be optional in jumpstart configuration.
Chris Oliver
Just add exceptions to PurgeCSS rules as you need add third-party libraries. 

Removing PurgeCSS will only slow your site down as you will be shipping lots of unused CSS.
Notifications
You’re not receiving notifications from this thread.