Shopify / shopify_app

A Rails Engine for building Shopify Apps
MIT License
1.77k stars 687 forks source link

Polaris CSS build fails on Heroku? #1037

Closed igrigorik closed 4 years ago

igrigorik commented 4 years ago

Are there any special considerations or requirements for deployment & build on Heroku?

I have an app running locally and webpacker is doing all the right things, with both JS and CSS coming through correctly, but when I push the same code to Heroku the JS is there (elements are responsive) but it looks like Polaris styles are missing -- also, I don't see any failed requests. Would really appreciate any tips, and apologies upfront if it's a misconfiguration on this end, since I've been running in circles on this one for well over and hour.

The app:

Heroku build output...

remote: Building source:
remote:
remote: -----> Ruby app detected
remote: -----> Installing bundler 2.0.2
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.6
remote: -----> Installing dependencies using bundler 2.0.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Using rake 13.0.1
remote:        Using concurrent-ruby 1.1.6
remote:        Using i18n 1.8.5
remote:        Using minitest 5.14.1
remote:        Using thread_safe 0.3.6
remote:        Using tzinfo 1.2.7
remote:        Using zeitwerk 2.4.0
remote:        Using activesupport 6.0.3.2
remote:        Using builder 3.2.4
remote:        Using erubi 1.9.0
remote:        Using mini_portile2 2.4.0
remote:        Using nokogiri 1.10.10
remote:        Using rails-dom-testing 2.0.3
remote:        Using crass 1.0.6
remote:        Using loofah 2.6.0
remote:        Using rails-html-sanitizer 1.3.0
remote:        Using actionview 6.0.3.2
remote:        Using rack 2.2.3
remote:        Using rack-test 1.1.0
remote:        Using actionpack 6.0.3.2
remote:        Using nio4r 2.5.2
remote:        Using websocket-extensions 0.1.5
remote:        Using websocket-driver 0.7.3
remote:        Using actioncable 6.0.3.2
remote:        Using globalid 0.4.2
remote:        Using activejob 6.0.3.2
remote:        Using activemodel 6.0.3.2
remote:        Using activerecord 6.0.3.2
remote:        Using mimemagic 0.3.5
remote:        Using marcel 0.3.3
remote:        Using activestorage 6.0.3.2
remote:        Using mini_mime 1.0.2
remote:        Using mail 2.7.1
remote:        Using actionmailbox 6.0.3.2
remote:        Using actionmailer 6.0.3.2
remote:        Using actiontext 6.0.3.2
remote:        Using activemodel-serializers-xml 1.0.2
remote:        Using activeresource 5.1.1
remote:        Using babel-source 5.8.35
remote:        Using execjs 2.7.0
remote:        Using babel-transpiler 0.7.0
remote:        Using msgpack 1.3.3
remote:        Using bootsnap 1.4.7
remote:        Using browser_sniffer 1.2.2
remote:        Using bundler 2.0.2
remote:        Using connection_pool 2.2.3
remote:        Using multipart-post 2.1.1
remote:        Using faraday 1.0.1
remote:        Using ffi 1.13.1
remote:        Using graphql 1.11.1
remote:        Using graphql-client 0.16.0
remote:        Using hashie 4.1.0
remote:        Using jbuilder 2.10.0
remote:        Using jwt 2.2.1
remote:        Using method_source 1.0.0
remote:        Using multi_json 1.15.0
remote:        Using multi_xml 0.6.0
remote:        Using oauth2 1.4.4
remote:        Using omniauth 1.9.1
remote:        Using omniauth-oauth2 1.5.0
remote:        Using omniauth-shopify-oauth2 2.2.2
remote:        Using pg 1.2.3
remote:        Using puma 4.3.5
remote:        Using rack-proxy 0.6.5
remote:        Using thor 1.0.1
remote:        Using railties 6.0.3.2
remote:        Using sprockets 4.0.2
remote:        Using sprockets-rails 3.2.1
remote:        Using rails 6.0.3.2
remote:        Using tilt 2.0.10
remote:        Using react-rails 2.6.1
remote:        Using redirect_safely 1.0.0
remote:        Using sassc 2.4.0
remote:        Using sassc-rails 2.1.2
remote:        Using sass-rails 6.0.0
remote:        Using shopify_api 9.2.0
remote:        Using shopify_app 13.5.0
remote:        Using turbolinks-source 5.2.0
remote:        Using turbolinks 5.2.1
remote:        Using webpacker 4.2.2
remote:        Bundle complete! 16 Gemfile dependencies, 80 gems now installed.
remote:        Gems in the groups development and test were not installed.
remote:        Bundled gems are installed into `./vendor/bundle`
remote:        Bundle completed (0.48s)
remote:        Cleaning up the bundler cache.
remote: -----> Installing node-v12.16.2-linux-x64
remote: -----> Installing yarn-v1.22.4
remote: -----> Detecting rake tasks
remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        yarn install v1.22.4
remote:        [1/4] Resolving packages...
remote:        [2/4] Fetching packages...
remote:        info fsevents@2.1.3: The platform "linux" is incompatible with this module.
remote:        info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
remote:        info fsevents@1.2.13: The platform "linux" is incompatible with this module.
remote:        info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
remote:        [3/4] Linking dependencies...
remote:        [4/4] Building fresh packages...
remote:        Done in 43.55s.
remote:        yarn install v1.22.4
remote:        [1/4] Resolving packages...
remote:        [2/4] Fetching packages...
remote:        info fsevents@2.1.3: The platform "linux" is incompatible with this module.
remote:        info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
remote:        info fsevents@1.2.13: The platform "linux" is incompatible with this module.
remote:        info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
remote:        [3/4] Linking dependencies...
remote:        [4/4] Building fresh packages...
remote:        Done in 6.16s.
remote:        Compiling...
remote:        Compiled all packs in /tmp/build_286952af/public/packs
remote:        Hash: b613f6533fd866458a0a
remote:        Version: webpack 4.44.1
remote:        Time: 45031ms
remote:        Built at: 07/31/2020 3:35:28 PM
remote:                                                     Asset       Size  Chunks                                Chunk Names
remote:                              css/application-d47ecf57.css    360 KiB       0  [emitted] [immutable]  [big]  application
remote:                           css/application-d47ecf57.css.br   29.7 KiB          [emitted]
remote:                           css/application-d47ecf57.css.gz   39.1 KiB          [emitted]
remote:                    js/application-78c4e8f16792cce6fc1a.js    661 KiB       0  [emitted] [immutable]  [big]  application
remote:        js/application-78c4e8f16792cce6fc1a.js.LICENSE.txt    1.8 KiB          [emitted]
remote:                 js/application-78c4e8f16792cce6fc1a.js.br    148 KiB          [emitted]
remote:                 js/application-78c4e8f16792cce6fc1a.js.gz    181 KiB          [emitted]
remote:                js/application-78c4e8f16792cce6fc1a.js.map   2.11 MiB       0  [emitted] [dev]               application
remote:             js/application-78c4e8f16792cce6fc1a.js.map.br    426 KiB          [emitted]              [big]
remote:             js/application-78c4e8f16792cce6fc1a.js.map.gz    529 KiB          [emitted]              [big]
remote:                                             manifest.json  494 bytes          [emitted]
remote:                                          manifest.json.br  151 bytes          [emitted]
remote:                                          manifest.json.gz  170 bytes          [emitted]
remote:        Entrypoint application [big] = css/application-d47ecf57.css js/application-78c4e8f16792cce6fc1a.js js/application-78c4e8f16792cce6fc1a.js.map
remote:         [57] (webpack)/buildin/module.js 552 bytes {0} [built]
remote:         [94] ./app/javascript/shopify_app/index.js 56 bytes {0} [built]
remote:         [95] ./app/javascript/shopify_app/shopify_app.js 359 bytes {0} [built]
remote:        [104] (webpack)/buildin/global.js 905 bytes {0} [built]
remote:        [228] ./app/javascript/packs/application.js + 51 modules 767 KiB {0} [built]
remote:              | ./app/javascript/packs/application.js 818 bytes [built]
remote:              |     + 51 hidden modules
remote:            + 850 hidden modules
remote:
remote:        WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
remote:        This can impact web performance.
remote:        Assets:
remote:          css/application-d47ecf57.css (360 KiB)
remote:          js/application-78c4e8f16792cce6fc1a.js (661 KiB)
remote:          js/application-78c4e8f16792cce6fc1a.js.map.gz (529 KiB)
remote:          js/application-78c4e8f16792cce6fc1a.js.map.br (426 KiB)
remote:
remote:        WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
remote:        Entrypoints:
remote:          application (1020 KiB)
remote:              css/application-d47ecf57.css
remote:              js/application-78c4e8f16792cce6fc1a.js
remote:
remote:
remote:        WARNING in webpack performance recommendations:
remote:        You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
remote:        For more info visit https://webpack.js.org/guides/code-splitting/
remote:        Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/@shopify/polaris/styles.css:
remote:            Entrypoint mini-css-extract-plugin = *
remote:               2 modules
remote:
remote:        Asset precompilation completed (99.47s)
remote:        Cleaning assets
remote:        Running: rake assets:clean
remote: -----> Detecting rails configuration
remote:
remote: ###### WARNING:
remote:
remote:        You set your `config.active_storage.service` to :local in production.
remote:        If you are uploading files to this app, they will not persist after the app
remote:        is restarted, on one-off dynos, or if the app has multiple dynos.
remote:        Heroku applications have an ephemeral file system. To
remote:        persist uploaded files, please use a service such as S3 and update your Rails
remote:        configuration.
remote:
remote:        For more information can be found in this article:
remote:          https://devcenter.heroku.com/articles/active-storage-on-heroku
remote:
remote:
remote: ###### WARNING:
remote:
remote:        We detected that some binary dependencies required to
remote:        use all the preview features of Active Storage are not
remote:        present on this system.
remote:
remote:        For more information please see:
remote:          https://devcenter.heroku.com/articles/active-storage-on-heroku
remote:
remote:
remote:
remote: -----> Discovering process types
remote:        Procfile declares types     -> web
remote:        Default types for buildpack -> console, rake
remote:
remote: -----> Compressing...
remote:        Done: 90.6M
remote: -----> Launching...
remote:        Released v18
remote:        https://shopify-core-web-vitals.herokuapp.com/ deployed to Heroku
resistorsoftware commented 4 years ago

I am surprised you got that far with Sprockets > 3.7... I always downgrade from 4+ as that was always screwing with webpack and assets. But that is probably neither here nor there. I also saw the same problem too, where my mickey mouse tiny CSS payload from Polaris would trigger that warning about my assets of 20kb exceeding limits --- hahaha...

Wish I knew the secret sauce to get you over that hump. I have > 20 Apps on Rails 6.0.3 plus Polaris working fine at Heroku... but for the life of me, it is always a roll of the dice to produce a perfect package that actually runs as there are 2,456,321 moving parts in JS of which I wrote exactly none.

igrigorik commented 4 years ago

@resistorsoftware ah, joy.. thanks for chiming in.

Can you share more details on your typical downgraded setup? Are you locking sprockets at ~>3.7, or do you also downgrade other dependencies? I tried gem "sprockets", "~> 3.7.0" in my Gemfile, but that didn't seem to yield any benefit.

resistorsoftware commented 4 years ago
sprockets (3.7.2)
  concurrent-ruby (~> 1.0)
    rack (> 1, < 3)
 sprockets-rails (3.2.1)
   actionpack (>= 4.0)
   activesupport (>= 4.0)
   sprockets (>= 3.0.0)

First off. I use rails new to generate an app with Webpacker and in my case, React so that I can deal with Polaris. Once that is done, I use the generators to install Shopify App and establish the basics. At this point, I am where you are, and it all just works.

Things I do different? I blow away the Shopify React codes, and use my own. I get Polaris via a slightly different approach, but nonetheless, the same. I use App Bridge, and all that jazz. I am not sure how I could show you without going through the whole rigamarole of setting up a complete demo.

I do not use React Rails. Not sure that that gem is a good one. Maybe it is... I just never use it.

So you followed that pattern? I am not sure my custom React approach would make a stitch of difference. I never use ERB I still use Haml and for me, I prefer to bring the App to life with a template slightly different than Shopify... it cannot be that makes webpacker assets work or not. Has to be Sprockets or something.

igrigorik commented 4 years ago

Aha, thank you sir. Your point about react-rails and webpacker config tipped me in the right direction: resolved in https://github.com/igrigorik/shopify-core-web-vitals/commit/27910d51a5c54b79d95fb09f19873aa9efb13cb5.

FWIW, I flipped back to latest sprockets and, so far at least, things seem to be working a-ok. To your point though, I'm not exercising much of react-rails machinery, so that's probably more a liability than a feature. But for now, it works.

resistorsoftware commented 4 years ago

Super!

I suppose I keep sprockets down and out as I never use it, and it was causing errors at v4 with asset calls. Like Turbolinks. Some things in Rails seem only fit for DHH and his Apps, or for really advanced and complex Apps. My use cases for Shopify Apps never seemingly need much more than a basic API on my end to hit my DB and return some JSON, along with the standard XHR + CSS we all know and love since 1998 or so... so I am getting better at removing more Rails than keeping it. Unfortunately, webpack, yarn and node now more than make for headaches with their endless versions of minuscule LOC chained together to make the creaky JS web go.