Click here to Skip to main content
Email Password   helpLost your password?
  • Download source files - 10.4 Kb

    Foreword

    This is the third and final part of the article, and for better understanding of this part, I recommend reading the first and second parts first.

    Part III

    From Previous Parts

    The challenge - To create an engine that will implement the JavaScript’s missing functionality of including in js files other js files.

    The solutions - A solution that works only if the external files contain functions, or declarations that don't depend on other files and another solution that works in every situation but has one small disadvantage: having to create header files for the source files.

    The second isn’t far from meeting the challenge, but not there yet. Can we push further?

    Solution 3

    The Logic

    One of the problems identified back then was that when the execution of a script starts, it goes all the way and from that we have the restriction: all files should contain only function declarations and object declarations (but only if they're not related to objects from other files).

    Ideally, only the part with the $include function of the file should be executed – and will name this part header, and then, when the time is right, the rest – body, but as I stated above, it cannot be done.

    Let’s think again; how do we stop the execution of a script? For a function you use return, but for the entire script?

    Error is the answer!!! When an error occurs the script’s execution is halted! So we throw an error on purpose! The next question will be: But the browser won’t display the error? It will, unless we override window.onerror so that nothing will be shown to the user.

    Our code should look like this

    $include = function ()

    {

    //code …

    throw new Error(“Special Error”);

    }

    Window.onerror = function ()

    {

    //we can check here to see if the message of the error is not “Special Error” //and then show it to the user

    }

    But 2 problems arise:

    1. The execution of the script can be resumed when needed? NO! (But we can execute it all again)

    2. Also, what happens when a legitimate error occurs? Can it be shown? (Yes, because we can differentiate through an error from the parser and a personalized error thrown by us).

    However there is a more elegant approach: using an iframe.

    But how? A solution would be as text file. Next we read the header (that now does not necessarily have to be a function) and then use eval to execute the body. As stated in the first part eval handles badly resources and this makes it totally inappropriate for executing large portion of code as in our case.

    The other problem is that IE doesn't load the js file like text, but asks you to download it.

    So we will have a html file that will load the script normally and will execute only the $include function that will pass to the parent document the filenames that are dependencies for the file currently loaded in the iframe, and after that we will throw the error.

    Also when a file is loaded is cached so, when needed for the main document, isn’t loaded from the server again.

    But what happens if the script has no dependencies, therefore no $include function?

    Can we force the user to use $include() with no parameters? Yes we can, but also we can wait till the script.onload event is fired and then tell the parent document that this file has no dependencies.

    Of course another problem: the script will be executed twice: first in the iframe and second in the main document; and that’s the least of our problems; the code can contain alert, confirm, open etc. that will screw up our work badly by executing in the iframe.

    And yet another artifice: overriding window.alert, window.open, window.confirm etc. and not just setting them to do nothing but to stop the execution of the script also.

    And that seems to be it!

    Let’s recap a bit:

    The main page will contain a tree of files that will be created by recursively passing a filename (filepath) to the iframe’s document that will return the dependencies for that file. Here we’ll need an algorithm to check for circular dependencies. And of course the $include function will do nothing in the main page.

    After that all files can be added to the main document’s head in the correct order.

    Of course we will keep from the first solution we’ll keep the code that lets us specify path relative to the IncludingEngine.js file and not to the current html document, and from the second solution the way the application starts with the Main function.

    The Implementation

    Unlike the implementations from the previous 2 parts, this one is much larger, therefore not suited for pasting it here.

    But the most important thing was already presented above: general idea together with the little ideas on how to overcome different barriers.

    However you can download this implementation and then examine it. (Don’t forget: there are 2 files: IncludingEngine.js and LoadFile.htm that toghether do the job)


    Next diagram expresses the power of the product that resulted from this solution:

     

    Things that this diagram doesn't show about the resulted product:
    - it works online and offline.
    - doesn't use eval
    - detects and shows the files that form circular dependencies.

    Now we can say that the challenges established in the first part were finally met.

    Notes:
    - the latest version of this implementation can be found at IncludingEngine.jsFramework.com

    Here are all the parts of "Javascript Including Engine" article: Part I, Part II, Part III.
    Also you may want to visit the IncludingEngine website for more info.



  • You must Sign In to use this message board.
     
     
    Per page   
     FirstPrevNext
    GeneralImpossible? Seems not!
    bobyThorn
    19:01 29 Jul '07  
    A couple of years ago I needed badly something to include my js files in other js files; since there was none I tried to do it myself. After spending a lot of time researching over the net and twisting my mind on how to do it, I've reach to the conclusion that it is impossible without a technological improvement (like a native implementation in JavaScript Smile )

    Now it seems that's not impossible!
    I think you did an extraordinary job!
    GeneralRe: Impossible? Seems not!
    Alexandru Lungu
    10:58 30 Jul '07  
    Thank you
    GeneralSee my post in Part I
    SBJ
    11:54 29 Jan '07  
    Happy Scripting!
    GeneralLicense
    Sceptic Mole
    6:18 24 Jan '07  
    A professional Open Source License[^], esp. BSD or MIT, would be more, well, professional. WTF




    GeneralRe: License
    Alexandru Lungu
    13:00 24 Jan '07  

    Professional, hmmm…
    You’re probably right…

    Thank you for the link.



    Last Updated 11 Jul 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010