Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I import an IIFE-based JavaScript module into an Angular TypeScript app?

So I have a third-party SDK written as an oldschool IIFE based module. In other words it looks something like this:

var ThirdPartySDK = (function() {
  var export = {};

  // Add some methods to export

  return export;
})();

You would then be expected to use it by referencing it on the global scope like this:

<html>
  <body>
    <script src="lib/ThirdPartySDK.js">
    <script>
      ThirdPartySDK.foo();
    <\script>
  <\body>
<\html>

I could still use it this way of course, but is that really the best practice with Angular and TypeScript? Is there some way to set things up with angular/TypeScript/webpack so that I can use a proper import statement? Something like this:

import { ThirdPartySDK } from '../lib/ThirdPartySDK.js';
ThirdPartySDK.foo();
like image 698
Zac Delventhal Avatar asked Jan 16 '19 21:01

Zac Delventhal


People also ask

Can you import modules in JavaScript?

Use JavaScript import() to dynamically load a module. The import() returns a Promise that will be fulfilled once the module is loaded completely. Use the async / await to handle the result of the import() .

Can I use TypeScript module in JavaScript?

We cannot use TypeScript modules directly in our application. We need to use the JavaScript for TypeScript modules. To get the JavaScript files for the TypeScript modules, we need to compile modules using TypeScript compiler. Compilation of a module depends on the target environment you are aiming for.


1 Answers

The best way to have a proper import statement for the actual value of ThirdPartySDK is to refactor the script to a module that exports this value. The following snippet allows you to use the import statement as showed:

export const ThirdPartySDK = {
    foo() { console.log('Doing foo'); }
};

For big libraries refactoring is not always that easy, so I see 2 approaches that do not involve too much refactoring:


1. Export the ThirdPartySDK variable

You could simply make a module out of the IIFE file by exporting the current IThirdPartySDK variable (returned by the IIFE), and then import it as you showed:

export const ThirdPartySDK = (function() {
    var _export = {};

    // Add some methods to export

    return _export;
})();

Note that if you want to have some useful information about the shape of ThirdPartySDK you would have to add a type annotation to the const declaration, and if SomeType (see below) does not yet exist you'll have to write it yourself:

export const ThirdPartySDK: SomeType = (function() {
// ...

At this point Typescript will start to complain about the IIFE expression not being assignable to SomeType; the quick 'solution' to tell typescript to pretend the expression evaluates to a value of type SomeType using the as keyword:

export const ThirdPartySDK: SomeType = (function() {
    // ...
})() as SomeType;

2. Keep the <script> tag and declare the variable

Another option it to keep the script tag, import nothing, and declare the variable and its expected type in typescript:

(But also in this case you might have to provide type definitions yourself)

interface SomeType {
    // SDK type shape goes here...
}

declare const ThirdPartySDK: SomeType;
like image 71
JJWesterkamp Avatar answered Oct 10 '22 13:10

JJWesterkamp