1

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

Zennichimaro
  • 5,236
  • 6
  • 54
  • 78

1 Answers1

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.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks it works! For my simplified `One`, `Two` and `Three`, but in the real `legacy.js` the `Three` actually refers to `Two` and `One`, do you know how I can include the new `legacy-2.js` into the now `legacy-3.js` – Zennichimaro Jan 27 '22 at 08:41