Hello forum! Require

Require wont find my NPM package. Tips?

If you are trying, say, require('turf'), I would try require('@turf/turf') and see if that is successful.

Hello, and congrats for being the first to post here!

Given how many kinds of modules there are in JavaScript, unfortunately part of the answer is “it depends on the module”. But there are some ways to fix the common issues:

  • By default Observable supports modules that have UMD or AMD files included, and they point to those files with unpkg or main fields in their package.json
  • Some modules don’t have UMD or AMD builds, but they’re written in basic CommonJS and can be run through browserify with success. For that, try instead of require('finicky-package'), require('https://wzrd.in/standalone/finicky-package'). wzrd.in is a site that automatically runs browserify for you, and often does the trick.

I’ve pulled together a notebook that guides you through some of the common troubleshooting steps: Requiring modules troubleshooting.

3 Likes

Thanks @tom! This was the first problem I had when trying to pull in a new library. I’ll be using this wrapper whenever require fails:

browserify = lib => require(`https://wzrd.in/standalone/${lib}`)

Tested with this:

FastSimplexNoise = (await browserify('fast-simplex-noise@3.2.0')).default

I’m having issues with a library that uses browserify-shim and expects me to load some libraries separately. Since Observable notebooks run cells in an isolated iframe, the dependencies are not available. What is the recommended approach here?

Did you see Tom’s how-to on stubborn modules, posted above? If that doesn’t cover it, please post a code snippet so we can help you debug. One of the tricky things here is that JS libraries (at least those not using the ES module standard) can come in myriad formats so there’s not a one-size-fits-all answer.

I have seen it but didn’t realize that I needed to put Vega and Vega-Lite in the window.

vegaEmbed = {
  window.vega = await require("vega@3");
  window.vl = await require("vega-lite@2");
  return require("vega-embed@3");
}

Works like a charm. Maybe you want to add this example to the notebook.

I’m thinking of publishing a single package with all dependencies in it. Unfortunately, then dependencies wouldn’t be updated automatically.

Building a single bundle is similar to

vegaEmbed = (await require('https://wzrd.in/standalone/vega-embed@3')).default

However, I don’t know how reliable https://wzrd.in/ is.

Wzrd.in wouldn’t parse it.
This worked however, so I’m guessing may cover some of cases where they aren’t written to amd etc…

await require('https://unpkg.com/enigmatic').catch(()=>{window.enigmatic})