JavaScript, ES6, Global Scope, and An Explicit Dependency Tree
Hey, I brought this up with @lbennett in MR !5676 but it seems more appropriate for its own thread.
A new policy was introduced or proposed for inserting classes into the global scope via the gl
global variable. In the case of user.js it would mean doing something like:
(gl => {
class User {
//...
}
gl.User;
})(window.gl)
and then referencing it in other classes like so:
let user = new gl.User();
I was wondering about the feasibility of doing away with the "transpile-then-concatinate-all-scripts" approach to compiling the front end scripts and adopt a polyfill for es6 dependency handling (compiled into something like CommonJS).
The syntax would then look like this:
export default class User {
//...
}
and it could be referenced with
import User from 'user.js'
let user = new User();
This has several benefits:
- Global scope pollution is made harder and we don't have to wrap every file in an anonymous function to isolate its variables.
- Dependencies are explicit. If you want to find out what code is instantiating the
User
class, just look at the import statements, and if you are refactoring a script which references functions or classes in another script, it is easy to figure out where it is defined. - If in the future we ever decide to split the gargantuan 1Mb single-file javascript into multiple scripts targeted to particular pages or actions, it will be much easier to navigate the spider web of dependencies between all of the scripts.
- Correct me if I'm wrong but I believe by compiling the scripts together this way, uglifying, minimizing, and "tree shaking" the scripts can also be done more intelligently since more is known about the relationships between files and classes, leading to a smaller footprint.
- This may be purely subjective, but I believe it looks far cleaner and more readable this way.
Potential pitfalls.
- Given the heavy reliance on jQuery some of its plugins which plug into the global scope, some hacky workarounds may be needed to fit them into this new paradigm.
- I'm not sure how this would affect the way testing is currently done.
Any thoughts?
(related issue: #19713 (closed))