My team (co-workers but also we do have Teams accounts) wants to build a “library” of functions we frequently use in Observable in order to expedite our work in future notebooks.
My first thought was to have a separate notebook that would serve as our Library notebook, and then we could import functions as needed as one might already do with Jeremy Ashkenas’s Inputs functions, or with Mike Bostock’s Form function.
But I wanted to see if anyone had approached this in a different way that worked well for them. One different idea would be to use JS classes rather than writing individual functions to possibly keep the code cleaner / more organized. Another would be to build something as a JS library and then just import as a module. Would love to hear any pro/cons and/or ideas that people have to share!
I use a library notebook that re-exports libraries and useful functions so I don’t need to import them separately and can instead say
import {d3, vl, _, min, max, uniq} from '@yurivish/common'
One downside is that Observable’s code bundling currently bundles together all of the libraries referred to in the common notebook, even if you don’t import any of them:
import {min} from '@yurivish/common'
will still download the code for @vega/vega-lite-api and @jashkenas/inputs, since they are imported within @yurivish/common.
I like individual notebooks with a little documentation and tests ( https://observablehq.com/@tomlarkworthy/reconcile-nanomorph) if I want a bundle for a project it would be a distinct notebook that imported all the others. Did you know you can import another notebooks imports? You don’t need to go to the source notebook which is Handy for bundling. Things slow down with massive notebooks so I try to stay on a single topic.
With library notebooks, version pinning becomes even more important. Unfortunately it’s still fairly cumbersome to find a notebook’s current version. If you need a helper for that, have a look at the Toolbox notebook linked above.
Be careful with additional imports of other notebooks, as the referenced notebooks will be fetched even if they are not part of the dependency chain (because Observable turns them into static imports). I’d also avoid monolithic notebooks and bundle them by topic (preferably) or by frequency (for the most commonly used functions).
I love making libraries in Observable. This is a fairly large one: https://observablehq.com/@jflatow/quest, where I started using a new approach to testing in which I uncomment out the testing cell only when I am working on an update.
For your inspiration, here are some other smaller ones: