Files with extension .module.js not being wrapped in require.define() #4

Closed
malandrew opened this Issue May 30, 2012 · 28 comments

Projects

None yet

4 participants

@malandrew

I'm trying to implement sprockets-commonjs in our project, but no file with the module.js extension is being wrapped in require.define() statements. From my understanding sprockets works from the leftmost (innermost) file extension outwards when determining how to process each. This means it should see the .module. extension, wrap it in require.define() and then move on to the .js extension to then process it. Does anyone know why sprockets isn't picking up on the .module. extension. I know the file is being included via sprockets directions.

My sprockets version is 2.1.2 and I've tried both the sprockets-commonjs gem via ruby gems.org and via master on github. How should I go about trouble shooting this?

@maccman
Owner
maccman commented May 30, 2012

Are you using Rails?

@malandrew

Yes. v 3.2.1

@jpadvo
jpadvo commented May 30, 2012

I'm having the same issue, Rails 3.2.3 and 3.2.2.

In the console, Sprockets.engines lists a number of engines, but none of them are the CommonJS engine. I can manually add it (in the rails console) with these commands:

require 'sprockets/commonjs'
Sprockets.register_engine 'applicaiton/javascript', Sprockets::CommonJS

It is behaving as though the gem is not automatically loaded, despite being in the Gemfile. I've tried putting the gem in the :assets group, the :assets, :development group, and simply in the root level of the Gemfile.

By the way, my company is going to refactor our code to use Spine, CommonJS, and Stylus, thanks to seeing how beautifully that stack works in Stylo. :)

@maccman
Owner
maccman commented May 30, 2012

Hmm interesting. It's actually a post processor, not an engine.

Can you check to see if the post processor is there?

@jpadvo
jpadvo commented May 30, 2012

I can't figure out how, I've been digging through the Sprockets documentation for the last half hour unsuccessfully. Is there a simple method call or something I'm not seeing?

@jpadvo
jpadvo commented May 30, 2012

Okay, figured out how to check. Doesn't look like it's registered (checking from the rails console):

rails c
> Rails.application.assets.postprocessors
=> {"application/javascript"=>[Sprockets::SafetyColons]} 

I manually require CommonJS, and still nothing:

> require 'sprockets/commonjs'
=> true
> Rails.application.assets.postprocessors
 => {"application/javascript"=>[Sprockets::SafetyColons]} 
@jpadvo
jpadvo commented May 30, 2012

I got the postprocessor to register by adding an initializer:

# config/initializers/sprockets_commonjs.rb
require 'sprockets/commonjs'
Rails.application.assets.register_postprocessor 'application/javascript', Sprockets::CommonJS

Now it processes .module.js files, but throws an error when trying to require sprockets/commonjs.js:

Sprockets::FileNotFound

couldn't find file 'sprockets/commonjs'
  (in [...]/filename.module.js)

It's like Rails refuses to acknowledge this entry in the Gemfile...

@maccman
Owner
maccman commented May 30, 2012

@jpadvo which version of sprockets-commonjs are you using?

@jpadvo
jpadvo commented May 30, 2012

Same error occurs with version 0.0.4 and with the latest commit on master direct from Github:

gem 'sprockets-commonjs', :git => 'https://github.com/maccman/sprockets-commonjs.git', :ref => '859b9fe18d'

Edit: I also tried 0.0.5pre, but that requires Sprockets 2.4.0, and that don't work with Rails 3.2.3.

@maccman
Owner
maccman commented May 31, 2012

Looks like the engine is not being initialized. That's weird. It works for me with a new blank app - what about you?

@jpadvo
jpadvo commented May 31, 2012

It doesn't. I put said bare app here so you can try it: https://github.com/jpadvo/example-sprockets-commonjs

I made a scaffolded "posts" resource, and changed it's javascript file to a .module.js file and it isn't processed.

@maccman
Owner
maccman commented May 31, 2012

Weird - if I request http://localhost:3000/assets/posts.module.js I get the CommonJS compiled file. I used bundle install. Hmm, rather baffled :(

@jpadvo
jpadvo commented May 31, 2012

Haha, bizarre. I'll try a fresh rvm gemset, maybe I've got a corrupted gem somewheres. And maybe it's an issue with ruby, I'm using ruby 1.9.2p290. What're you running?

@malandrew

@jpadvo is there a simple bundler command to try refreshing the entire gem set of a project? If so, I'll try that on my end as well. I'm running ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]

@maccman
Owner
maccman commented May 31, 2012

Ah - success, I've cleared my gemset and replicated the problem. I shall investigate further.

@jpadvo
jpadvo commented May 31, 2012

@maccman Godspeed!

@malandrew If you've got rvm, you can do this:

rvm gemset create sprockets-commonjs-test
rvm gemset use sprockets-commonjs-test
gem install bundle
bundle install

When you're done, you can switch back to your other gemset by running rvm gemset list to see all available ones, then rvm gemset use [name] to select the right one.

@maccman
Owner
maccman commented May 31, 2012

@josh Any clues on where to look?

@malandrew

@jpadvo I got that example app to work on my machine, but @maccman just FYI it's outputting some extra semi-colons in the code. I'm not sure if this is a feature or a bug since the semi-colons may be there to prevent a bug.

this:

module.exports = {does_it_work: "Yes, yes it does"}

becomes this:

this.require.define({
    "posts": function(exports, require, module) {
        module.exports = {
            does_it_work: "Yes, yes it does"
        }
        ;
        ;
    }
});
@josh
josh commented May 31, 2012

try rm -rf tmp/cache in your rails repo

@jpadvo
jpadvo commented May 31, 2012

The extra semicolons may be coming from Sprockets::SafetyColons, a postprocessor in the Sprockets core.

> Rails.application.assets.postprocessors
 => {"application/javascript"=>[Sprockets::SafetyColons]} 
@jpadvo
jpadvo commented May 31, 2012

Got it fully working after (1) creating a new, fresh gemset and (2) clearing tmp/cache as @josh suggested. Thank you so much @josh and @maccman, and let me know if I can do anything to help.

@malandrew

@jpadvo Were both a new gem set and clearing tmp/cache required or is only one or the other required to fix this issue?

@jpadvo
jpadvo commented May 31, 2012

@malandrew: short answer, I think both. Just clearing the cache on a stale gemset didn't fix it.

Here's a clean description of my setup, what goes wrong, and how it got fixed. (This is using ruby 1.9.2p290 on OS X Lion.)

  1. Set up the environment
rvm create gemset [gemset-name]
rvm use gemset [gemset-name]
gem install bundle rails
  1. Generate a new rails app and a resource
rails new sprockets-commonjs-example
cd sprockets-commonjs-example
rails g scaffold posts title:string body:text
  1. Create a module file. I changed app/assets/posts.js.coffee to app/assets/posts.module.js, and added some javascript.
  2. Start rails and access http://localhost:3000/assets/posts.module.js, confirm it is unprocessed except an extra semicolon.
  3. Add gem 'sprockets-commonjs', '0.0.4' to Gemfile, run bundle, restart rails server.
  4. Access http://localhost:3000/assets/posts.module.js and confirm it is still unprocessed.
  5. Kill rails server, clear the cache (rm -rf tmp/cache), restart rails.
  6. http://localhost:3000/assets/posts.module.js is now properly wrapped.
@maccman
Owner
maccman commented May 31, 2012

Awesome stuff!

@maccman maccman closed this May 31, 2012
@malandrew

@jpadvo thanks. I will try that later tonight.

@maccman Saw that you closed this issue. Will you be updating the repo to prevent this edge case in case others come across it? Or have you already done so?

@maccman
Owner
maccman commented May 31, 2012

Not much I can do - caching issue. I'll update the README though.

@malandrew

I think this pull request should fix this issue:

#5

@malandrew

We also figured out that you need to be using bundler v1.1 or better and that this gem will not install properly with bundler 1.0. This means that if you have bundler installed globally instead of locally, you may still end up not getting the fresh gemset trick above to work properly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment