Importing JS Modules

Table of Contents

References

jsdestructuring
const x = {
  default: "a",
  b: "42",
  c: () => {},
};
const { default: y, b: z } = x;
return { y, z };

txtUpdated 140.3w ago
{ y: 'a', z: '42' }

Skypack

jsskypack
const skypack = (pkg) => import(`https://cdn.skypack.dev/${pkg}`);
return skypack("canvas-confetti");

txtUpdated 140w ago
{ create: [Function: confettiCannon],
  default: { [Function: fire] reset: [Function], create: [Function: confettiCannon] } }
jsskypack
const skypack = (pkg) => import(`https://cdn.skypack.dev/${pkg}`);

return skypack("canvas-confetti").then((pkg) => {
  const { default: fire } = pkg;
  return fire();
});

txtUpdated 140.3w ago
undefined
jsskypack
const skypack = (pkg) => import(`https://cdn.skypack.dev/${pkg}`);

// I like async await
return (async (fn) => {
  const { default: fire } = await skypack("canvas-confetti");
  return fire();
})();

txtUpdated 140.3w ago
undefined

Unpkg

jsunpkg
const unpkg = (pkg) => import(`https://unpkg.com/${pkg}?module`);
return unpkg("canvas-confetti");

txtUpdated 140.3w ago
{ create: [Function: confettiCannon],
  default: { [Function: fire] reset: [Function], create: [Function: confettiCannon] } }
jsunpkg
const unpkg = (pkg) => import(`https://unpkg.com/${pkg}?module`);
return unpkg("canvas-confetti").then((pkg) => {
  return pkg.default();
});

txtUpdated 140.2w ago
undefined

Native ES Module REPL

jsmodule
import fire from "https://cdn.skypack.dev/canvas-confetti";

export const success = "yes";
export const issue =
  "module caching means it only executes once, had to add a cachebusting comment.";

export default () => import.meta
export const cons = typeof console !== "undefined" ? console : null;
fire();

txtUpdated 140w ago
{ url: 'blob:https://dotlit.org/f371b8d7-12a1-49d1-b9c6-ff6373727cf6#location=https://dotlit.org/testing/importing_js_modules.html?file=testing/importing_js_modules.lit#../plugins/repls/module.js' }
jsmodule
import foo from '/notfound.js'
export default foo
txtUpdated 140w ago
Module name, '/notfound.js' does not resolve to a valid URL.
txtUpdated 140.2w ago
Module name, '/notfound' does not resolve to a valid URL.
txtUpdated 140.2w ago
Module specifier, 'notfound' does not start with "/", "./", or "../". Referenced from data:text/javascript;base64,LyoxNjIxNTk2NjcxNDkzKi9pbXBvcnQgZm9vIGZyb20gJ25vdGZvdW5kJzsKZXhwb3J0IGRlZmF1bHQgZm9vOw==
jsmodule
export default async function (...args) {
  return { args, console, ctx: this };
};

txtUpdated 140.2w ago
{ args: [],
  console: 
   { debug: [Function],
     error: [Function],
     log: [Function],
     info: [Function],
     warn: [Function],
     clear: [Function],
     dir: [Function],
     dirxml: [Function: dirxml],
     table: [Function],
     trace: [Function: trace],
     assert: [Function],
     count: [Function],
     countReset: [Function],
     profile: [Function: profile],
     profileEnd: [Function: profileEnd],
     time: [Function],
     timeLog: [Function],
     timeEnd: [Function],
     timeStamp: [Function: timeStamp],
     takeHeapSnapshot: [Function: takeHeapSnapshot],
     group: [Function],
     groupCollapsed: [Function],
     groupEnd: [Function],
     record: [Function: record],
     recordEnd: [Function: recordEnd],
     screenshot: [Function: screenshot] },
  ctx: { console: 'fake me' } }
jsmodule
export default fn => console.screenshot(document.body)
txtUpdated 140.2w ago
undefined
jsmodule
const { inspect } = lit.utils;
const { wait } = lit.utils.fns;

export default async (fn) => {
  // https://github.com/whatwg/console/issues/120
  console.record();
  await wait(1000);
  console.log("tick", new Date());
  await wait(1000);
  console.log("tock", new Date());
  return console.recordEnd.toString();
};

txtUpdated 140.2w ago
'function recordEnd() {\n    [native code]\n}'

Local modules

This assumes you have the experimental service worker (testing/ServiceWorker) (version 0.2.10) enabled to vend files in the local filesystem via Web fetch API.

jscustom-module.mjs
export default (fn) => "Great Success!?";

js
const url = new URL("./foo", location.href)
return url.toString()
txtUpdated 140w ago
https://dotlit.org/testing/foo
jsmodule
import foo from "HORRIBLE_HACKcustom-module.mjs";
export const test1 = "HORRIBLE_HACKfoo";
export const test2 = new URL("HORRIBLE_HACKcustom-module.mjs").toString();
export const meta = import.meta;
export default foo();

txtUpdated 139w ago
{ default: 'Great Success!?',
  meta: { url: 'blob:https://dotlit.org/1e70656b-1af9-446a-a6f2-65ecd1b9baa8#location=https://dotlit.org/testing/importing_js_modules.html#' },
  test1: 'https://dotlit.org/testing/foo',
  test2: 'https://dotlit.org/testing/custom-module.mjs' }
txtUpdated 140w ago
'Great Success!'
txtUpdated 140w ago
Module name, './testing/custom-module.mjs' does not resolve to a valid URL.
txtUpdated 140w ago
{ url: 'blob:https://dotlit.org/cda4db85-6121-4041-b417-46e4de9dfe08#path=testing/importing_js_modules.lit' }
js
return fetch('/testing/custom-module.mjs').then(res => res.headers.get('Content-Type'))
txtUpdated 139w ago
text/javascript
  • Seems like 0.2.2 is Still not setting headers correctly, was expecting Got text/javascript.
  • fetch/sw now sends correct mime type, but still get Module name, '/testing/custom-module.mjs' does not resolve to a valid URL.
js
return fetch('/testing/custom-module.mjs--sw').then(res => res.text())
txtUpdated 139w ago
{
  "version": "0.2.14",
  "dotlit": "object",
  "root": "/",
  "enableCache": false,
  "filepath": "/testing/custom-module.mjs",
  "stat": {
    "type": "file",
    "mode": 438,
    "size": 42,
    "ino": 148,
    "mtimeMs": 1622206284542,
    "ctimeMs": 1622206284542,
    "uid": 1,
    "gid": 1,
    "dev": 1
  }
}
js
return fetch('/testing/custom-module.mjs').then(res => res.headers.get('server'))
txtUpdated 139.2w ago
dotlit.org/sw@0.2.12
txtUpdated 139.2w ago
GitHub.com
  • After updating the service worker to return the correct mime type, I suspect it's failing to resolve urls relative to the base64 data:uri setup. c.f. Original repl implementation which uses createObjectURL
jsextract
const esm = ({ raw }, ...vals) =>
        URL.createObjectURL(
          new Blob([String.raw({ raw }, ...vals)], { type: "text/javascript" })
        );