3

I have struggled a few days to figure this out,, but finally I need your help today.
my repo: https://github.com/seoyoochan/bitsnut-web


what I want to achieve:
- Load and optimize r.js - Write bower tasks for RequireJS and r.js :
   tasks are: minify & uglify & concatenation for RequireJS, and optimise with r.js on production
- How to exclude js script tags in index.html when using wiredep tasks and load them through RequireJS loader?


I use Yeoman 'Webapp' generator and generated the scaffold app.

I installed backbone, marionette, text, underscore, and etc via bower install I modified bower.json by removing dependencies and left only "requirejs": "~2.1.16" on dependencies. (devDependencies is empty)

because I use [2][grunt-wiredep], everything is automatically loaded bower_components into index.html. I modified .bowerrc to store dependencies at app/scripts/vendor.

However, the problem is that I don't know how to successfully load them through ReuqireJS and not to load the vendors as script tags inside index.html. I have to write some tasks for RequireJS and r.js, but don't know how to achieve this goal ( I installed grunt-contrib-requirejs though )

I want to follow the 4th method to make use of r.js at https://github.com/jrburke/requirejs/wiki/Patterns-for-separating-config-from-the-main-module. but the issue I encountered was that RequireJS's documentation does suggest to not use named module, but anonymous module. I would like to hear various opinions about how I should approach.

I really appreciate your help in advance!

seoyoochan
  • 822
  • 3
  • 14
  • 28
  • @PeteTNT I know I don't want it to be included in the index.html, but they were included automatically by 'wiredep'. How could I solve it? And also, are both main.js and config.js correct? – seoyoochan Mar 28 '15 at 13:26

1 Answers1

8

You load your scripts manually here and here, rendering the whole point of requireJS useless. You also load main first here config.js#L49.

Instead, you should only have this line in your index.html

<script data-main="scripts/config" src="scripts/vendor/requirejs/require.js"></script>

And load all your dependencies in that file (like you do with main) using define() and require(). As you have set exports, which sets the values as globals, the functions can be empty. Here's an sample:

define([
    "jquery",
    "underscore", 
    "backbone",
    "marionette",         
    "modernizr"
], function () {
        require([
        "backbone.babysitter", 
        "backbone.wreqr", 
        "text", 
        "semantic"
    ], function () {
        /* plugins ready */
    });

    define(["main"], function (App) {
           App.start();
    });
});

Also the baseUrl is the same as the directory as your data-main attributes folder (http://requirejs.org/docs/api.html#jsfiles):

RequireJS loads all code relative to a baseUrl. The baseUrl is normally set to the same directory as the script used in a data-main attribute for the top level script to load for a page. The data-main attribute is a special attribute that require.js will check to start script loading.

So I think your baseUrl in config.js points to scripts/scripts/-folder which doesn't exist. It could/should be vendor/ instead (and remove the vendor part from all of the declarations) or just left empty.

Instead of wiredep, you could try using https://github.com/yeoman/grunt-bower-requirejs which does similar things to wiredep but specially for bower/requirejs apps (see: https://github.com/stephenplusplus/grunt-wiredep/issues/7)

Your repo doens't include the dist-folder for jQuery, but otherwise here's a working sample of config.js: http://jsfiddle.net/petetnt/z6Levh6r/

As for the module-definition, it should be

require(["dependency1", "dependency2"])

and the module should return itself. Currently your main file sets itself as a dependency

require(["main", "backbone", "marionette"], function(App, Backbone, Marionette){

As you already set the backbone and marionette as globals with exports, you can again set the function attributes empty, so your main file should look like this:

require(["backbone", "marionette"], function(){
  "use strict";
  var App = new Backbone.Marionette.Application();

  App.addInitializer(function(){
    console.log("hello world!");
    Backbone.history.start();
  });

  return App;
});

And as you already use define to load main, don't require it again. Instead just call App.start() inside the define function.

https://jsfiddle.net/66brptd2/ (config.js)

Pete TNT
  • 8,293
  • 4
  • 36
  • 45
  • I really appreciate your detailed answer! but I have still a few problems when loading files with requireJS. if you `grunt serve` my app from the repo, the console complains a lot of stuff .. and how can I let `config.js` refer to `main.js` ? or let `main.js` refer to `config.js`? I thought I could just say `require` the defined module file set by `define() method`, am I wrong? – seoyoochan Mar 28 '15 at 14:29
  • @seoyoochan, I pulled your updated repo and modified the `config.js` file a bit: see the end of the page for a fiddle. The repo didn't contain the /dist/-folder for `jquery` though. I didn't notice that you (correctly) set the exports, so you can / should leave the define and ready-functions attributes empty. – Pete TNT Mar 28 '15 at 16:10
  • Thanks! It almost works now, but when I require ["main"] inside `config.js`. it returns `undefined`. look at this http://s18.postimg.org/6dcw0l57t/Screen_Shot_2015_03_29_at_1_25_46_AM.png and I updated the repo – seoyoochan Mar 28 '15 at 16:26
  • See my edit again, it fixes some issues with the Main. – Pete TNT Mar 28 '15 at 16:54
  • Aaand some racing conditions. I think it still could be improved a bit but it finally works :) – Pete TNT Mar 28 '15 at 17:12
  • I don't know why my server keeps saying `'define' is not defined.` because define was not defined successfully, `var App = new Backbone.Marionette.Application();` does not work either and spits out error on console. :/ (updated repo) – seoyoochan Mar 29 '15 at 00:33
  • Check your Network-tab. It might be that your servers `baseUrl` is different than the one locally! – Pete TNT Mar 29 '15 at 08:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74031/discussion-between-seoyoochan-and-pete-tnt). – seoyoochan Mar 29 '15 at 13:12
  • I will enter that chat. – seoyoochan Mar 29 '15 at 13:13