简体   繁体   中英

RequireJs + Rails 4

I'm new to RequireJs, so i little bit stuck with getting my rails 4 app working on production with requirejs pieces.

I have the following:

1) Require_rails gem

gem 'requirejs-rails'

2) Piece of require-js called in a middle of a html.erb file

<%= requirejs_include_tag asset_url("scribe/scribe-editor.js") %>

3) In this a file I have following

require({
  paths: {
    'scribe': 'scribe/bower_components/scribe/scribe',
    'scribe-plugin-blockquote-command': 'scribe/bower_components/scribe-plugin-blockquote-command/scribe-plugin-blockquote-command',
    'scribe-plugin-code-command': 'scribe/bower_components/scribe-plugin-code-command/scribe-plugin-code-command'
  }
}, [
  'scribe',
  'scribe-plugin-blockquote-command',
  'scribe-plugin-code-command',
], function (
  Scribe,
  scribePluginBlockquoteCommand,
  scribePluginCodeCommand,
) {
...
});

4) All these files located in vendor/javascripts/scribe

vendor/javascripts/scribe/scribe-editor.js
vendor/javascripts/scribe/bower_components/scribe/scribe.js
vendor/javascripts/scribe/bower_components/scribe/scribe/scribe-plugin-blockquote-command/scribe-plugin-blockquote-command.js
vendor/javascripts/scribe/bower_components/scribe/scribe-plugin-code-command/scribe-plugin-code-command.js

5) On production I have the following code.

<script src="/assets/require-21be67676bcf2b75c547dd382d849e26.js"></script>
<script>require.config({"baseUrl":"http://domain.com/assets","paths":{"application":"/assets/application-e720d39c2f6b94f1fd554d97b48ee312"}}); require(["http://domain.com/assets/scribe/scribe-editor-a848a8a552e89e8a8f6e9a62d10cd58f.js"]);</script>

6) And finally, my asset.rb file:

Rails.application.config.assets.precompile += %w( 
    scribe/scribe-editor.js
)

============= 7) The problem: script editor is loaded, but all dependencies come with 404 not found.

Thanks for your help.

I have not used requirejs-rails with Rails 4 yet, just rails 3.2 but I think it works mostly the same.

I think the reason you are getting those 404's for the dependencies is because r.js never ran on scribe/scribe-editor instead it ran on application.js which is why you see /assets/application-e720d39c2f6b94f1fd554d97b48ee312 referenced in your production code.

First problem I see is that you are using config.assets.precompile . Based on the Troubleshooting section in requirejs-rails Readme you should not include requirejs modules in config.assets.precompile since that will make rails try precompile it using sprockets. You want r.js to optimize any requirejs modules. Requirejs-rails will run r.js for you during the precompile step. In my project I use config.assets.precompile to compile css, an Javascript that is not a requirejs module. For instance application.js is not a requirejs module in my case (and apperently also in your case).

You don't mention whether you have a requirejs.yml file in your project. If not I suggest you add one and move your requirejs config there instead of adding it to the head of the scribe-editor.js module.

requrejs.yml:

modules:
   - name: scribe/scribe-editor
paths:
   scribe: scribe/bower_components/scribe/scribe
   scribe-plugin-blockquote-command: scribe/bower_components/scribe-plugin-blockquote-command/scribe-plugin-blockquote-command
   scribe-plugin-code-command: scribe/bower_components/scribe-plugin-code-command/scribe-plugin-code-command

RequireJS-Rails will use the modules config as part of the r.js build config to indicate what files need to be run through r.js.

RequireJS-Rails will convert the paths into Javascript and add it as a <script> tag before the require.js script tag (excluding the modules stuff) as the requirejs.config. Anything that can be in a requirejs config can be added to requirejs.yml

You can then change your scribe-editor module definition to something like:

define(['scribe', 'scribe-plugin-blockquote-command', 'scribe-plugin-code-command'], 
       function( Scribe, scribePluginBlockquoteCommand, scribePluginCodeCommand) {
...
});

Lastly I don't think you want the asset_url() call in requirejs_include_tag , you need to reference the requirejs module. Something like <%= requirejs_include_tag('scribe/scribe-editor') %> should work.

You should end up with 2 script tags added to your response in production as a result of the requirejs_include_tag . If I am guessing right it should look a lot like this(the SHA's I just made up):

<script>var require = {"baseUrl":"/assets","paths":{"scribe/scribe-editor":"/assets/scribe/scribe-editor-c48f6b842cf0f40976393a1d2f4568e0"}};</script>
<script data-main="scribe/scribe-editor-c48f6b842cf0f40976393a1d2f4568e0" src="/assets/require-cbfc3f690e2109e37e09aefd8fe40332.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM