1

I'm beginning learning Node.js and Backbone. I'd like to share some code between the server and the client (related to [1] and [2]). More in deep:

  • Share defaults values for a model. Defaults are used to populate forms (client-side), while they are enforced server-side
  • Share validation rules in order to be DRY and perform client/server validation
  • Share instance methods

So my idea is to use a factory object to encapsulate common code (defaults, validation rules, public instance methods) and adapt the factory object based on the environment (Node.js or AMD module).

This code is quick&dirty and may not work. Is this a good approach or just a waste of time?

(function (factory) {
    if (typeof exports === 'object') { // Node.js
        var config    = require('../config/config.json'),
            Sequelize = require('sequelize'),
                    _ = require('underscore');

        var User = {
            receiveSms: {
                type: Sequelize.BOOLEAN, allowNull: false
            },
            receiveNewsletter: {
                type: Sequelize.BOOLEAN, allowNull: false
            }
        };

        // Add defaultValue for each returned by 
        _.each(factory.defaults, function (value, key) {
            if(_.has(User, key)) {
                User[key].defaultValue = value;
            }
        });

        module.exports = function () {
            (new Sequelize(config.database, config.username, config.password))
                .define('User', User);
        };
    } else if (typeof define === 'function' && define.amd) { // AMD
        define(['backbone', 'uderscore'], function (Backbone, _) {
            return Backbone.Model.extend(factory);
        });
    }
}(function () {
    return { // To be adapted
        defaults: {
            receiveSms: false,
            receiveNewsletter: true
        }
    }
}));
Community
  • 1
  • 1
gremo
  • 47,186
  • 75
  • 257
  • 421

2 Answers2

1

I think it's a better solution to use require.js (especially for using frameworks like underscore in multiple files). You should use a factory only for objects that change during the runtime. A shopping cart for example (but even in this example i think it's more appropriate to use a backbone collection that is given to your function as an argument when instantiated). See more information here: http://requirejs.org/docs/node.html

tmuecksch
  • 6,222
  • 6
  • 40
  • 61
  • As I understand correctly, with requirejs node extension I'll be able to use one format for my modules. It's not what I'm asking, but it's interesting too. Thanks anyways. – gremo Feb 09 '13 at 15:04
  • Yeah. And you can "require" your frameworks or objects with some config values for example. I think after some reading you will realize this is exactly what you are looking for. – tmuecksch Feb 09 '13 at 15:06
1

Personally, I would steer away from requirejs as it requires you to rewrite your modules to fit their spec, which will eventually become defunct as the Ecmascript standard evolves.

For the time being, I would advise looking into the 'gulp' streaming build system. Using it, you'll find it extremely easy to pipe your shared js scripts into a publicly accessible directory, which can then be loaded from the client-side. A common technique for converting node js modules into browser scripts is using 'browserify' - magic!

Process: gulp.src > gulp-browserify > gulp.dest > ??? > Profit.

Further reading: http://viget.com/extend/gulp-browserify-starter-faq

Vix
  • 1,046
  • 10
  • 16