How to efficiently import an external ES module from a URL using TypeScript

I've recently started experimenting with Observable notebooks and I must say, it's been a great experience so far. Now, my next goal is to integrate a notebook into my web app. The following vanilla JavaScript code using JavaScript modules accomplishes this seamlessly:

<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>

However, when attempting to import a module from a remote URL in TypeScript, compilation errors arise:

// 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 experimented with using // @ts-ignore to bypass the compile-time errors but they then manifest during runtime. I've also delved into the import-http Webpack plugin as a potential solution, without success in resolving the compile-time issues.

I am aware that this issue is not exclusive to Observable, rather it pertains more to TypeScript and/or Webpack. Nonetheless, any alternatives or solutions specific to Observable would be highly valuable.

Therefore, my query is: How can I dynamically import an external ES module from a remote location, particularly in TypeScript? This way, I aim to achieve something similar to:

// 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));
}

Answer №1

TLDR: To resolve the issue, you must declare the module and include it in your tsconfig.json

It seems that TypeScript is unable to find any definition for this particular module.
For further assistance, you can refer to this helpful answer and this informative document.
I have conducted a test by creating a sample project:

.
└── ./
    ├── 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
// one of the following declarations should suffice
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 configuration here
  },
  "include": [
    ....your configuration here
    "./src/declarations.d.ts" // include this line
  ]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Uncovering Module - which interface is missing a defined structure?

Can anyone explain why I am receiving this error in TypeScript 3.9.2: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. The code triggering the error is shown below: const Module = function(){ ...

The React Functional Component undergoes exponential re-renders when there is a change in the array

I'm encountering a problem with one of my functional components. Essentially, it maintains an array of messages in the state; when a new message is received from the server, the state should update by adding that new message to the array. The issue ar ...

Jest: Test fails due to import statement in node_module dependency

Short Version I'm experiencing a crash in my Jest test due to a SyntaxError related to an import statement outside a module. The issue arises from a node_module that uses the import statement. How can I resolve this error? Situation Overview In deve ...

Tips for integrating TypeScript with Vue.js and Single File Components

After extensive searching online, I have struggled to find a straightforward and up-to-date example of setting up Vue.js with TypeScript. The typical tutorials out there either are outdated or rely on specific configurations that don't apply universal ...

Transformation of CSS classes in React with Webpack

Have you ever noticed that when you inspect the Airbnb website, the classnames appear to be morphed into single alphanumeric names? What is the name of this technique and is it applied at the code level or build level? ...

Using surge.sh to deploy a Vue project

All day I've been attempting to deploy my Vue project on Surge.sh. The project is built using the webpack-simple template. Strangely, manual deployment from my CLI works fine. However, when I push it to GitHub and try deploying it from Travis CI, it ...

Dynamic table row that expands to show additional rows sourced from various data sets

Is there a way to expand the table row in an angular-material table when it is clicked, showing multiple sets of rows in the same column as the table? The new rows should share the same column header but not necessarily come from the same data source. Whe ...

Six Material-UI TextFields sharing a single label

Is there a way to create 6 MUI TextField components for entering 6 numbers separated by dots, all enclosed within one common label 'Code Number' inside a single FormControl? The issue here is that the label currently appears only in the first tex ...

What is the correct way to implement "next-redux-wrapper" with "Next.js", "Redux-ToolKit" and Typescript?

Currently, I am integrating RTK (redux-toolkit) into my Next.js App. I am facing an issue while trying to dispatch an AsyncThunk Action within "getInitialProps". During my research, I came across a package named "next-redux-wrapper" that allows access to t ...

"Dealing with conflicts between RMQ and TypeORM in a NestJS

Every time I try to use TypeOrm, RMQ crashes. I can't figure out why. Utilizing the library golevelup/nestjs-rabbitmq has been a struggle for me. I've spent 7 hours trying to resolve this issue. @Module({ imports: [ ConfigModule.f ...

Is it possible to set up a universal type definition in TypeScript version 2 and above?

I have a collection of straightforward .ts files, not part of any projects but standalone .ts scripts. They implement certain node.js features. Both TypeScript and node type definitions are set up through the following commands: npm install -g typescript ...

Encountering issues with TypeScript class

I am facing an issue with transpiling the following TypeScript class: class DataService { styles: Object[]; selectedStyle: Object; selectedChildStyle: Object; constructor() { this.styles = [{ "name": " ...

Concerning the utilization of the <mat-toolbar> element within Angular

Is the mat-toolbar in Angular going to persist across all components and pages of the application? Will it be present in every component throughout the application? <mat-toolbar color="primary"> <mat-toolbar-row> <span>Welcome to C ...

Angular - Show a table of items from a given list

I recently started using Angular and I'm facing a challenge in displaying multiple tables based on a list of values. Each rule refNo should have its own separate rule conditions table displayed sequentially. Currently, all the tables are showing the s ...

Error message TS2339 in Typescript: The property '__super__' is not found on the type '($element: any, options: any) => any'

Having trouble with Javascript code inside typescript. $.fn.select2.amd.require([ 'select2/data/array', 'select2/utils' ], function (ArrayData, Utils) { /* tslint:disable */ function CustomData ($element, opti ...

Encountered an error while trying to update information in Angular

I have been working on a project involving a .NET Core Web API and Angular 11 (Full-Stack) project. I have successfully managed to add data to the database in my back-end, but I am encountering an issue when trying to update the data. Below is a snippet o ...

Validating React components with TypeScript using an array structure where the field name serves as the key

Trying to implement form validation with React. I have a main Controller that contains the model and manages the validation process. The model is passed down to child controllers along with the validation errors. I am looking for a way to create an array ...

Encountering an Unexpected Token error while attempting to lazy load a component with Vue Router

I have been attempting to implement lazy loading for the Login component on my login route in Vue.js. However, upon building with webpack, I encounter the following error: SyntaxError: Unexpected Token Interestingly, the Login.vue component works perfect ...

Guide on Importing All Functions from a Custom Javascript File

As a beginner in learning Angular, I am faced with the task of converting a template into Angular. However, I am struggling to find a solution for importing all functions from a custom js file into my .component.ts file at once. I have already attempted t ...

Dynamically attach rows to a table in Angular by triggering a TypeScript method with a button click

I need help creating a button that will add rows to a table dynamically when pressed. However, I am encountering an error when trying to call the function in TypeScript (save_row()). How can I successfully call the function in TypeScript and dynamically a ...