Follow treslines by email clicking Here!

Thursday, October 13, 2016

How to add / import javascript dependencies dynamically into your html

Hi there!

Today i'm gonna show you, how to import / add javascript dependencies dynamically to your html files. I'm playing with object orientation in javascript and in this context, I've created a class that does exactly that and I'd like to share with you.

'use strict'

/** 
 * Use this class to import all dependencies dynamically into your html.
 * This class imports the dependencies only if not exits already.
 * 
 * Usage example: 
 * add this line to your html. Ex: index.html
 * < script  src="../yourProjectPath/js/dependencies.js" > < / script >
 * 
 * Then in your program.js used in this index.html, use it like this:
 * var dependencyArray = [];
 * dependencyArray.push("../../js/constants.js");
 * dependencyArray.push("../../js/utils.js");
 * dependencyArray.push("../../js/home.js");
 * var deps = new Dependency();
 * deps.addToBody(dependencyArray);
 * or alternativelly
 * deps.addToHead(dependencyArray);
 * 
* @author Ricardo Ferreira */ var Dependency = function(){ //***************************************************************************** // Private methods // As per convention, private methods in javascript starts with underscore "_" //***************************************************************************** /** * private method - Use this method to import all dependencies into the html head or body. * @param {String} tag value "head" or "body". Other values than that will return false * @param {Array} srcArray - A string array with the source paths relative to this file * @returns {Bool} true the dependency has been added successfully. * @author Ricardo Ferreira */ function _into (tag, srcArray ) { if(srcArray){ // this way to check for an array is 2/3 faster // then "srcArray instanceof Array" and much faster // then "Array.isArray(srcArray)" if(srcArray.constructor === Array){ var index1; var index2; var bodyTag = "body"; var headTag = "head"; var srcTag = "src"; var scriptTag = "script"; var shallAddDependency; for (index1 = 0; index1 < srcArray.length; index1+=1) { // check if dependency does not exist already shallAddDependency = true; var srcPathDelimiter = "/"; var srcPath = srcArray[index1]; var scriptTagArr = document.body.getElementsByTagName(scriptTag); var javascriptName = _getJavascriptName(srcPath, srcPathDelimiter); for (index2 = 0; index2 < scriptTagArr.length; index2+=1) { var javascriptSrc = scriptTagArr[index2].src; if( _contains( javascriptSrc, javascriptName ) ){ shallAddDependency=false; break; } } if(shallAddDependency){ var script = document.createElement( scriptTag ); script.setAttribute( srcTag, srcPath ); if(tag === headTag){ document.head.appendChild( script ); }else if(tag === bodyTag){ document.body.appendChild( script ); }else{ return false; } } }return true; }return false; }return false; } /** * private method - Use this method to find out the javascript file name. * @param {String} srcPath that contains the whole javascript path * @param {String} pathDelimiter is the delimiter used to split the path * @returns {String} the javascript file name. Ex: home.js * @author Ricardo Ferreira */ function _getJavascriptName (srcPath, pathDelimiter){ var arrayOffset = 1; var split = srcPath.split(pathDelimiter); var javascriptName = split[split.length-arrayOffset]; return javascriptName; } /** * private method - Use this method to check if a substring is part of another string. * @param {String} string that could contain substrings * @param {String} substring to be checked inside of string * @returns {Bool} true if substring is part of string. * @author Ricardo Ferreira */ function _contains (string, substring) { var invalidIndex = -1; return string.indexOf(substring) != invalidIndex; }; //***************************************************************************** // Public methods //***************************************************************************** /** * Use this method to import all dependencies into the html body. * @param {Array} srcArray - A string array with the source paths relative to this file * @returns {Bool} true if dependencies has been added, false otherwise. * @author Ricardo Ferreira */ this.appendToBody = function( srcArray ) { var bodyTag = "body"; return _into(bodyTag , srcArray); }, /** * Use this method to import all dependencies into the html head. * @param {Array} srcArray - A string array with the source paths relative to this file * @returns {Bool} true if dependencies has been added, false otherwise. * @author Ricardo Ferreira */ this.appendToHead = function( srcArray ) { var headTag = "head"; return _into(headTag, srcArray); } };

That's all. Hope you like it!

2 comments:

  1. In browsers with limited execution of JS this use of lazy load JavaScript files is not practical.
    You should change the addTo to a more JS like function name, like appendTo...

    ReplyDelete
    Replies
    1. Hi Luis!

      The idea behind this post not to "lazy load" but further more to remove imports from the html and maintain and controll it in a single place (in the place where you need it) and to avoid duplicity besides the idead to show some OOP concepts using javascript.

      In the practise, we didn't see any problem or noticed any issue with it. Your suggestion with with the "appentTo" is really a better choice. Very well observed. Thanks a lot for that. :)

      Delete