The only thing thatās implicitly loaded in an Observable notebook is the Observable standard library.
In addition, when using require, any dependencies of the module you require are also loaded. For example, if you look at the d3-graphviz bundle, youāll see that it depends on a few other modules (viz.js/viz, d3-selection, d3-dispatch, d3-transition, etc.):
https://unpkg.com/d3-graphviz@2.1.0/build/d3-graphviz.js
These modules are loaded because they are dependencies of d3-graphviz, but they are not exposed on the object resolved by require because they are considered internal dependencies to d3-graphviz.
If you want access to these dependent modules, you need to require them separately. Note, however, that this wonāt cause the scripts to be downloaded twiceārequire is smart enough to detect that it has already loaded a module and return the existing copy.
For example, you might say:
d3 = require("d3-graphviz", "d3-selection", "d3-dispatch", ā¦)
Viz = require("viz.js/viz")
(Note that Iām using the āsplatā capabilities of Observableās require that allows combining of multiple modules into a single shared namespace object. This is nice for D3 modules since they are designed for this pattern.)
There are two unfortunate limitations here:
First, you canāt mix and match D3ās default bundle (d3) with individual D3 modules (such as d3-selection). Since d3-graphviz (correctly) depends on the D3 modules, your notebook must also load the D3 modules separately. We could fix that in D3 by providing an AMD-only bundle that depends on the D3 modules (as we already do for CommonJS). But for now you have to list the D3 modules by hand.
Second, Observableās require doesnāt currently handle dependency version resolution. Meaning, when you require a module, it will always require the latest version of any dependencies, regardless of whatās declared in the dependencies block of the moduleās package.json. You can specify versions at the top level, such as require("d3-selection@1")
, but if you do this, it will no longer be considered the same module as the require("d3-selection")
dependency of d3-graphviz, so then youāll have two copies of d3-selection.
These limitations can be avoided by using ES dynamic import instead of require, since unpkg dynamically rewrites static imports to resolve dependency versions. However, the D3 default bundle also isnāt optimized for ES imports at the momentāitāll trigger about 500+ requests for unminified code, making it much slower than require.
Our hope is that in the long term these challenges will evaporate with widespread adoption of ES modules and support for ES import. But weāre still a ways from that, so it may be needed for us to ship some interim improvements to require.