-
Notifications
You must be signed in to change notification settings - Fork 185
Implement SystemLoader constructor #209
Conversation
This adds a SystemLoader constructor function used internally to inherit from Loader. `System` then becomes an instance of SystemLoader and `SystemLoader` is set as `System.constructor`. This way downstream code can do something like: ```js class MyLoader extends System.constructor { fetch() { } } ``` And doing so will have access to `super` and the like. I also added in `esnext` to build this and use es6 classes. We talked about doing it this way and it is *much* more elegant in my opinion (just look at the minimal amount of code changes). Let me know if this adds too much code or you don't like it for some reason and I'll implement this as regular old constructor functions, but I thought this turned out really well. Fixes ModuleLoader#199
class SystemLoader extends Loader { | ||
|
||
constructor() { | ||
super(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need to call super
against this
?
It may be worth still keeping constructor(options)
and then running super(options)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, you're right, I'll update this.
This is great! Works out really elegantly yes and very happy with it. Perhaps lets rename |
I think we can keep |
Sounds great. |
This updates with all of the changes recommended. To summarize: * Using a string-replace grunt plugin to insert polyfills where needed for the various Object.* methods being used by esnext. Verified to work in IE9 (don't have an IE8 VM on this machine). * Constructor now calls `super(options || {})` * Removed unnecessary `System.constructor =` assignment * Replaced tests and Node references to use `dist/es6-module-loader.js` * instead. Part of ModuleLoader#209
This updates with all of the changes recommended. To summarize: * Using a string-replace grunt plugin to insert polyfills where needed for the various Object.* methods being used by esnext. Verified to work in IE9 (don't have an IE8 VM on this machine). * Constructor now calls `super(options || {})` * Removed unnecessary `System.constructor =` assignment * Replaced tests and Node references to use `dist/es6-module-loader.js` * instead. Part of ModuleLoader#209
01f2253
to
2e79b2d
Compare
Hey @guybedford , I think i've accounted for all of your questions, but please do review thoroughly again. Here are the tests passing in IE9 (don't have an IE8 available): |
@guybedford I still don't love the way I'm patching the Object.* functions. I think it would be better to actually polyfill the Object.* functions themselves. I don't know how you feel about adding more polyfills though. The advantage is that we could stick these in the top of Let me know if that sounds good to you and I'll make the change. Then we could eliminate the |
}; | ||
$__Object$defineProperty = (function () { | ||
try { | ||
if (!!Object.defineProperty({}, 'a', {})) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do this in the outer function - otherwise the try - catch
is going to deoptimize the defineProperty function everytime it is called. Note we should still wrap it in a function closure so the try - catch
doesn't deoptimize the whole script.
I'd prefer not to polyfill Will do the IE8 testing myself no problem... happy to go with it with the last perf adjustment. |
There is actually a |
That won't work, that |
Ah right... it may be worth doing... or is that too many closures? |
There's no such thing as too many closures ;) I'll get it updated tonight. |
Alright! Since we're not compiling or loading the scripts separately anymore it may be worth sharing the outer closure anyway. For example, |
This refactors the two polyfills to share a single closure that wraps both of them and contains polyfills for a few Object.*. Implementation is that there is now a `polyfill-wrapper-start.js` which has the outer most closure, then the two polyfills (after being compiled), then `polyfill-wrapper-end.js`.
All, I think this gets everything. To summarize:
Does this cover everything? Oh, all tests still pass. |
I just adjusted the wrappers slightly to ensure the eval doesn't get any of the local variables leaked. Thanks so much for this - SystemJS tests are passing against it too which is great. Will be nice to write proper extensions now. |
This adds a SystemLoader constructor function used internally to inherit from Loader.
System
then becomes an instance of SystemLoader andSystemLoader
is set asSystem.constructor
. This way downstream code can do something like:And doing so will have access to
super
and the like.I also added in
esnext
to build this and use es6 classes. We talked about doing it this way and it is much more elegant in my opinion (just look at the minimal amount of code changes).Let me know if this adds too much code or you don't like it for some reason and I'll implement this as regular old constructor functions, but I thought this turned out really well.
One thing to consider is that the tests were pointing directly to
lib/loader.js
andlib/system.js
so I made a built version of each of those go todist/
as well.Review this carefully because the requirements were spread out over various issues and personal discussions.
Fixes #199