This is honestly pretty tough, since as extension developers we have no control over the Webpack config.
Here are a few strategies I’ve used with success:
Pure CSS
Write a CSS file, targeting your .jp-xkcdCartoon
, and have it reference the image by URL. Eg,
/* style.css */
.jp-xkcdCartoon {
backgroundImage: url('./local/path/to/img.png');
}
And in your JS file, import
the CSS file:
// main.ts
import "./path/to/style.css"
This works because Webpack will see the “import” in your JS file, and follow it. Then, a separate Webpack plugin (defined in the JupyterLab build config) will in-line the stylesheet and the image. This is the most reliable, but rather inflexible and means you won’t be able to get the source data from JS.
URL loading
Using url-loader
is best if you need access to raw data from within JS.
// main.ts
import * as comic from "./path/to/img.png"
// `comic` will be a Base64 string
Note that for some file types, this may not work directly. You can force the use of url-loader
with a prefix:
// main.ts
import * as myTemplateFile from "url-loader!./path/to/my/data.html";
// myTemplateFile will be a regular text string
File reference
If none of those work, you can use file-loader
to import it. This will make Webpack include it with the build, but won’t give you direct data access (you’ll need to fetch()
it yourself). I’ve found this to be the least reliable method, because you need to be very careful constructing URLs (making sure they work on end-user deployments), but it has the benefit of not needing to pass data around directly.
Wrapping it all up
The build system in JupyterLab is very complicated right now, unfortunately. This is by necessity, given the technical constraints imposed by the build-chain (and the web as a whole). You can follow discussion on future direction here: Notes on JupyterLab Build