Преобразовать модуль IIFE во что-то импортируемое RollupJS

Я использую RollupJS в качестве компоновщика, и он может читать CommonJS (через плагин) или модули ES6. Но этот модуль, кажется, в формате UMD, и я ищу быстрый способ, которым я могу отредактировать его (без замены большого количества строк), чтобы он был в формате commonJS или ES6.

Что люди предлагают? Я показываю верх и низ 5000-строчного файла.js.

@module vrlinkjs
**/
(function (mak) {

mak.MessageKindEnum = {
        Any : -1,
        Other : 0,
        AttributeUpdate : 1,
        Interaction : 2,
        Connect : 3,
        ObjectDeletion : 4
    };
/**
    Decodes AttributeUpdate messages into an EnvironmentalStateRepository object.
    @class EnvironmentalStateDecoder
    @constructor
    @augments StateDecoder
    @param {WebLVCConnection} webLVCConnection Connection to a WebLVC server
    **/
    mak.EnvironmentalStateDecoder = function(webLVCConnection) {
        mak.StateDecoder.apply(this, arguments);
    };

    mak.EnvironmentalStateDecoder.prototype = Object.create(mak.StateDecoder.prototype, {
        constructor : { value : mak.EnvironmentalStateDecoder },

        /**
        Decodes a AttributeUpdate message into an EntityStateRepository object.
        @method decode
        @param {Object} attributeUpdate WebLVC AttributeUpdate message
        @param {EntityStateRepository} stateRep State repository to be updated
        **/
        decode : {
            value : function( attributeUpdate, stateRep ) {

                // if(this.webLVCConnection.timeStampType == mak.TimeStampType.TimeStampAbsolute &&
                    // attributeUpdate.TimeStampType == mak.TimeStampType.TimeStampAbsolute) {
                // } else {
                    // stateRep.timeStampType = mak.TimeStampType.TimeStampRelative;
                // }
                stateRep.timeStampType = mak.TimeStampType.TimeStampRelative;

                var curTime = 0.0;
                // if (stateRep->timeStampType() == DtTimeStampAbsolute)
                // {
                // // Use timestamp as time of validity
                // curTime = pdu.guessTimeValid(myExConn->clock()->simTime());
                // }
                // else
                // {
                // // Use receive time as time of validity
                // curTime = myExConn->clock()->simTime();       
                // }
                curTime = this.webLVCConnection.clock.simTime;

                 if(attributeUpdate.ProcessIdentifier != undefined) { 
                    stateRep.entityIdentifier = attributeUpdate.EntityIdentifier;
                }
                if(attributeUpdate.Type != undefined) { 
                    stateRep.entityType = attributeUpdate.Type;
                }
                if(attributeUpdate.ObjectName != undefined) { 
                    stateRep.objectName = attributeUpdate.ObjectName;
                }
                if(attributeUpdate.GeometryRecords != undefined) {
                    stateRep.GeometryRecords = attributeUpdate.GeometryRecords;
                }
                if(attributeUpdate.EnvObjData != undefined) {
                   if(attributeUpdate.EnvObjData.VrfObjName != undefined) {
                      stateRep.marking = attributeUpdate.EnvObjData.VrfObjName;
                   }
                }
            }
        }           
    });
.....

} (this.mak = this.mak || {}));

ОБНОВИТЬ

Я использовал модульное решение ES6 от Estus (ниже), которое мне действительно нравится. Это решило проблему с накопительным пакетом, но все еще есть ошибка времени выполнения.

Но есть еще кое-что, что нужно сделать. Я получаю эту ошибку с Chrome. У меня есть два варианта файла HTML main.html, один использует пакет, а другой просто импортирует мои модули es6. Ошибка возникает, даже когда я не использую накопительный пакет, а создаю и использую пакет.

Uncaught TypeError: Cannot set property objectName of [object Object] which has only a getter
    at mak$1.ReflectedEntity.mak$1.ReflectedObject [as constructor] (vrlink.mjs:818)
    at new mak$1.ReflectedEntity (vrlink.mjs:903)
    at mak$1.ReflectedEntityList.value (vrlink.mjs:1358)
    at mak$1.WebLVCMessageCallbackManager.<anonymous> (vrlink.mjs:1155)
    at mak$1.WebLVCMessageCallbackManager.processMessage (vrlink.mjs:1745)
    at mak$1.WebLVCConnection.drainInput (vrlink.mjs:2139)
    at SimLink.tick (SimLink.js:34)

Это кажется нарушителем при переходе с модулей IIFE на ES6. Это говорит о том, что нет сеттера.

Код не мое творение, но казалось, что это не должно быть серьезным усилием для преобразования IIFE в ES6. Оскорбительный фрагмент:

mak.VrfBackendStateRepository = function (objectName) {

/**
Unique string identifying entity
@property objectName 
@type String
**/
this.objectName = objectName;   //error generated on this line!

Если вам интересно, что это такое, это объект с именем mak.webLVConnection, который создается этой функцией в коде IIFE:

/**
    Represents a connection to a WebLVC server.
    clientName and port are required.  webLVCVersion is optional (current version
    supported by the WebLVC server will be in effect).  serverLocation is optional
    ( websocket connection will be made to the host servering the javascript )
    @class WebLVCConnection 
    @constructor
    @param {String} clientName String representing name of the client federate
    @param {Number} port Websocket port number
    @param {Number} webLVCVersion WebLVC version number
    @param {String} serverLocation Hostname of websocket server
    **/
mak.WebLVCConnection = function (clientName, port, webLVCVersion, serverLocation, url) {

    var self = this;

    if (clientName == undefined) {
        throw new Error("clientName not specified");
    }
    if (!(typeof clientName == "string" && clientName.length > 0)) {
        throw new Error("Invalid ClientName specified");
    }
    if (port == undefined) {
        throw new Error("Port not specified");
    }
    if (url == undefined) {
        url = "/ws";
    }

    var websocket;
    if (serverLocation == undefined) {
        if (location.hostname) {
            websocket = new WebSocket("ws://" + location.hostname + ":" + port + url);
        }
        else {
            websocket = new WebSocket("ws://localhost:" + port + "/ws");
        }
    }
    else {
        websocket = new WebSocket("ws://" + serverLocation + ":" + port + url);
    }

    /**
    Websocket connected to a WebLVC server.
    @property websocket
    @type WebSocket
    **/
    this.websocket = websocket;

    /**
    DIS/RPR-style identifier, used to generate new unique IDs for entities simulated
    through this connection.   Array of 3 numbers [site ID, host ID, entity number].
    @property currentId
    @type Array
    **/
    this.currentId = [1, 1, 0];

    /**
    Manages registration and invoking of message callbacks.
    @property webLVCMessageCallbackManager
    @type WebLVCMessageCallbackManager
    **/
    this.webLVCMessageCallbackManager = new mak.WebLVCMessageCallbackManager();

    /**
    Simulation clock
    @property clock
    @type Clock
    **/
    this.clock = new mak.Clock();

    /**
    Indicates whether timestamping is relative or absolute
    (mak.TimeStampType.TimeStampRelative or 
    mak.TimeStampType.TimeStampAbsolute).
    @property {Number} timeStampType
    **/
    this.timeStampType = mak.TimeStampType.TimeStampRelative;

    /**
    List of incoming messages.  When messages are received, they are placed
    in this queue.  The drainInput() member function must be called regularly
    to remove and process messages in this queue.
    @property {Array} messageQueue
    **/
    this.messageQueue = new Array();

    /**
    Callback function invoked on receipt of a message.  Calls 
    webLVCMessageCallbackManager.processMessage().
    @method processMessage
    @private
    **/
    this.processMessage = this.webLVCMessageCallbackManager.processMessage.bind(this.webLVCMessageCallbackManager);

    /**
    Callback function invoked when websocket connection is opened.  Sends
    the initial WebLVC connect message.
    @method onopen
    @private
    **/
    this.websocket.onopen = function () {
        var connectMessage = {
            MessageKind: mak.MessageKindEnum.Connect,
            ClientName: clientName
        }

        if (webLVCVersion != undefined) {
            connectMessage.WebLVCVersion = webLVCVersion;
        }

        if (self.websocket.readyState == 1) {
            self.websocket.send(JSON.stringify(connectMessage));
        }
    };

    /**
    Callback function invoked when a WebLVC message is received.  Parses the
    the JSON message data and passes the resulting object to processMessage.
    @method onmessage
    @event {Object} JSON message
    @private
    **/
    this.websocket.onmessage = function (event) {
        //just in case
        if (event.data == "ping")
            return;

        var message = JSON.parse(event.data);
        if (message != null) {
            self.messageQueue.push(message);
        } else {
            console.warn("onmessage - null message received");
        }
    };

    /**
    Callback function invoked when the websocket is closed.
    @method onclose
    @private
    **/
    this.websocket.onclose = function () {
        console.debug("In websocket.onclose");
    };

    /**
    Callback function invoked when an error in the websocket is detected.
    Sends warning to console.
    @method onerror
    @private
    **/
    this.websocket.onerror = function () {
        console.log("websocket onerror");
    };

    this.isOk = function () {
        return this.websocket.readyState == 1;
    }
};

mak.WebLVCConnection.prototype = {

    constructor: mak.WebLVCConnection,

    /**
    Set the DIS/RPR-style application ID.
    @method set applicationId
    @param {Array} applicationId Array of 2 integers [site ID, host ID].
    **/
    set applicationId(applicationId) {
        this.currentId[0] = applicationId[0];
        this.currentId[1] = applicationId[1];
        this.currentId[2] = 0;
    },

    /**
    Returns next available DIS/RPR-style entity ID.
    @method nextId
    @return {Array} Array of 3 integers [site ID, host ID, entity number].
    **/
    get nextId() {
        this.currentId[2]++;
        return this.currentId;
    },

    /**
    Register callback function for a given kind of message.
    @method addMessageCallback
    @param {Number} messageKind WebLVC MessageKind
    @param callback Function to be invoked
    **/
    addMessageCallback: function (messageKind, callback) {
        this.webLVCMessageCallbackManager.addMessageCallback(messageKind, callback);
    },

    /**
    De-register callback function for a given kind of message.
    @method removeMessageCallback
    @param messageKind WebLVC MessageKind
    @param callback Function to be invoked
    **/
    removeMessageCallback: function (messageKind, callback) {
        this.webLVCMessageCallbackManager.removeMessageCallback(messageKind, callback);
    },

    /**
    Send a WebLVC message to the server.
    @method send
    @param {Object} message
    **/
    send: function (message) {
        try {
            if (this.websocket.readyState == 1) {
                this.websocket.send(JSON.stringify(message));
            }
        } catch (exception) {
            console.log("Error sending on websocket - exception: " + exception);
        }
    },

    /**
    Send a time-stamped WebLVC message to the server.
    @method sendStamped
    @param {Object} message
    **/
    sendStamped: function (message) {
        // Timestamp is hex string
        var timeStamp = this.currentTimeForStamping().toString(16);
        //message.TimeStamp = ""; // timeStamp;

        this.send(message);
    },

    /**
    Get the current simulation time for a time stamp.
    @method currentTimeForStamping
    @return {Number} Simulation time in seconds.
    **/
    currentTimeForStamping: function () {
        if (this.timeStampType == mak.TimeStampType.TimeStampAbsolute) {
            return this.clock.simTime();
        }
        else {
            return this.clock.absRealTime();
        }
    },

    /**
    Iterate through message queue, calling processMessage() and then
    removing each message.  Should be called regularly from your 
    application.
    @method drainInput
    **/
    drainInput: function () {
        var message;

        while (this.messageQueue.length > 0) {
            message = this.messageQueue.shift();
            this.processMessage(message);
        }
    },

    /**
    Closes the websocket connection.  Calls the destroy method on its 
    WebLVCMessageCallbackManager data member.
    @method destroy
    **/
    destroy: function () {
        console.debug("In WebLVCConnection.destroy");
        this.webLVCMessageCallbackManager.destroy();
        this.websocket.close();
    }
};

2 ответа

Модули UMD по определению являются CommonJS. Код выше только IIFE и опирается на mak Глобальный.

Функцию-обертку IIFE можно заменить на экспорт по умолчанию или на имя модуля ES:

const mak = {};

mak.MessageKindEnum = { ... };
...

export default mak;

Или с экспортом CommonJS:

const mak = {};

mak.MessageKindEnum = { ... };
...

module.exports = mak;

Ты пробовал:

(function (mak) {
  ...
}(module.exports));

// instead of 
// } (this.mak = this.mak || {}));
Другие вопросы по тегам