This should shave down bundle sizes by 14.4 kb for many non-blaze projects.
The other core meteor packages have not depended on `underscore` since #9362. However, we are only able to remove this last dependency now due to the previous commit, which eliminated usages of `underscore` from apps that did not have the package listed in their `packages` files. This was causing CI test failures that now should be corrected.
Any meteor apps currently using `_` without `underscore` listed in their `packages` file will need to add the package explicitly.
Version number of `meteor-base` bumped from 1.3.0 to 1.4.0.
There are only a few uses of `underscore` in these apps, and two of them actually used `underscore` without having it explicitly listed in their `packages` file.
This is a problem, because the apps were relying on the dependency from `meteor-base`, which we want to remove to cut down bundle sizes.
For the `modules` test app, I've added `underscore` to the `packages` file, because it is using `_` in an assertion about the module system. For the other app and all other uses of `_`, rather than add `underscore` to the `packages` files, I took the modernization route and replaced the functions with their ES6 equivalents, and then removed `underscore` from all `packages` files.
Although it was tempting to avoid including the SockJS library in the
bundle for modern browsers, Meteor 1.6.2 will have a much better way of
managing this kind of differential bundling for modern/legacy browsers
(see PR #9439), and removing SockJS seems to lead to a worse experience
when native WebSockets end up failing, as @jamesmillerburgess discovered:
https://github.com/meteor/meteor/pull/9274#issuecomment-356214405
Now that dynamic-import no longer depends indirectly on ecmascript, the
ecmascript package can finally guarantee support for dynamic `import()`,
as it rightfully should.
Now that es5-shim has no impact on modern browsers (thanks to selectively
server-side rendering a <script> tag for older browsers), there's very
little reason not to use it.
If you really don't want to use it, you can always remove meteor-base and
install your preferred set of base packages.
Supersedes #9316, in which @stubailo demonstrated that SockJS can be
straightforwardly eliminated if native WebSocket support is assumed.
Native WebSocket support is close to universal now (94% of all clients
according to https://caniuse.com/#feat=websockets), which means we can
remove ~30KB of legacy code from the client bundle that we send to most
web browsers.
To achieve this flexibility, the sockjs-0.3.4.js script is injected as a
standalone <script> tag in the <head> of the document, but only if the
user agent string of the HTTP request fails to convince the sockjs-shim
package that the browser has native WebSocket support. When Meteor is
running in production, a minified version of that script is used instead.
Not only is this loading strategy a bit faster for older browsers, because
the SockJS script begins loading earlier, and is independent from the
normal JS bundle, it also removes the cost of loading SockJS completely
for more recent browsers.
Though it's tempting to keep hacking the SockJS script to make it smaller,
we should avoid spending too much time on that, since it only benefits a
small portion of users whose devices are likely to have poor performance
for lots of other reasons. In other words, I think we should keep
[Amdahl's Law](https://en.wikipedia.org/wiki/Amdahl%27s_law) in mind.