简体   繁体   中英

Dynamically include JavaScript modules

I am trying to dynamically load (aka 'include') a series of additional .js "module" files from a parent script.

I am doing this as part of a D3 reusable charts library which, when I publish, I actually run a Makefile which concatenates said "modules" together into a single script (and therefore removes the need for the dynamic include method). But while testing I want to load these "modules" separately (mainly to save me having to run the Makefile script each time I make a small change to one of the files).

I have figured out 3 possible solutions, and written different 'include' functions, one for each solution:

https://github.com/jamesleesaunders/d3.ez/blob/master/js/d3.ez.js

// Solution 1 - Using document.write
function includeV1(file) {
    var loc = document.currentScript.src
    var path = loc.substring(0, loc.lastIndexOf("/") + 1);
    var src = path + file;
    var type = 'text/javascript';

    document.write('<' + 'script src="' + src + '"' + ' type="' + type + '"><' + '/script>');
}

// Solution 2 - Using document.createElement
function includeV2(file) {
    // Method 2 - Using document.createElement
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');

    var loc = document.currentScript.src
    var path = loc.substring(0, loc.lastIndexOf("/") + 1);

    script.src = path + file;
    script.type = 'text/javascript';
    head.appendChild(script);
}

// Solution 3 - Using D3
function includeV3(file) {
    var loc = document.currentScript.src
    var path = loc.substring(0, loc.lastIndexOf("/") + 1);
    var src = path + file;
    var type = 'text/javascript';

    d3.select('head')
        .append("script")
        .attr('src', src)
        .attr('type', type);
}

Called like:

include('header.js');
include('radialBarChart.js');
include('circularHeatChart.js');
include('discreteBarChart.js');

Solution 1 above seems to work fine, and does exactly what I want to, however Solution 2 and 3 do not seem to work? Even though, as far as I can tell, they are doing the same thing.

I think the possible difference is that Solutions 2 and 3 insert the additional elements to the DOM after the page has loaded (and therefore not available to the main page script when it calls for one of the module functions). Whereas I am guessing that Solution 1 adds the tags at the point where it is called (and therefore module functions are available to the main page script when called for).

I am happy if Solution 1 is the only solution, as it works, but to satisfy my curiosity and also because I am writing a D3 library I would have preferred to have used Solution 3.

Can anyone advise why Solutions 2 and 3 do not work? Or offer any amendments?

I am not looking for a jQuery solution, but there may be some jQuery experts who may know?

For reference here is the Makefile which, when publishing, I run to concatenate the "module" files into a single script:

https://github.com/jamesleesaunders/d3.ez/blob/master/Makefile

Which then generates the concatenated:

https://github.com/jamesleesaunders/d3.ez/blob/master/d3.ez.js

现在已通过使用ES6模块解决了这一问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM