Getting rid of globals completely in 1.3

I’m starting this thread for people to post questions about the need for globals in Meteor 1.3. I’ve come across a couple scenarios where the need for globals still seems to be present.

I’ll kick it off with calling a cordova plugin. It is usually prefixed with cordova.nameOrFunctionOfPlugin. I tried doing import {cordova} from 'meteor/cordova' however this is unsuccessful. So how would one import a cordova plugin? Other cordova plugins such as this one reference a different name (in this case, Keyboard). I’m not sure how to proceed here.

update: StatusBar is another scenario where I couldn’t find a way to import.

@martijnwalraven curious what your thoughts are here!

I don’t think there is a good way to avoid globals with Cordova plugins. One of the ideas behind these plugins is that they try to replicate browser APIs as much as possible. The camera plugin defines a global object for instance.

Cordova plugins actually use a custom AMD-like module system, but this is mostly an implementation detail. Plugins define globals by specifying a namespace to clobber or merge exports into in their plugin.xml (see the docs for more information).

1 Like

The downside to globals is it makes an application harder to secure. If things are available on window or any child object of window, then 3rd party scripts can read or modify those things (assuming they aren’t frozen or sealed, and probably could break functionality if they were).

I’ve been experimenting with freezing window and creating all objects inside a self-executing function (never attaching them to anything outside the scope of that function). This can prevent browser extensions from accessing things you don’t want them to access unless you explicitly make something available for them (f.e. exports that can be required with the require function placed on window before freezing it).

I haven’t tried this with Meteor apps yet, but it would be nice to. I’m not sure if Meteor 1.3 core relies on globals at all, but it’d be nice if it relied entirely on modules (if it doesn’t already) to import everything it uses, so the only global Meteor adds and uses would be require. When anything is attached to global while frozen, those lines will fail silently or throw a TypeError in certain cases not limited to strict mode, so Meteor could wrap those lines with try-catch.

Someone like me who wants to freeze the global could modify the package that puts require on the global (modules I believe) to have it freeze the global once require has been added. require would be the only thing added to global, and all other things would fail, but Meteor would continue to work if it relies solely on require for obtaining any other API it may ever use, and all app code should also work if it also relies solely on require and not globals (or import if using ecmascript for ES2015 syntax). Simply putting only require on the global (nothing else) but not freezing the global would allow another script to monkey-patch require to gain access to everything that require ever returns.

This could also be a problem for cordova.

I’d really like to try this with Meteor.

I haven’t played with freezing the DOM, but that’s also something I’d like to play with. Even if freezing DOM is possible, the problem is it is still globally readable, so I’m not sure how much benefit we’d get from freezing it. Browser plugins would still be able to glean information like bank account numbers, user balances, etc, from the DOM.

A possible solution to DOM readability could be to grab all the methods off of document that are used for accessing the DOM, then removing them from document, all prior to freezing window. We would do this inside the self-executing module of our app. We would also have to null out jQuery after importing that into our app, so that a 3rd party script would get null when importing jQuery (or any other libraries that may touch DOM (React, etc)). I can’t wait to try this…