Instead of having every message consumer listen to every message and act
on the ones that seem relevant to its interests, we now have a single
process.on("message", callback) hook that can dispatch messages to
different Meteor packages running in the server process.
Receiving packages should export an onMessage function. The onMessage
function may be async, and its result will be delivered back to the build
process as the result of the sendMessage Promise.
This package is already importable because it's a dependency of request,
npm, and http-signature, but it's a good idea to depend on it explicitly
just in case those packages stop depending on it in the future.
Now that we're postponing the legacy build until after the first client
refresh message is sent, there's a risk that changes to the legacy build
will not be picked up until after the next rebuild.
If we attempted to fix that problem by sending the refresh message after
the legacy bundle is rebuilt, then we would lose most of the benefit of
delaying the legacy build, because the client would not refresh until
after the legacy build completed.
The right way to fix the problem is by sending a second client refresh
message after the legacy build finishes, but doing so with the current
autoupdate implementation would very likely cause modern clients to reload
a second time.
The solution implemented by this commit is simple in theory: the
autoupdate package should keep track of distinct versions for each client
architecture, so that modern clients will refresh only when the modern
versions change, and legacy clients will refresh only when the legacy
versions change, which allows us to send two refresh messages without
causing any clients to refresh more than once.
In reality, this was a fairly major rewrite, since the ClientVersions
collection has a totally different schema now. I've tested it as well as I
can, though I'm not entirely sure what will happen if clients using the
previous version of the autoupdate package begin receiving DDP messages
from this version of the autoupdate server code.
This means the autoupdate package is no longer responsible for recomputing
client hashes, and we can recompute the hashes whenever there's a new (or
updated) client program, which enables delayed builds of architectures
like web.browser.legacy (#10055).
Most importantly, we no longer return a copy of previousBuilders from
bundler.bundle, but simply modify the input object over time. The copying
approach was nice in theory, but incompatible with delaying the bundling
of certain architectures (e.g. web.browser.legacy) until some time after
bundler.bundle returns.
Follow-up to https://github.com/meteor/meteor/pull/9933.
As recommended by @abernix, the sha1 hash of every file is now computed
from the file's sha512 hash, so we don't have to hash the entire contents
of the file twice with two different algorithms.
Other changes/improvements:
* Invalidate the hashes when/if `File#setContents` is called.
* Ignore `options.hash` and just compute hashes from actual file contents.
Disagreement here would be worse than any performance benefits from
precomputing the hash.
Because of 8b04c25390, there may now be
multiple calls to meteorInstall in the modules package bundle.
The code for extracting module sizes from the minified bundle previously
assumed there would be only one call to meteorInstall, so this commit
allows for more than one call.
While I was at it, I deleted the simplistic Visitor implementation this
code was using in favor of the more sophisticated Visitor provided by the
reify package, which has the abitlity to skip whole subtrees that do not
contain the identifier(s) we care about.
This may help with lots of issues, most recently #10044 but also #10034, #9976, #9711, and #9568,
to name a few. In particular, since we silently fall back to
`Babel.minify` when `uglify-es` (now `terser`) fails, there should be
fewer problems with `Babel.minify` (parse errors, performance, memory
usage) if `terser` succeeds more often.
Note: because we have bumped the minor versions of `minifier-js` and
`standard-minifier-js`, and they are core packages, you'll have to be
using the next beta version of Meteor 1.7.1 in order to update to these
versions, unless you clone those packages into your local `packages/`
directory. However, if we can validate that `terser` is fully backwards
compatible with `uglify-es`, we might be able to back-port this fix as a
patch update, or publish a Meteor 1.7.0.4 release that permits
`minifier-js@2.4.x`.