Im leaning towards this not being possible, based on all my searching prior to posting this (unless using jquery
Can I use multiple versions of jQuery on the same page?
which i am not) but I figured I would check.
I have come accross a situation where I need one version of socket.io in order for my web application to work, and another version in order to communicate with my python websockets.
Is it possible to use multiple versions of the same js? for instance, one remote, one local:
<script src="/socket.io/socket.io.js" as="ioA"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.6/socket.io.js" as="ioB"></script>
Obviously that itself isnt going to work but I hope it helps illustrate what I want.
If my fear is true that this isnt doable, is there a workaround? Such as containing what I need from the remote one in another js/ejs file, and somehow calling to it from the first page? or will the imports clobber each other.
Apologies if this is a dumb question - haven't come accross this in my limited use of these languages, and can't get a straight answer from my own searches
maybe it would work
<script src="/socket.io/socket.io.js" as="ioA"></script>
<script>
window.antherIO=io;// io refer to the name above.
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.6/socket.io.js" as="ioB"></script>
and the local one maybe like this:
function (f) {
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f()
} else if (typeof define === "function" && define.amd) {
define([], f)
} else {
var g;
if (typeof window !== "undefined") {
g = window
} else if (typeof global !== "undefined") {
g = global
} else if (typeof self !== "undefined") {
g = self
} else {
g = this
}
g.io = f()
}
})(function () {
...
g.io = f()
io set to another name.
Related
I was looking for a javascript implementation of the Astar algorithm that i could steal for my own project, and google immediately led me to bgrins implementation on github:
https://github.com/bgrins/javascript-astar
I copied and pasted his astar.js, and quickly found myself confused on how i was supposed to access the code from my own js module. I took a look at his demo.js file in their repo, and quickly saw that there were no imports. demo.js immediately has access to the astar function as well as the graph object that it takes as a parameter, and i am a little confused by how they managed to accomplish this.
On line 129 of demo.js, they have
this.graph = new Graph(nodes);
without ever using an import statement.
looking closer at the top of astar.js, i see the following code:
(function (definition) {
/* global module, define */
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = definition();
} else if (typeof define === 'function' && define.amd) {
define([], definition);
} else {
var exports = definition();
window.astar = exports.astar;
window.Graph = exports.Graph;
}
})(function () {
Clearly setting window.astar and window.Graph are a part of the answer here, but I find this whole code block a little confusing and very abstract. Can anybody help me to understand what they are doing right here?
We are trying to minify/obfuscate a js library, so that we can reuse it in other projects. Background info: I have done some js, but i'm new with AMD or requireJS.
Here's a reduced version of the library, retaining only the format:
(function (global, factory) {
if ( typeof exports === 'object' && typeof module !== 'undefined'){
factory(exports);
}
else if (typeof define === 'function' && define.amd){
define(['exports'], factory);
}
else{
global['SimpleMath'] = factory({});
}}(typeof global !== "undefined" ? global : self.window || self.global,
(function (exports) {
'use strict';
exports.square = function square(value){
return value * value;
}
exports['square'] = exports.square;
return exports;})));
Inside the main.html we have
requirejs(['./libs/SimpleMath'], function (smath){
console.log(smath);
console.log(require.s.contexts._.defined);
});
This works and we can see the loaded object print out.
Since we wish to optimize/obfuscate the code, we are trying requirejs' optimizer (single js file):
node ../../r.js -o name=SimpleMath out=SimpleMath.min.js baseUrl=.
And we do get something that looks like a minified file.
However, if now I try to load the minified version with the same method:
requirejs(['./libs/SimpleMath.min'], function (smath){
console.log(smath);
console.log(require.s.contexts._.defined);
});
we get 'undefined' for the print out instead.
I can't tell if the original code was wrong, or we are not using the optimizer correctly, or we totally got the concept wrong. Any help or pointers is much appreciated. Thanks in advance.
Answering myself in case someone might find it useful: The minified file was exporting a named module like this
define('SimpleMath',['exports'],t)..
we had to either
load it as a named module with require.config or,
make it anonymous, which seems to be the recommended option for our case.
When I go to the vast majority of websites, open up the console and paste the following code:
(function(global, appName, app) {
if (typeof define === "function" && typeof define.amd === "object") {
console.log("AMD/RequireJS");
define(app);
console.log("defined app");
} else if (typeof module !== "undefined") {
console.log("CommonJS");
module.exports = app(global);
console.log("defined with module.exports");
} else {
console.log("Browser");
global[appName] = app(global);
console.log("defined as global");
}
})(this, "App", function(global) {
"use strict";
console.log("defining getThis");
function getThis() {
console.log('i got it!');
}
return {
getThis: getThis
};
});
console.log("finished IIFE");
App.getThis();
I get the following output:
Browser
defining getThis
defined as global
finished IIFE
i got it!
If I paste that same code into the console of a site that uses RequireJS such as www.bestbuy.com or www.homedepot.com it fails with this output:
AMD/RequireJS
defined app
finished IIFE
Uncaught ReferenceError: App is not defined at <anonymous>:27:1
I've tried changing the line define(app); to define(['App'], app); with no effect.
I have been googling and puttering around with this for hours now and am at my wit's end. I thought the UMD pattern was UNIVERSAL hence its name. What gives?
Well, it all depends on how are you going to use your script. If you know you are going to use your script in a browser without RequireJS, then it is OK the way you are testing it.
App.getThis();
Because it is in the global object, in the case of a browser, window.
But if you know RequireJS is present, then you need to require your app.
require(["App"], function(App){
App.getThis();
});
And if NodeJS
const App = require('App');
But I've not tested this one.
Also, I recommend you to change define(app); by define(appName, app);
Hope it helps
I'm trying to extend my browser-side library's runtime environment to node.js. I implemented the Universal Module Definition (UMD) pattern to do that. It works with AMD implementation and <script> but doesn't work in node.js since there is no window.
The dependencies in question are WebSocket, EventSource, XMLHttpRequest, document. The detail is described in here: https://github.com/flowersinthesand/portal/issues/115 So what is the best approach to resolve window dependency in node.js? I have though the following way to do that. Since I'm new to node.js, these are somewhat unfamiliar and I don't know which way is natural. Though I'm trying to support node.js, I don't want to change too much something.
The following code snippet comes from https://github.com/flowersinthesand/portal/blob/master/portal.js
Using jsdom
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(function() {
// Passes the window
return factory(root);
});
} else if (typeof exports === 'object') {
// Node
module.exports = factory(require('jsdom').something);
} else {
// Browser globals, Window
root.portal = factory(root);
}
}(this, function(window) {
If the jsdom supports the above dependencies well, this looks best. If it works, however, I wonder why client of sockjs, socket.io and engine.io don't use jsdom. Maybe, they are for node rather than browser? performance?
Making window as a plain object of dependency
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(function() {
// Passes the window
return factory(root);
});
} else if (typeof exports === 'object') {
// Node
module.exports = factory({
WebSocket: require('package name for WebSocket').something,
EventSource: require('package name for EventSource').something,
document: require('jsdom').hmm,
// ...
});
} else {
// Browser globals, Window
root.portal = factory(root);
}
}(this, function(window) {
It looks picky and somewhat uncomfortable to make a group of dependency, window, But, I want to preserve current code if possible. Also, jsdom may be required as well to resolve document used to do HTTP request by script tag when XMLHttpRequest can't work due to cross-domain or unloading event and this situation includes IE 6. It's possible to separate logic using document to use something supported in node and script tag in browser checking what the current runtime is, but it's big change for me.
(function(root, factory) {
if (typeof define === "function" && define.amd) {
// AMD
define(function() {
return factory(root);
});
} else if (typeof exports === "object") {
// Node
module.exports = factory(function() {
// Prepare the window powered by jsdom
var window = require("jsdom").jsdom().createWindow();
window.WebSocket = require("ws");
window.EventSource = require("eventsource");
return window;
}());
// node-XMLHttpRequest 1.x conforms XMLHttpRequest Level 1 but can perform a cross-domain request
module.exports.support.corsable = true;
} else {
// Browser globals, Window
root.portal = factory(root);
}
}(this, function(window) {
A WebWorker executes with a scope completely separate from the 'window' context of traditional JavaScript. Is there a standard way for a script to determine if it is, itself, being executed as a WebWorker?
The first 'hack' I can think of would be to detect if there is a 'window' property in the scope of the worker. If absent, this might mean we are executing as a WebWorker.
Additional options would be to detect properties not present in a standard 'window' context. For Chrome 14, this list currently includes:
FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL
Detecting WorkerLocation seems like a viable candidate, but this still feels a bit hackish. Is there a better way?
EDIT: Here is the JSFiddle I used to determine properties present in the executing WebWorker that are now in 'window'.
The spec says:
The DOM APIs (Node objects, Document objects, etc) are not available to workers in this version of this specification.
This suggests checking for the absence of document is a good way to check you're in a worker. Alternatively you could try checking for the presence of WorkerGlobalScope?
Although post a bit old, adding a couple of generic alternatives
What is used in Asynchronous.js library (a library for generic handling of asynchronous/parallel processes, author) is the following:
// other declarations here
,isNode = ("undefined" !== typeof global) && ('[object global]' === Object.prototype.toString.call(global))
// http://nodejs.org/docs/latest/api/all.html#all_cluster
,isNodeProcess = isNode && !!process.env.NODE_UNIQUE_ID
,isWebWorker = !isNode && ('undefined' !== typeof WorkerGlobalScope) && ("function" === typeof importScripts) && (navigator instanceof WorkerNavigator)
,isBrowser = !isNode && !isWebWorker && ("undefined" !== typeof navigator) && ("undefined" !== typeof document)
,isBrowserWindow = isBrowser && !!window.opener
,isAMD = "function" === typeof( define ) && define.amd
,supportsMultiThread = isNode || "function" === typeof Worker
,isThread = isNodeProcess || isWebWorker
// rest declarations here..
This worked for me
if (self.document) {
console.log('We are calculating Primes in Main Thread');
} else {
console.log('We are calculating Primes in Worker Thread');
}
this works for me:
if (self instanceof Window) {
// not in worker
}
There's even more: WorkerNavigator etc.
Unless there's a keyword to detect webworkers, you got to use a variable.
(Nothing can stop a rogue script running before your script from setting or replacing variables. )
So, assuming you do not have any rogue scripts running before your script, any of these lines will work:
this.DedicatedWorkerGlobalScope?this.__proto__ === this.DedicatedWorkerGlobalScope.prototype:false
this.WorkerGlobalScope?this.__proto__.__proto__ === this.WorkerGlobalScope.prototype:false // works for shared workers too
this.constructor === this.DedicatedWorkerGlobalScope //or SharedWorkerGlobalScope
!(this.DedicatedWorkerGlobalScope === undefined)
!(this.DedicatedWorkerGlobalScope === undefined)
You can also use self ยง instead of this, but since this can't be set, its neater.
I prefer:
this.DedicatedWorkerGlobalScope !== undefined
Of course, if you only have worker context and window context, you can do the inverse tests for window context. Eg this.Window === undefined.