Webpacker: Compile as part of `rails assets:precompile`.

Created on 29 Dec 2016  Â·  15Comments  Â·  Source: rails/webpacker

We were using ReactOnRails before trying Webpacker. In order to get Heroku to compile the assets I had to add the following rake task.

Rake::Task['assets:precompile']
  .clear_prerequisites
  .enhance(['assets:compile_environment'])

namespace :assets do
  # In this task, set prerequisites for the assets:precompile task
  task compile_environment: :webpack do
    Rake::Task['assets:environment'].invoke
  end

  desc 'Compile assets with webpack'
  task :webpack do
    sh 'bundle exec rails webpacker:compile'
  end
end

Anyway we can make this part of webpacker?

Most helpful comment

We are working on adding yarn to the buildpack for Rails right now on Heroku, so it won't work yet because we don't have the binaries in place.

All 15 comments

Yes, we should definitely make compilation part of the default package for
assets:precompile.

On Thu, Dec 29, 2016 at 7:23 AM, Christopher Garvis <
[email protected]> wrote:

We were using ReactOnRails before trying Webpacker. In order to get Heroku
to compile the assets I had to add the following rake task.

Rake::Task['assets:precompile']
.clear_prerequisites
.enhance(['assets:compile_environment'])

namespace :assets do
# In this task, set prerequisites for the assets:precompile task
task compile_environment: :webpack do
Rake::Task['assets:environment'].invoke
end

desc 'Compile assets with webpack'
task :webpack do
sh 'bundle exec rails webpacker:compile'
endend

Anyway we can make this part of webpacker?

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/rails/webpacker/issues/45, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAKtZU9viMhlXLRuFplMZYBkx4HOvMzks5rM9B2gaJpZM4LXpoe
.

@cgarvis Did you also edit the heroku-ruby-buildpack to install node and yarn ? Or are you using some other solution.

I am using webpacker + react
I had to fork the heroku-ruby-buildpack and add code to do the following:

  • Install node.
  • Install yarn.
  • Install node packages using yarn.
  • run the webpacker:compile

If the package.json and yarn.lock files were in the root folder(instead of vendor) I could have just used the https://github.com/heroku/heroku-buildpack-nodejs#yarn which would have installed the packages for me and then added the code you have posted above in my codebase.

Thanks in advance for you help!

@puneet-sutar I have multiple build packs heroku/ruby and heroku/nodejs. I have a fake package.json and yarn.lock file at the root level.

@cgarvis Are your fake package.json and yarn.lock at root level exact copies of those in vendor?

No.

package.json

{}

yarn.lock

# trick heroku into installing yarn

Thanks @cgarvis.

I tried that approach, but got this error:

    remote: -----> Preparing app for Rails asset pipeline
    remote:        Running: rake assets:precompile
    remote:        bundle exec rails webpacker:compile
    remote:        sh: 1: ./node_modules/webpack/bin/webpack.js: not found
    remote:        rails aborted!

I'm guessing this is because yarn never ran in the vendor folder, so vendor/node_modules was empty when webpacker:compile was called.

The following worked for me:

In root Rails app folder:

package.json

{
  "name": "app-name-here",
  "description": "dummy package.json for heroku/nodejs buildpack support",
  "private": true,
  "engines": {
    "node": "6.5.0",
    "yarn": "0.18.1"
  },
  "scripts": {
    "heroku-postbuild": "cd vendor && yarn"
  }
}

yarn.lock

# Dummy yarn.lock to force heroku/nodejs to install yarn

Then add the nodejs buildpack first, before ruby buildpack:

$ heroku buildpacks:add --index 1 heroku/nodejs

Deploy

$ git push heroku master

Caveats:

  • This creates an extra unused node_modules folder in Rails root when the Heroku nodejs buildpack runs the dummy install.
  • Heroku was confused when I added the nodejs buildpack to an existing Heroku app. Had to add/re-add ruby buildpack. Possibly a fluke with my config. https://devcenter.heroku.com/articles/buildpacks#detection-failure

@cgarvis @audionerd Nice tricks.

I had tried the fake package.json + yarn.lock + patching rake task to run bin/yarn install and web:compile approach works nicely.

I have also forked the heroku-ruby-buildpack and using it in my project now. If you want to give it a shot https://github.com/puneet-sutar/heroku-buildpack-ruby. Trying to get it merged(https://github.com/heroku/heroku-buildpack-ruby/pull/521).

With this you just need 1 buildpack and don't need an fake files or patching tasks. It will do the following:

  1. Detect presence of vendor/yarn.lock and vendor/package.json
  2. If above files are present the download and install appropriate version of yarn an package.json(you can specify version as engines in package.json).
  3. Install node_modules bin/yarn install
  4. Run rake webpacker:compile

Ah, I see – definitely makes more sense to run yarn via that rake task vs in heroku-postbuild. Like this example:
https://github.com/gauravtiwari/rails-webpacker/blob/master/lib/tasks/assets.rake

That patch looks great. It would be so nice to have yarn installed by the Heroku ruby buildpack.
Not sure if it should be responsible for calling webpacker:compile though, if it's easy enough to hook that into the existing assets:precompile.

@audionerd Just did not want to patch my rails App. Can always remove the webpacker:compile once webpacker adds it to assets:precompile.

Not sure if this still helps, but for getting it running on Heroku, I did following:

  • Set Buildpacks heroku/nodejs & heroku/ruby
  • Create a fake yarn.lock ( Thanks for the tip @cgarvis )
  • Extend the Rakefile with:
Rake::Task['assets:precompile'].enhance do
  system('bundle exec ./bin/yarn')
  system('bundle exec rails webpacker:compile')
end

as I locally run the Rails app through foreman or in a Docker container I don't use the Rakefile elsewhere.
Will not be necessary anymore if both steps wander into the assets precompile step anyway :)

Seems that yarn bug is fixed in master version.
I'm think different now, because i won't recompile packs from the outside of the current engine, so i decide to precompile it & and release within public/dist folder. So any app that uses current engine can pick it up without dependencies 💩.

We are working on adding yarn to the buildpack for Rails right now on Heroku, so it won't work yet because we don't have the binaries in place.

Admitting you already have the npm modules installed, how one could still use assets:precompile with the ability to remove the yarn command ? Just keep the effective build (the rails one and the webpack(er) one)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ytbryan picture ytbryan  Â·  3Comments

naps62 picture naps62  Â·  3Comments

Eearslya picture Eearslya  Â·  3Comments

iChip picture iChip  Â·  3Comments

johan-smits picture johan-smits  Â·  3Comments