New Meteor apps have the following meteor.testModule in their package.json
files by default
"meteor": {
"testModule": "tests/main.js"
}
When meteor.testModule is defined, it determines the test entry point when
running the `meteor test` command, ignoring legacy file naming conventions
like *.tests.js or *.app-tests.js.
The package-source.js code changed by this commit was incorrect because it
ignored those specially-named test files even when running tests, which
was a problem if the meteor.testModule tried to import them explicitly,
because they would not be properly compiled.
If you're using meteor.testModule, the distinction between `meteor test`
and `meteor test --full-app` matters a bit less, since the test entry
point will be the same for both modes, though you can still check
Meteor.isTest and Meteor.isAppTest at runtime to control test behavior.
For some reason, without all three of these environment variables set
(LANG, LC_ALL, and LANGUAGE), the STDOUT returned from the child process
in findMongoPids contained ?? in place of non-ASCII unicode characters,
which was causing the self-test of Mongo shell in a unicode application
directory to fail.
This implementation defaults all three environment variables to
process.env.LANG if it was defined, or "en_US.UTF-8" otherwise.
Hashes have a number of overlapping but not entirely redundant or
equivalent purposes within the build system.
Hashes of source code are important because they can be computed before
compilation and processing, and thus are useful as keys for caching that
expensive work. Source hashes remain useful even after compilation, as a
way of reflecting the contributions of source-code-sensitive assets like
source maps.
However, source hashes do not tell the whole story, and using them as
cache keys can be risky if the work that's being cached depends on
generated code rather than source code, as we recently discovered with the
findImportedModuleIdentifiers function. The preliminary fix for that
problem (#10330) was to cache findImportedModuleIdentifiers using a hash
of the generated code rather than the source hash.
PR #10330 swung a bit too far in the direction of ignoring source hashes
and considering only hashes of generated code. For example, the URLs of
source maps share the hash of the corresponding resource, but source maps
can change (because of superficial changes in the source code) without
changing the generated code of the resource. Ignoring the source hash when
computing source map URLs resulted in stale source maps with incorrect
line numbers.
A better solution seems to be to propagate the source hash (along with any
hashes of intermediate generated artifacts) all the way through bundling,
so that the final hash of any static resource reflects all information
that could/should change the behavior of that static resource, including
its source map, which embeds the exact source code of all contributing
files in the sourcesContent property. At every step of the way, we merge
all the input hashes into a single hash, so we don't have to keep juggling
multiple hashes, thankfully.
Sub-Resource Integrity (SRI) hashes still need to be computed from just
the final contents of a given asset, so that the browser can verify those
contents without knowing anything about the Meteor build system, but
that's handled separately.
With the introduction of lazy compilation in Meteor 1.8, calling
inputFile.addJavaScript({
...
hash: inputFile.getSourceHash(),
...
}, function () {
return compiler.processFilesForTarget(inputFile);
});
becomes problematic, since inputFile.getSourceHash() is usually different
from compiler.processFilesForTarget(inputFile).hash, because the latter is
computed from the compiled code, whereas the former is computed from the
source code.
For example, when we use file.hash to cache imported module identifiers in
ImportScanner#_findImportedModuleIdentifiers, we really need to be using
the hash of the compiled code, since a single source module can be
compiled in different ways. If we cache based on the source hash, there's
a risk of reusing the scanned imports from the web.browser version for the
web.browser.legacy version, which can lead to all sorts of problems that
are only apparent in legacy browsers.
The quick fix is easy enough: BabelCompiler can simply stop including a
hash in the eager options to inputFile.addJavaScript. This fix can be
published as a minor update to the babel-compiler and ecmascript packages.
The remaining changes in this commit add another layer of defense against
this problem, by ignoring any hash options provided by compiler plugins,
in favor of simply computing the hash from the compiled data buffer.
These additional changes will become available in the next release of
Meteor (likely 1.8.1).
Whenever you're looking at a stack trace generated by the command-line
tool, you see tons and tons of useless stack frames for withValue,
enterJob, and/or capture.
Each of these function calls has its own try-finally block, which is
probably the real reason this pattern is slow, though the excess of
unnecessary stack frames is subjectively gross as well.
Initial build times for the `meteor create --full` app on my machine are
about 4.4 seconds with Meteor 1.8, and just 2.8 seconds after this change,
which is a nice 36% improvement. Rebuild times are not noticeably
different, however.
Looking to the future, flattening this function call pyramid should make
it easier to introduce non-Fiber-based async/await into the buildmessage
system, so that we can start properly propagating promises up the stack.
Should resolve#10233, reported by @klaussner.
Previously, if a compiler plugin called inputFile.addJavaScript multiple
times with different { path } strings, Meteor would allow importing all of
those modules at once by importing the original source module identifier,
by synthesizing a new source module containing a series of re-exports for
each of the generated modules.
Preserving this behavior is important for backwards compatibility, since
some compiler plugins still generate files like "module.ext.js" given an
input file named "module.ext", so Meteor tries to make those modules
interchangeable/synonymous.
However, if the compiler plugin explicitly calls inputFile.addJavaScript
with the original source path, then it would be a mistake to modify the
contents of that module, so Meteor will now leave the contents of that
explicit source module unmodified, rather than using it as a catch-all way
to import other generated modules.
This change dramatically reduces the number of attempted files.stat calls
during module resolution, especially for apps that use a large number of
compiler plugins, and thus have many different file extensions to try.
Follow-up to af51b816, which fixed#8005 by copying symlinks to external
directories as directories rather than trying to preserve the symlinks.
Issue #10177 revealed a flaw in this strategy: the filter function that we
use to strip development npm packages always rejects external paths, even
if the original symlink was found in a valid production npm package, and
thus its contents should be included in the production bundle.
In the process of fixing this problem, I realized that the only important
part of af51b816 was this code:
// Update fileStatus to match the actual file rather than the
// symbolic link, thus forcing the file to be copied below.
fileStatus = optimisticLStatOrNull(externalPath);
and the code for manipulating thisAbsFrom and _currentRealRootDirectory
could be removed.
Fixes several cases causing cordova plugins reinstall on every build:
- proper handling of scoped npm cordova plugins
- proper detection of plugin removal (previously a cordova plugin containing a dependency would make the algorithm think a package was removed from cordova-plugins)
- proper handling of plugins which have plugin.xml id different than the npm package name
Additionally rechecks the build integrity verifying if packages were really installed and perform a retry if needed.
Allows to override a meteor package cordova dependency with scoped package i.e. @scope/cordova-dummy-plugin will now override a cordova-dummy-plugin dependency.
This should make the @babel/runtime dependency that I added to the
compile-coffeescript plugin in a52a2c28f1
actually work as intended.
Specifically, the babel-runtime package that's bundled into the
compile-coffeescript plugin will now be able to import @babel/runtime and
receive the plugin's private version of @babel/runtime, rather than the
one in dev_bundle/lib/node_modules or the application's node_modules.
cc @hwillson @abernix