'javascript - importing from file that have a few function(global, factory)

I have a legacy code that uses function(global, factory) like this:

// legacy.js
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        console.log('my amd One');
        define([], factory);
    } else if (typeof module !== 'undefined' && module.exports) {
        console.log('my cjs One');
        module.exports = factory();
    } else {
        console.log('my esm One');
        global.One = factory();
    }
})(this, function () {
    console.log('hello One');

    function One(options) {
        console.log("function One", options);
        var self = this;
        self.connect = (url) => {
            console.log('One.connect: ' + url)
        }
    }

    One.prototype.myone = function (roomId, token) {
        console.log('myone: ' + roomId + ', ' + token);
     }

    return One;
});

(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        console.log('my amd Two');
        define([], factory);
    } else if (typeof module !== 'undefined' && module.exports) {
        console.log('my cjs Two');
        module.exports = factory();
    } else {
        console.log('my esm Two');
        global.Two = factory();
    }
})(this, function () {
    console.log('hello Two');

    function Two(options) {
        console.log("function Two", options);
        var self = this;
        self.connect = (url) => {
            console.log('Two.connect: ' + url)
        }
    }

    Two.prototype.mytwo = function (roomId, token) { 
        console.log('mytwo: ' + roomId + ', ' + token);
    };

    return Two;
});

(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        console.log('my amd Three');
        define([], factory);
    } else if (typeof module !== 'undefined' && module.exports) {
        console.log('my cjs Three');
        module.exports = factory();
    } else {
        console.log('my esm Three');
        global.Three = factory();
    }
})(this, function () {
    console.log('hello Three');

    function Three(options) {
        console.log("function Three", options);
        var self = this;
        self.connect = (url) => {
            console.log('Three.connect: ' + url)
        }
    }

    Three.prototype.mythree = function (roomId, token) { 
        console.log('mythree: ' + roomId + ', ' + token);
    };

    return Three;
});

I have setup webpack with babel so that I can import all One, Two, Three and hopefully use it from ES6 code, however it seems like I can only use Three which is defined last..

I'm importing and using it like this in my es6.js

// es6.js
import One from './legacy'
// const legacy = require('./legacy')

// console.log(legacy)
// console.log(legacy.One)
console.log(One) // prints out Three

function initTest() {

  const one = new One('hw');
  console.log('one: ', one); // prints out an instance of Three
  // one.myone('room1', 'token1'); // this will crash, myone is undefined but idk why??
  one.mythree('room1', 'token1'); // works
}

document.addEventListener('DOMContentLoaded', () => {

  initTest();
})

Anybody knows what I should do to access One and Two properly? I've tried using named import {One, Two, Three} or const legacy = require('./legacy'); to no avail..



Solution 1:[1]

The module is, frankly, broken.

If you load it as a CommonJS module (which you are), then each of the IIFEs will call a line that looks like this:

module.exports = factory();

So the first IIFE assigns One as the thing that is exported. Then the second IIFE overwrites it with Two and the third with Three.

Those IIFEs are not designed to be in the same file.

Move them into separate files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Quentin