Dynamically import a remote ES module from an URL, in TypeScript
Asked Answered
J

1

11

I'm playing around with Observable notebooks and loving it. Now I want to embed a notebook on my web app. Using vanilla Javascript and Javascript modules this works well:

<script type="module">
  import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js";
  import notebook from "https://api.observablehq.com/d/d64beea6bedb0375.js?v=3";
  new Runtime().module(notebook, Inspector.into(document.body));
</script>

When I attemt to import a module through a remote URL in TypeScript, I get compile errors:

// error: Cannot find module 'https://api.observablehq.com/d/d64beea6bedb0375.js?v=3'
import notebook from 'https://api.observablehq.com/d/d64beea6bedb0375.js?v=3';

I've tried ignoring the compile-time errors using // @ts-ignore, but then they occur at runtime. I'm also looking into the import-http Webpack plugin, but that still does not appear to solve the compile-time errors.

I fully understand this is not specific to Obervable, but more related to TypeScript and/or Webpack. However, alternatives specific to Observable would be appreciated as well.

So, my question is: How can I dynamically import a remote/external ES module, in TypeScript? This so I can reproduce something like:

// url = 'https://api.observablehq.com/d/d64beea6bedb0375.js?v=3';

public async foo(url: string): Promise<void> {
  const notebook = await import(url);

  const runtime = new Runtime();
  const main = runtime.module(notebook, Inspector.into(document.body));
}
Jazminejazz answered 26/7, 2019 at 14:36 Comment(1)
have you figure this out?Spiracle
M
3

TLDR: you need to declare module and include it in tsconfig.json

I think it's because typescript can't find any definition about this module
This answer and this document could help you.
I did create a sample project to test this.

.
└── ./
    ├── src/
    │   ├── declarations.d.ts
    │   └── index.ts
    └── tsconfig.json
// index.ts
import notebook from "https://api.observablehq.com/d/d64beea6bedb0375.js?v=3";
// declarations.d.ts
// either
declare module 'https://api.observablehq.com/d/d64beea6bedb0375.js?v=3'

// or
declare module "https://api.observablehq.com/d/d64beea6bedb0375.js?v=3" {}

// or
declare module "https://api.observablehq.com/d/d64beea6bedb0375.js?v=3" {
  export default function define(runtime:any, observer:any):any
}
{
  "compilerOptions": {
   ....your config
  },
  "include": [
    ....your config
    "./src/declarations.d.ts" // add this line
  ]
}
Maziemazlack answered 31/5, 2022 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.