Probably the most notable change in this update is that the Reify compiler
now generates
module.link("./child", { ...setters... });
instead of
module.watch(require("./child"), { ...setters... });
for import and export-from declarations.
Thanks to these commits in the Reify project, there's a new runtime module
system method: module.link(id, setters), which replaces the previous (more
cumbersome) module.watch(require(id), setters).
This is more than a cosmetic change, since it will allow creating module
Entry objects before evaluating modules, which will help improve spec
compliance around import cycles and hoisted function declarations.
It's also shorter than the module.watch style, which is always nice.
However, since require(id) no longer appears in the generated code, we
can't just rely on findImportedModuleIdentifiers looking for require
function calls, so the scanner now needs to look for module.link(id, ...)
calls as well.
Because in-place rebuilds are disabled by default on Windows, we were
losing .meteor/local/build/programs/web.browser.legacy every time we
rebuilt .meteor/local/build as part of writeSiteArchive, as reported by
@lmachens in this comment: https://github.com/meteor/meteor/pull/9942#issuecomment-406656741
In-place rewriting of .meteor/local/build seems essential for the new
strategy of writing different targets at different times, though I have
attempted to limit the risk of overwriting open files on Windows by
continuing to build the individual target directories from scratch (that
is, by writing a fresh temporary directory and then renaming it over the
existing directory).
Though I don't have any specific ideas in this direction, it may be worth
noting: if we could find a way to make in-place builds safer on Windows
(as they are on Linux and Mac), Windows rebuilds would be significantly
faster than they are with the current strategy of rewriting everything
from scratch every time.
With the addition of inter-process-messaging npm deps to the cache, but
no change in the shrinkwrap checksum, the cache will not get updated
until we either change any of the shrinkwrap files or change the cache
keys. So I'm bumping the version numbers to do the latter.
The defaultExtensionHandlers[".json"] function in import-scanner.js sets
file.jsonData as a side effect, which is important because that's what the
linker uses to construct a stub module.exports object for dynamically
imported package.json modules.
When I introduced ImportScanner#_readPackageJson as an alternative to
ImportScanner#_readModule in a recent commit, I intentionally did not call
defaultExtensionHandlers[".json"], but in so doing I neglected to preserve
the behavior of setting file.jsonData.
Without a proper package.json stub with at least a "main" property, the
dynamic import() system can't resolve dynamically imported packages until
the full package.json module has been fetched from the server, which leads
to missing module errors in the initial dynamic import().
This hack dates all the way back to 2013: a2c4a78743
Though it is convenient to reload the browser when server files change
while running test-packages, that's not the behavior of most Meteor apps
that use the autoupdate package, and this hack introduced a signficant
difference in behavior between the test-in-browser and test-in-console
driver packages, which finally surfaced due to the interaction between
@toinevk's headless testing PR #9814 and my refactoring of the autoupdate
package (fe9e4035f9). Tests should behave
the same regardless of which driver package is used.
It turns out there's a better way to make the browser reload each time the
server restarts: simply modify Meteor.settings.public, since that object
is included in the client hashes computed by the webapp package.
It seems obvious in hindsight, but any logic relating to the
AUTOUPDATE_VERSION override should reside within the autoupdate package,
and the true client hashes should be available to any other package that
needs them, without AUTOUPDATE_VERSION getting in the way.