Rails: Precompiled Assets Missing Node Modules

Rails: Precompiled assets missing node modules

I have finally found the problem. It is a very nasty bug of the sass-rails gem & an unfortunate design of the sprockets component of Rails.

1) sass-rails

@import does not seem to work with node_modules as it does with other assets. While those other assets get compiled into one file, node_modules only get referenced, loaded by the browser as separate sources, but ultimately not being used by the browser.

2) sprockets

Sprockets' require statement does only work if it is at the beginning of a file. Or as they put it in their documentation:

Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.

However, in my case, I was importing directives from a file that itself was imported from application.sass.

Add node_modules to the rails asset paths causes an asset compilation error

OK, so it turns out that sprockets will hungrily process any JS it finds in a directory named application!

I found this by changing my uglifier to handle ES6 syntax:

config.assets.js_compressor = Uglifier.new(harmony: true)

And then discovered that the assets compile had produced another JS file:

./public/assets//@schematics/angular/application/index-7cb879a643459c580f46b4127272b2918753e9941c074dcf27faea589ca610de.js
./public/assets//application-f78f0f583e152fa235ca51f99bab70d1aeb59675de57c78bcef18b5a2e8a5a5f.js

The file is coming from here:

$ find ./node_modules/ | grep -E "application/.*.js$"
./node_modules//@schematics/angular/application/index.js
./node_modules//@schematics/angular/application/files/karma.conf.js
./node_modules//@schematics/angular/application/files/protractor.conf.js

Heroku and Precompiled Assets

Compile assets locally

To solve this chicken and egg problem with the database in deploy, do not invoke precompile in production, precompile on development machine for production prior to push. With a functional code base pushed, you can run "$heroku db:xxx" commands on Heroku.

  1. Turn off precompile assets in production.rb:
config.assets.compile = false

  1. Precompile assets for production on development machine:
$bundle exec rake assets:precompile RAILS_ENV=production

  1. Now your code glob will include your precompiled assets, so push it.
$heroku push

On deploy to Heroku, you're looking for this line:

    -----> Preparing Rails asset pipeline
Detected manifest.yml, assuming assets were compiled locally

  1. At this point you can create your production database on Heroku
$heroku db:migrate

I think these steps will solve your problem. Please let me know.

Caveat

Once you disable precompile, you will have to remember to always precompile for production on your dev system prior to deploy to production.

Javascript compilation into asset pipeline

Since you're specifically speaking of js precompile, And I haven't tried this, but it seems these types of precompile js-specific lines should also be commented out in production.rb if you have them. There are the same type of js directives in assets. rb, again I don't know if these need to be cleared or not. (The main point is to do a local asset precompile, before the push to Heroku.)

  # Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# config.assets.precompile += %w( xxxx.js )

Heroku docs

https://devcenter.heroku.com/articles/rails-asset-pipeline#compiling-assets-locally

Rails precompile assets Yarn executable was not detected

Rails 5.1 comes with SUPPORT for yarn and webpack, but you need to install them yourself.
Yarn is a package manager and webpack is a package.

Follow instruction at https://yarnpkg.com/lang/en/docs/install/ to install Yarn in your system and then add webpack to your project like:

yarn add --dev webpack webpack-dev-server

Additionally, the message you're seeing is warning, rather than straight up error. If you do not need to use any of the fancy js packages, you can just use good ol' asset pipeline



Related Topics



Leave a reply



Submit