Run tests in production and development modes #29
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Note: This PR started off as an investigation into why a test I wrote against tracked properties and frozen objects wasn't failing, and metastasized from there. 😂
It is very common for JavaScript libraries to have two "modes": one that developers can run locally to get better error messages or other helpful feedback, and another mode where assertions and other non-critical code with runtime overhead is stripped out to provide the best performance for users.
Both the Glimmer VM and Glimmer.js conceptually have a "development" mode and a "production" mode. Perhaps the most notable example of the difference between development mode and production mode in Glimmer.js is what happens with tracked properties. In development mode, we install a getter even on properties that are not marked as tracked, so we can emit a helpful error if a developer inadvertently mutates that property and expects the DOM to update. Because of the non-trivial runtime cost of installing a setter on every property of every object that passes through a template, we strip this functionality in production mode.
To do this stripping, we use a pattern that looks like this:
In
@glimmer/env
,DEBUG
is aconst
boolean, so bundlers like Rollup will transform the above code into something like this:When that goes through a minifier like Uglify, the minifier will notice the conditional contains a constant boolean and the entire conditional branch will be stripped out (in this case, leaving an empty file).
Which brings us to this PR. This PR addresses several issues with the current build/test setup:
babel-plugin-debug-macros
plugin to statically replace imports from@glimmer/env
with literal boolean values based on the current environment.@glimmer/env
on npm, whereDEBUG
is alwaysfalse
.@glimmer/env
and@glimmer/local-debug-flags
, which appear to have quite a bit of overlap.@glimmer/local-debug-flags
, which was unused.@glimmer/local-debug-flags
instead of@glimmer/env
. This "bug" was actually beneficial, because without it we actually would not have produced any build artifacts that contained the development mode assertions!@glimmer/local-debug-flags
entirely. The Babel plugin is now configured to rewrite imports from@glimmer/env
, allowing us to toggle when they are enabled or disabled as intended.@glimmer/application-pipeline
) to keep dev-mode assertions during development but strip them in production builds.@glimmer/env
having debug flags set toconst
false
values. As described above, building with better bundlers like Rollup and passing through a minifier will produce the optimized build "automatically."test
command to run tests in both production and development modes.