include javascript files in marionette project - javascript

I have a marionette project, and I have my main js file which looks like:
define(["marionette", "handlebars"], function(Marionette, Handlebars){
...
});
Now I want to make a structure of my big app. So I would like to separate the content of this function to different files. So how can I do something like:
define(["marionette", "handlebars"], function(Marionette, Handlebars){
include routes.js
include menu/model.js
include menu/views.js
...
});
I think require.js can help me, but I don't know how. Any ideas?

To require a file in the AMD structure (like the one you describe), you can give the path to the file in the array and get the exported value as argument of the callback like this.
define(
[
"marionette",
"handlebars",
"routes",
"menu/model",
"menu/views"
],
function(Marionette, Handlebars, Routes, Model, MenuView){
// ...
});
Since this is a very basic thing in AMD, you should really read the documentation of Require.JS (here) and explanation about AMD modules (like this one). You will find lot of information about the AMD structure, etc

If you prefer, browserify lets you to load front-end javascript modules using the require syntax. It looks like this.
// library includes
var Marionette = require('backbone.marionette');
var handlebars = require('handlebars');
// custom includes
var routes = require('./routes.js');
var models = require('./menu/models.js');
var views = require('./menu/views.js');
var App = new Marionette.Application();
It includes modules recursively and there is less code. It implements the Common.js format so it looks and feels the same as node.js.

Related

NodeJS - how can I make my code beautiful / cleaner / better readable

I have generated my app with express --view=pug myapp which created me a folder-tree with the files I need to start over.. I wrote some code which I would like to outsource from the main app.js in maybe a function-file or something like that, to keep the app.js cleaner.
where would I put my custom functions? how would I then require the function-file in nodeJS ?
You can arrange your files as you wish. Wherever you keep your functions, just add the functions you want to use in any other files to module.exports object in that file. Then in your app.js (or any other file where you want to use these functions), import the file using require and you should have access to all the exported properties and functions from the file you import.
For example:
I can put my functions in ./lib/core-lib.js:
function test(){
// do something
}
module.exports = {
test: test
};
And then in my app.js
const lib = require('./lib/core-lib');
lib.test();

How to precompile gulp-handlebars helpers?

I am precompiling my templates into JS using gulp-handlebars but I am having trouble getting custom handlebars helpers to also precompile. Does anyone know if there is any support/way to precompile custom helper methods?
I noticed that gulp-handlebars can use a specific handlebars library, essentially overriding its default. So, by just creating my own module and registering some helpers, and feeding that into the handlebars call, things are working locally.
// helpers.js
var handlebars = require('handlebars');
handlebars.registerHelper('upper', function(str){
return str.toUpperCase();
});
module.exports = handlebars;
And then in the gulpfile (something like this):
var handlebars = require('./src/js/helpers.js');
gulp.task('handlebars', function(){
gulp.src('src/html/*.html')
.pipe(gulp_handlebars({handlebars: handlebars})) // override library here
});
If you're using Browserify and optionally watchify and need the output to be a commonjs style module, gulp-defineModule will use a require('Handlebars') in the compiled template file.
This negates any registered helpers that you had passed into gulp-handlebars custom library option (see above). Here is an example of the output file we don't want:
// template.js
var Handlebars = require("handlebars");
module.exports = Handlebars.template({"compiler":[7,">= 4.0.0"]...
1: To fix this, create a helpers.js file that requires the handlebars library, adds the helpers, and then exports the library. Use gulp-defineModule's require option to pass in the handlebars library with the helpers like so:
.pipe(defineModule('node', {
require: {
Handlebars: '../helpers'
}
})
)
this will produce:
// template.js
var Handlebars = require("../helpers");
module.exports = Handlebars.template({...
Note that the relative path will be from the outputfile, and be careful on prod where filepaths may change.
2: Another way is to use gulp-wrap to define the module exactly how you want it. Something like:
.pipe(wrap('module.exports = function(Handlebars) {return Handlebars.template(<%= contents %>) }'))
then in main-js:
var Handlebars = require('./helpers');
var template = require('./template)(Handlebars);

Adding a implicit dependency in an AMD file

How do I add implicit requires to a set of AMD files?
I'm porting some code from a bower-managed app to a play, webjars app. The original app has several places that use jquery ($), but do not declare jquery in the define block. How does this happen? How can I do it in my new app?
The code I'm porting looks like:
define(['underscore',
'backbone',
'text!./html/my-view.html'],
function(_,
mvc,
myView) {
'use strict';
...
return {
render: function() {
var el = this.el;
$(el).html(myView);
...
Require js is probably loading Jquery before you define this module.
Backbone.Views has a dependency on Jquery, so without jquery , your views will not work.
Try to find the main module of this app that you're using and there you will figure out how requireJs loads Jquery.
Backbone has this piece of code. Which shows his dependency on Jquery.
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '1.1.2';
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
Backbone.$ = $;

Ordering files with grunt-neuter

I've created an ember app with yeoman and am trying to get the build to order the scripts. I have an app.coffee which contains require 'scripts/controllers/*' but I also need to order the scripts within controllers. I have something like this:
controllers/foo_controller.js.coffee
require "./bar_controller"
App.FooController = App.BarController.extend()
controllers/bar_controller.js.coffee
App.BarController = Ember.Controller.extend()
But it isn't ordering these files. Am I doing it correctly?
I fixed this, I had the relative path wrong. It should have looked like this:
require "scripts/controllers/bar_controller"
App.FooController = App.BarController.extend()

require.js: how can I load a module that defines a name under a different name?

I'm trying to load underscore.js with require.js like this:
require(["libs/underscore-1.2.3.js"], function(_) {
...
});
But this doesn't work because underscore.js exports a module name: define('underscore', function() { ... }).
Without renaming lib/underscore-1.2.3.js, how can I load it with require.js?
Alright, after some more googling, I've found: https://github.com/documentcloud/underscore/pull/338#issuecomment-3245213
Where
#dvdotsenko all AMD loaders allow mapping a module ID to a partial path, usually the configuration is called 'paths', so to do what you want:
requirejs.config({
paths:
underscore: 'js/libs/underscore-1.2.3.min'
}
});
require(['underscore'], function () {});
Since underscore is used by other higher-level modules, like backbone, a common dependency name needs to be used to communicate a common dependency on underscore, and it makes sense to call that dependency 'underscore'. The paths config gives a way to do the mapping to a specific URL you want to use for that dependency.
This doesn't answer my question (ie, I still don't know how I'd go about loading underscore if all I had was a URL), but at least it's a functional workaround.
While this doesn't strike me as the most ideal solution, you can require your external files, and then require their registered module names in the inner block.
JSFiddle Example
require(
['require','http://documentcloud.github.com/underscore/underscore-min.js'],
function(require){
require(['underscore'],function(_){
var a = _.intersection([1,2,3],[2,3,4]);
document.write("Underscore is available in the closure : " + a);
})
}
)
It might not look pretty, but that might be a recommended pattern for loading up initial assets so that they can be required intuitively in dependent modules.

Categories