Преобразовать модуль 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 || {}));