Solving Javascript dependencies with arbitrary ordered include

The problem is I include a script, it uses a different one, but what if this dependency also needs the following script to be ready? This means it is not enough to load it, but I also need to make sure that its initialization callback has been called before execution. The order of script tags in the DOM cannot be correct if dependencies are allowed to require more dependencies and show them when they are loaded.

The problems become more complex when more than one dependency is required for scripts and dependencies, or a file satisfies more than one component.

Using .js seems to have a good approach for this, but first, the dependency relationships must be known before downloading them, and secondly, the author claims that some tests no longer work in Firefox. I suspect this is an execution lock, which seems a bit magical.

I wrote a loader to handle this completely asynchronous, which actually seems to work. But I can't shake the feelings that something has been decided before or that it cannot be so difficult.

+2


source to share


3 answers


The order of script tags in the DOM cannot be correct if dependencies are allowed to require more dependencies and show them after loading.

Well, what are these scripts trying to load their own dependencies? This is not a standard JavaScript feature, so there is no answer; how you deal with this is specific to the script that is trying to include dependencies.

For scripts loading synchronously (included via document.write or adding script elements to the DOM on load), you can at least be sure that you are good to go to load. For asynchronous loading (deferred scripting, AJAX enable, or out-of-the-box callbacks triggered by a timeout) there must be a callback mechanism. If you're mixing different scripts that have different systems of dependencies and out-of-the-box callbacks, it will be a pain.



I wrote a loader to handle this completely asynchronous, which actually seems to work. But I can't shake the feelings that something has been decided before or that it cannot be so difficult.

No, not at all. Dependency handling and dynamic script injection will always be a little tricky. The only "standard approach" allowed is completely static scripts, manually writing them in dependency order.

+2


source


There are several approaches to solving your problem. Almost all of the approaches are in this presentation on Javascript Dependency Management .

The one that better solves your problem is using the jingo library.

Basically with jingoยน you can do something like this to declare a module with dependencies:



  jingo.declare({
    require: [
      'hallmart.Greeter'
    ],
    name: 'hallmart.Store',
    as: function() {
      hallmart.Store = function() {
        var greeter = new hallmart.Greeter();
        this.admit = function(customer) {
          greeter.welcome(customer.name);
        };
      };
   }
 });

      

See code.google.com/p/jingo/wiki/GettingStarted file for links.

ยน code.google.com/p/jingo/

+2


source


I'm biased but recently created a javascript dependency manager called Pyramid . It is similar to other dependency managers (and probably similar to the one you created), except for a few key features.

  • It can load any file, not just javascript, and allows you to define how the file will be included in your web page. During development, I use it to not only load javascript and css files, but also insert html into my main page. This allows me to keep my html views separate (which is great for libraries like knockout)
  • Merges your files when it's time to release.
  • It is written entirely in javascript, so setup is easy. You don't need to worry about external tools.
  • You only need to install the script for all your html files. After that, all files can be updated in a single dependency loader file (instead of constantly updating included files in all headers when you rename, delete or add scripts)

Pyramid Dependency Manager Documentation

Sample code to show how it works during development.

File: dependencyLoader.js

//Set up file dependencies
Pyramid.createOrUpdate({
    name: 'standard',
    files: [
    'standardResources/jquery.1.6.1.min.js'
    ]
});

Pyramid.createOrUpdate({
name:'lookAndFeel',
files: [
    'styles.css',
    'customStyles.css'
    ]
});

Pyramid.createOrUpdate({
name:'main',
files: [
    'createNamespace.js',
    'views/buttonView.view', //contains just html code for a jquery.tmpl template
    'models/person.js',
    'init.js'
    ],
    dependencies: ['standard','lookAndFeel']
});

      

HTML files

<head>
    <script src="standardResources/pyramid-1.0.1.js"></script>
    <script src="dependencyLoader.js"></script>
    <script type="text/javascript">
        Pyramid.load('main');
    </script>
</head>

      

0


source







All Articles