Vendor jquery and lodash, introduce EventEmitter3 #1193
Conversation
Removes the cdn version of jQuery and adds it to the `globals` pack, which loads jQuery, initialises `window.event` (to replace $.publish and $.subscribe in the future), and loads third party jQuery plugins to the global scope. EventEmitter 3 ============== I'm replacing our jQuery-dependent pub/sub functions for EventEmitter 3. It has no external dependencies and is 1kb minified+gzipped. It's also better alternative that is compatible with the Node.js events API. To register event handlers, use `ee.addEventListener` or `ee.on`. To emit an event, use `ee.emit`. Github: https://github.com/primus/eventemitter3 Node.js Events: https://nodejs.org/api/events.html *Note:* For convenience, `$.publish` wraps `ee.emit` and `$.subscribe` wraps `ee.on`.
31c34b3
to
b4c0f15
Compare
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.
Looks good to me - do you want me to run and test this somehow?
Could you just do us a solid and write a short summary on what's changed - e.g. not using jquery events anymore, using event emitter instead, what's in the global packs
import _ from "lodash"; | ||
import $ from 'jquery'; | ||
import I18n from 'champaign-i18n'; | ||
import Backbone from 'backbone'; |
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.
How come it worked without all these imports?
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 had window.$
loaded via CDN - but we're getting a lot of errors on sentry on jQuery not being present, which was the main reason for this change in how we load jQuery.
$('.shares-editor__existing').on('click', '.share-copy-url', e => { | ||
e.preventDefault(); | ||
}); | ||
$('.shares-editor__existing').on( |
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.
ack, I will need to rebase with your branch
this.model.post(FB, () => { | ||
this.trackEvent("shared"); | ||
this.model.post(window.FB, () => { | ||
this.trackEvent('shared'); |
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.
Are all these single quotations / splitting things into new lines Rubocop changes?
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.
They're prettier which will autoformat on commit.
@@ -61,7 +63,7 @@ const CampaignTile = props => ( | |||
})} | |||
</div> | |||
</div> | |||
<div className="campaign-tile__lead">{props.title}</div> | |||
<div className="cggggampaign-tile__lead">{props.title}</div> |
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.
Did you mean to rename this class so wonky?
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.
😨 me failing at VIM
jquery: 'window.$', | ||
'champaign-i18n': 'window.I18n', | ||
externals: [ | ||
/* Replace any jquery import/require statements for the global `$` object, |
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.
Thanks for this very illustrative comment
* Move recommend_pages.js into the member-facing pack and out of its own pack. Reduces size (boilerplate) and number of requests. Also change initialisation to use events (avoid more globals) * Move event_tracking.js into the member-facing pack and out of its own pack.
💯 |
locale: '{{locale}}', | ||
pageId: "{{ id }}" | ||
}; | ||
mountRecommendPages('recommend-pages-component', data); |
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.
Does this mean we're no longer mounting components by calling a function? we're now emitting an event?
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 think overall this is a cleaner approach that's less error prone, but I've only updated recommend pages for now as the feature is the newest and meant the least effort. Using events we avoid throwing errors in the template that may break the entire page.
I also refactored the RecommendPages
component as it didn't need its own pack (so I've added it to member_facing.js) and it's also less error prone.
Note: PR SumOfUs/sou-assets#58 must be merged before this.
This PR reomves the cdn version of jQuery and instead it adds it to a new "globals" pack, which does the following:
window.$
andwindow.jQuery
.window._
.window.event
;window.$
with two methods:publish
andsubscribe
, to maintain some backwards compatibility with$.publish
and$.subscribe
. These methods use EventEmitter3 internally.There are new rules on how jquery, and lodash are imported: if you're importing the module from within the
app/javascript/vendor
folder, webpack returns the npm module as you would expect, but when you import jquery/lodash from anywhere else, webpack marks them as externals, i.e.window.$
andwindow._
. This ensures that once we've imported jQuery and added it to the global scope, other modules are modifying the same instance (e.g.jquery-sticky
,selectize
, etc). You can see how the webpack module is marked as an external conditionally here: https://github.com/SumOfUs/Champaign/pull/1193/files#diff-d725c81d79986543575ead6053b79a54R18EventEmitter 3
I'm replacing our jQuery-dependent pub/sub functions for EventEmitter 3. It has no external dependencies and is 1kb minified+gzipped. It's also better alternative that is compatible with the Node.js events API.
To register event handlers, use
ee.addEventListener
oree.on
. To emit an event, useee.emit
. For convenience,$.publish
wrapsee.emit
and$.subscribe
wrapsee.on
, so there is some degree of backwards compatibility. Subscribed events using this method can no longer rely on the jQuery event object.Other changes
// @flow [weak]
pragma to most files underapp/javascript/member-facing
andapp/javascript/campaigner-facing
(except for those that would've introduced too many errors). These files were previously not checked so there were no guarantees that we wouldn't introduce errors inadvertently when modifying them.$.publish
and$.subscribe
foree.emit
andee.on
in all JavaScript sources, and uses the globalwindow.event.emit/on
in all template code. Note: there are still pages in production with custom JavaScript code that rely on$.publish/subscribe
, so I've kept both for backwards compatibility, however, they should be ported ASAP. This PR therefore depends on Move from $.subscribe to window.event.on sou-assets#58PD: Although the PR lists 100 files changed, most of them only change a few lines where
$.publish
or$.subscribe
have been updated toee.emit
oree.on
. The more relevant files worth taking a look at when reviewing this PR are listed here:app/javascript/packs/globals.js
app/javascript/shared/pub_sub.js
app/javascript/vendor/{jquery|lodash}.js
config/webpack/custom.js