hobbes3 hobbes3 - 2 months ago 18
Javascript Question

How to load a d3-dependent script using RequireJS?

I'm trying to load

using RequireJS. Looking at the minified
d3-path
source code, it looks like it's AMD-compliant since I see this in the first line:

!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s(t.d3=t.d3||{})}


My
index.html
looks like

<script>
require.config({
paths: {
"d3": "https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min",
"d3-path": "https://d3js.org/d3-path.v1.min",
"underscore": "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min",
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"
}
});
</script>


And my JS file that I'm trying to load
d3.path()
looks like

require([
"d3",
"d3-path",
"underscore"
],
function(
d3,
d3_path,
_
) {
// d3, d3_path, and _ are defined
// but d3.path() isn't defined
});


I can use
d3-path
by doing
d3_path.path()
but I would ideally like to do
d3.path()
. However if I set both
d3
and
d3-path
to
d3
then
d3-path
overrides
d3
and I lose the main
d3
functions.

I'm also open to RequireJS best practices since I'm not sure if I'm using the best method. Thanks!

Answer

Preliminary note : you're trying to load d3 V3 with a V4 module, that's not going to mesh very well.

Onto your question : that's the way it is intended to work when you use the micro modules. You load isolated functionalities and combine them.

You only get a d3 global when you use the vanilla environments as said in the docs: try

require.config({
    paths: {
        "d3": "https://d3js.org/d3.v4.min"
    }
});

require(['d3'], function(myd3) {
    console.log(window.d3); // undefined
    console.log(myd3); // d3 object
});

Note that if you load the whole d3 v4 library, you will get d3.path :

require(['d3'], function(myd3) {
    console.log(myd3.path); // function
});

Finally, if you intend to use multiple micro modules, you could use a mapped configuration:

require.config({
    paths: {
        d3src: 'https://d3js.org'
    },
    map: {
        '*': {
            'd3':  'd3src/d3.v4.min',
            'd3/selection':  'd3src/d3-selection.v1.min',
            'd3/path': 'd3src/d3-path.v1.min',
        }
    }
});


// if you want to load the selection and the path modules
require(['d3/selection', 'd3/path'], function(selection, path) {
    // ...
});

// if you want to load d3
require(['d3'], function(d3) {
    // ...
});