Using Data URLs to Load Dependencies in Deno

shadowtime2000

shadowtime2000

Posted on February 1, 2021

Using Data URLs to Load Dependencies in Deno

Recently Deno released 1.7.0 which had support for data URLs. I think this is a pretty cool way to dynamically create modules on the fly when paired with import(). This could be used to dynamically load all the dependencies we want to use in our file at once.

Data URLs

Data URLs are basically URLs but with data encoded in some form so that instead of a link to data, it holds the data inside itself. Data URLs first need to start with data:. We then need to append the MIME type of the file we are loading, in this case application/typescript but we could also do application/javascript. After we append the format for encoding the file, in this tutorial we will be using base64 and you also append a , followed by the actual encoding of the file.

An Example

Imagine we have this file:

export const add = (a: number, b: number) => a + b;
Enter fullscreen mode Exit fullscreen mode

and we want to import it from a data URL. Then we would first get the boilerplate.

const { add } = await import("data:application/typescript;base64,");
Enter fullscreen mode Exit fullscreen mode

Then we need to append the base64 encoding. For this it is

ZXhwb3J0IGNvbnN0IGFkZCA9IChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gYSArIGI7
Enter fullscreen mode Exit fullscreen mode

So the final code is:

const { add } = await import("data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGFkZCA9IChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gYSArIGI7");
Enter fullscreen mode Exit fullscreen mode

and it will correctly export the add function.

Loading Dependencies

Now that we know how to use them, let’s create a helper function to load dependencies. Let’s first create the type definition.

interface Dependency {
 url: string;
 name: string;
}
function loadDependencies(deps: Dependency[]) {
}
Enter fullscreen mode Exit fullscreen mode

We want to create a variable for the data URL to import and a variable for the source code of the import. We also want to loop over the deps array.

function loadDependencies(deps: Dependency[]) {
 let code = "";
 let dataURL = "data:application/typescript;base64,";
 deps.forEach({ url, name} => {

 });
}
Enter fullscreen mode Exit fullscreen mode

Now let’s append exports to code for each dependency.

function loadDependencies(deps: Dependency[]) {
 let code = "";
 let dataURL = "data:application/typescript;base64,";
 deps.forEach(({ url, name }) => {
  code += `export * as ${name} from "${url}"`;
 });
}
Enter fullscreen mode Exit fullscreen mode

Now let’s encode that. We also have to add a dependency to the standard library.

import { encode } from "https://deno.land/std@0.84.0/encoding/base64.ts";
Enter fullscreen mode Exit fullscreen mode

Now let’s do the finishing parts.

function loadDependencies(deps: Dependency[]) {
 let code = "";
 let dataURL = "data:application/typescript;base64,";
 deps.forEach(({ url, name }) => {
  code += `export * as ${name} from "${url}"`;
 });
 dataURL += encode(code);
 return import(dataURL);
}
Enter fullscreen mode Exit fullscreen mode

And 🎉you can import dependencies with it!

const deps = await loadDependencies([{ name: "aleph", url: "https://deno.land/x/aleph/mod.ts" }]);
Enter fullscreen mode Exit fullscreen mode

If you liked this article I suggest you check out other articles of mine on my blog.

💖 💪 🙅 🚩
shadowtime2000
shadowtime2000

Posted on February 1, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related