With every larger Project I’ve developed and architected I’ve tried something new to improve things I’ve coded before. Reflecting and never being satisfied whit things done before has helped me become a better front end developer and architect. Now I’m arrived at a point where I dare to say that I have found the ultimate technique to insert JavaScript into an application.
This technique uses, or rather is a combination of:
- non-blocking javascript downloads
- curl.js – a small, fast module and resource loader with dependency management
First, take a look at this code block. I’ll provide the explanation below.
<script id="bootstrap-js">
// curl.js configuration
var curl = {
baseUrl: "/js",
paths: {
curl: "libs/curl"
},
apiName: "require"
};
// this wrapper doesn't block the load event
setTimeout(function(){
// create curl.js script tag
var curlScript = document.createElement( "script" );
curlScript.src = "/js/libs/curl.min.js";
// callback executed when curlScript has loaded
curlScript.onload = function() {
// require main module on domReady
require(["app", "domReady!"], function( app ){
// here we init our application
app.init();
});
};
// inject curl.js script tag
var insertPoint = document.getElementById( "bootstrap-js" );
insertPoint.parentNode.insertBefore(curlScript, insertPoint);
}, 0);
</script>
The <script id="bootstrap-js">
Tag
This is the only <script>
tag in our markup! It’s very small (311 bytes minified) so we won’t benefit that much if we extract it to an external JS file. Instead we leave it without a src
attribute and save a HTTP request.
The curl
Object
The curl
Object is the configuration for curl.js. Curl let’s you rename the apiName
– in this case to require
– so you can use require
in your modules instead of curl
. This results in cross-loader ready modules. Check out Configuring curl.js for all configuration options and their explanation.
The setTimeout
Function
Without the setTimeout
wrapper the non-blocking curlScript
would block the load event as explained in The truth about non-blocking JavaScript. If we don’t care that much when the load event fires – or need it to fire as by default – we can change setTimeout to a Immediately-Invoked Function Expression (IIFE) (function(){ ... })();
.
The curlScript.onload
Function
Each resource loader has to be defined before you can access his API. With the curlScript.onload
event we know that curl.js has loaded. Now we can safely access its API by calling require
. Remember, we set the apiName
to require
before?
The insertPoint
This is our <script id="bootstrap-js">
tag, so we have more control where our curlScript
gets inserted.
Feedback is Welcome
I would love to hear your opinion about my ultimate technique. Please feel free to share your thoughts in the comments section. Hey, and you’re gonna be the first one who comments my blog. I’ll send you a bottle of Bavarian Beer if you do ;)
I didn’t explain how Asynchronous Module Defintion (AMD), CommonJS and ES Harmony modules work, so I assume that you already knew about them. If you want to know more about how JavaScript modules work and why they are important I recommend reading Writing Modular JavaScript.