ded/script.js

[EXPIRED] Page-based loading

Closed this issue · 2 comments

There are a lot of JS loaders, really. But none of them, at least within documentation, addresses a problem I'm eager to solve. That is to use single <script> line per whole project which inits page-based loading of dependencies.

Let's create a simple project with index, portfolio, and contacts pages.

Microframework will help us with routing:

$app->get('/portfolio/',
    function () use ($app) {
        $prices = array(
              "price_mine"  => "90",
              "price_rival" => "120"
        );
        $app->render('portfolio.twig', $prices);
    })->name('portfolio');

Template engine will help us with rendering:

{% extends "base.twig" %}
{% block content %}
     <p>Aren't you sick and tired to pay {{price_rival}}…</p>.
{% endblock content %}

And the missing part in every page is <script src="/static/init.js"></script> that works as follows

  • all pages load jQuery from CDN or from my server as fallback,
  • index loads SoundManager to serve audio salutation,
  • portfolio loads Lightbox to serve images,
  • contacts loads Forms validator.

What's the best way to achieve it?
And how to do that with $script.js whether it's possible?

Thank you in advance.
Warm regards from Russia, Alexander.

ded commented

interesting. i'll have to think about this one for a bit.

@ded, so far I'm lucky to solve the case with LABjs!

  1. Download lab.min.js.
  2. Rename it to init.js.
  3. Add <script src="/js/init.js"></script> into <HEAD> of all pages.
  4. Add the following code inside init.js.
...original lab.min.js goes here...

// Parse URL to get last argument before trailing slash as page name, or set / for root page
// e.g. http://domain.tld/portfolio/dell/ -> dell, http://domain.tld/ -> /
var path = location.pathname.split("/"),
    page = path[path.length-2] || "/";

// Scripts for all pages
$LAB
        .queueScript("/js/lib/jquery.js")
        .queueWait();

// Scripts per page
switch (page) {
    case '/':
        $LAB
        .queueScript("/js/lib/soundmanager2.js");
        break;
    case 'portfolio':
        $LAB
        .queueScript("/js/lib/lightbox.js");
        break;
    case 'contacts':
        $LAB
        .queueScript("/js/lib/forms.js");
        break;
}

// Load last instructions and execute the queue, cutie
$LAB
        .queueScript("/js/letsrock.js")
        .runQueue();

As you can see solution is basic, yet it serves the purpose without overhead of extra attributes and third-party routers.
Unfortunately it seems LABjs has not fallback functionality built-in, so, for example, jQuery fallback turns into hell.

As for $script.js, is it possible to chain scripts and waits to run them in the end as shown above?