javascripttypescriptbrowserstrophestrophe.js

Use javascript lib from typescript (with inherited javascript dependencies)


Context

I am building a project in plain Typescript to communicate with a chat server. For the that communication I am using strophe.js lib.

Strophe lib comes in three flavors: commonjs, esm and umd. I do not really understand the difference between these formats, according to what I have searched:

Based on this I could use esm or umd, as this app is intended to run in the browser.

I wrote a Typescript file to act as a wrapper to strophe library. This is how I import it:

import * as core from './dependencies/strophe.umd.js'; // using UMD
import core from './dependencies/strophe.esm.js'; // using ESM
const Strophe = core.Strophe;

// ...
// Usage example:
this.conn = new Strophe.Connection(options.connection, options.options);

My problem

When using ESM format:

I can see the interface definition, call its functions, etc. Everything is great but the browser throws: Uncaught TypeError: Failed to resolve module specifier "abab". Relative references must start with either "/", "./", or "../".

When using UMD format:

Not errors shown at first, but Strophe is not being imported correctly. When trying to call connect function this error is thrown:

Uncaught TypeError: Cannot read property 'Connection' of undefined

Update


Sandbox: https://codesandbox.io/s/bitter-grass-sh4s9

To test this I run tsc and then live-server to serve the files

tsconfig.json

{
  "extends": "@tsconfig/recommended/tsconfig.json",
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "baseUrl": "src",
    "outDir": "build",
    "sourceMap": false,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "allowJs": true,
    "noImplicitAny": false,
    "moduleResolution": "node",
    "removeComments": true,
    "lib": ["es2018", "dom"],
    "types": ["jest", "node"],
    "paths": {
      "@core/*": ["./src/core"]
    }
  },
  "include": ["src/**/*.ts"]
}

Solution

  • It woule be a good idea to add Strophe.js as a dependency through a package manager like npm or Yarn. It looks like you have manually placed them in the folder called dependencies.

    Adding the dependency: yarn add strophe.js
    Adding the type declarations: yarn add -D @types/strophe.js

    This would download Strophe.js into your node_modules folder.

    Importing it in your code:

    import { Strophe } from "strophe.js";
    this.conn = new Strophe.Connection(options.connection, options.options);