jwhitley/requirejs-rails

Precompilation fails with "module path does not exist" after upgrading to 0.9.5

Closed this issue · 4 comments

agis commented

Hello.

I'm on a Rails 3.2.22 application and using requirejs-rails 0.9.0 for a long time everything is fine. However, after upgrading to 0.9.5, I get the following error while deploying:

#...
rake aborted!
Asset compilation with node failed with error:

{ [Error: Error: ERROR: module path does not exist: /home/staging/tmp/assets/rjs/application_desktop.js for module named: application_desktop. Path is relative to: /home/staging
    at /home/bundles/staging/ruby/1.9.1/gems/requirejs-rails-0.9.8/bin/r.js:27089:35
]
  originalError: [Error: ERROR: module path does not exist: /home/staging/tmp/assets/rjs/application_desktop.js for module named: application_desktop. Path is relative to: /home/staging] }

/home/bundles/staging/ruby/1.9.1/gems/requirejs-rails-0.9.8/lib/tasks/requirejs-rails_tasks.rake:141:in `block (3 levels) in <top (required)>'
Tasks: TOP => requirejs:precompile:all => requirejs:precompile:run_rjs
(See full trace by running task with --trace)
rake aborted!
Command failed with status (1): [/usr/bin/ruby1.9.1 /home/bundles...]
/home/bundles/staging/ruby/1.9.1/gems/requirejs-rails-0.9.8/lib/tasks/requirejs-rails_tasks.rake:18:in `ruby_rake_task'
/home/bundles/staging/ruby/1.9.1/gems/requirejs-rails-0.9.8/lib/tasks/requirejs-rails_tasks.rake:85:in `block (3 levels) in <top (required)>'
Tasks: TOP => assets:precompile => requirejs:precompile:external
(See full trace by running task with --trace)

Here are the relevant parts from requirejs.yml:

# config/requirejs.yml

locale : 'en'
optimize : 'none'
paths:
  jquery.datepicker:  'vendor/jquery/plugins/jquery.datepicker'
  jquery.jcrop:       'vendor/jquery/plugins/jquery.jcrop'
modules :
  - name: 'application_desktop'

  - name: 'application_tablet'

  - name: 'application_mobile'

The file in question is located at app/assets/javascripts/rjs/application_desktop.js.coffee.

Note that I also have the following initializer:

# config/initializers/requirejs_path_override.rb

# Override the baseUrl value used in the build_config parameter to
# locate the temporary folder where compiled scripts put (from coffeescript compiler)
# This workaround is only needed for usage with r.js driver of requirejs-rails gem
if ENV['RAILS_GROUPS'] == "assets"
  requirejs = Rails.application.config.requirejs
  requirejs.build_config['baseUrl'] = "#{Rails.root}/tmp/assets/rjs"
end

Note that compilation is fine with 0.9.0, 0.9.1 and 0.9.2. Also, it fails with the same error in 0.9.8.

Thanks.

agis commented

This is most probably a path issue but I'm not yet sure why it happens.

After some further investigation, I've found that in 0.9.2 (a working version that successfully compiles the assets), the temporary rjs_driver.js file (my_app/tmp/rjs_driver.js) has an extra snippet regarding baseConfig and also contain the proper paths for each of the modules in question (application_desktop etc.):

// generated rjs_driver.js file using 0.9.2
// ...

// Function used to mix in baseConfig to a new config target
function mix(target) {
  for (var prop in baseConfig) {
    if (baseConfig.hasOwnProperty(prop)) {
      target[prop] = baseConfig[prop];
    }
  }
  return target;
}

var module_specs = [
{
  "name": "application_desktop",
  "out": "/home/staging/public/assets/application_desktop.js" // <-- CORRECT
},
{
  "name": "application_tablet",
  "out": "/home/staging/public/assets/application_tablet.js"
},
{
  "name": "application_mobile",
  "out": "/home/staging/public/assets/application_mobile.js"
},

Now, compare this with the generated file when using 0.9.5, a version that causes the asset compilation to fail (notice the comments I've added):

// generated rjs_driver.js file using 0.9.5
// ...

// NOTICE! The mix() function doesn't exist anymore!

// NOTICE! The paths are missing!
baseConfig.modules = [
  {
  "name": "application_desktop" // <-- OOPS! Output path (`out`) is missing
},
  {
  "name": "application_tablet"
},
  {
  "name": "application_mobile"
},

Not sure if the output paths are an issue, but I think the baseUrl not being taken into account in 0.9.5 is the culprit.

agis commented

Apparently, after 8785162#diff-d678a8a60f5428d7f354e0856743c206R20 the source path has changed, so I've also had to update the initializer to reflect the new default path.

@agis- Nice find! Why were you depending on the source staging path anyways?

agis commented

@carsomyr I guess because scripts that use requirejs are placed in app/assets/javascripts/rjs/ and without that initializer the source_dir is incorrectly set to /home/staging/tmp/assets (it should really be home/staging/tmp/assets/rjs) so asset compilation fails.

Not sure if that makes sense to you.