3

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:

  • commonjs is for node
  • esm for web apps
  • umd is generic

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"]
}
adrisons
  • 3,443
  • 3
  • 32
  • 48

1 Answers1

4

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);
torkel
  • 2,096
  • 3
  • 10
  • 20
  • Thanks! I didn't have the strophe.js dependency. Although when I open the html in the browser this error is shown in console: `Uncaught TypeError: Failed to resolve module specifier "strophe.js". Relative references must start with either "/", "./", or "../".` – adrisons Sep 22 '20 at 08:45
  • Great that you made a codesandbox! It looks like your current issue is not related to importing the Strophe.js dependency. At least I'm not seeing that issue in your codesandbox. If you're still having problems I'd suggest trimming down your codesandbox until it's the smallest reproducible version you can get, and then file a new question here on SO with that. – torkel Sep 22 '20 at 14:15
  • Also, would you mind accepting the answer, @adrisons? – torkel Sep 22 '20 at 14:16
  • I think it is related to the Strophe.js dependency, try to clic submit in the codesandbox. I will accept the answer when I can it work. You will receive the bounty anyway :) – adrisons Sep 22 '20 at 15:12
  • https://codesandbox.io/s/small-browser-4mgfv?file=/src/index.ts This only seem to happen when there's no value for the `jid` field. I'm assuming it makes sense to have the button be a no-op if there's no value there. As for "working", I'm not sure exactly what you're trying to do here. – torkel Sep 22 '20 at 21:32