Pattern for Backbone app using requirejs

2020-07-27 16:29发布

问题:

I came across this article about about backbone apps with requirejs. There is one thing that seems really odd. Whenever they need a reference of Backbone, Underscore or jquery in my module I have to require them:

define([
  'jQuery',
  'Underscore',
  'Backbone',
  'collections/projects',
], function($, _, Backbone, ProjectsCollection, projectsListTemplate){
  var projectListView = Backbone.View.extend({
    el: $("#container"),
...

So is there really a need to go that way? Isn't a bit over engineered? Couldn't I just load Backbone and its dependencies before I start my app and use them as global objects like I would do it without requirejs? Or miss I something here?

回答1:

There are pros/cons either way.

Advantage:

Your dependency management is completely controlled by require.js, instead of relying on synchronously-loaded globally-scoped libraries. It's elegant, modular, and is probably The Right Way to do things.

Advantage:

It's easier to swap in versions of libraries, particularly per-module. I've honestly never seen this in practice - it seems like a "what if" situation rather than something practical. If you do then you're probably hacking something together anyway, sacrificing the "code elegance" you're getting by using them as modules in the first place.

Disadvantage:

You get a lot of boilerplate imports.

define(['jQuery', 'underscore', 'backbone', 'raphael', ...],

In a large app, it could take a half dozen library dependencies before you get to your dependencies. In every module.

The redundancy feels especially unnecessary for Backbone-heavy apps, where each module is probably defining a Backbone model/controller/view - almost every module requires Backbone.

You could wrap them all into a single Lib module that you'd reference like Lib.$(...) or Lib._(...), but that's just moving the boilerplate out of the imports and into the code. It also negates advantage #2.

So which one?

I'd say to look at each library individually and decide whether or not it should be global or its own imported module.

If you're going to use the library almost everywhere (e.g. jQuery, Backbone), then just keep it global.

For other libraries you might only use them in a couple views (e.g. Raphael.js). In that case, import it as a module.