-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JS compatibility mode option #1206
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1206 +/- ##
==========================================
+ Coverage 75.31% 75.34% +0.02%
==========================================
Files 147 148 +1
Lines 10711 10763 +52
==========================================
+ Hits 8067 8109 +42
- Misses 2180 2189 +9
- Partials 464 465 +1
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely add tests that some code works in es51
and that some code doesn't work in es51
but works in es6
I was going to try to look in how to hack around the configuration problems, but got a headache ... so, maybe on a future review will try again :). Hopefully @na-- suggests something without getting a headache as well
js/bundle.go
Outdated
compiler, err := compiler.New() | ||
compatMode := compiler.CompatibilityModeES6 | ||
if rtOpts.CompatibilityMode.Valid { | ||
if cm, err := lib.ValidateCompatibilityMode(rtOpts.CompatibilityMode.String); err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also actually not disabling core.js yet 😄: Will fix/test. |
So it turns out not to be trivial implementing tests for this. The current failures are because essentially (You can confirm it's because of this since they pass in isolation: The problem with this is that up until now we haven't had the need for I tried setting Let me know what you think is the best way to proceed here. I think passing the compatibility mode also to |
Resolves: - #1206 (comment) - #1206 (comment) - #1206 (comment)
So this required a substantial refactoring of The change was to make a new I think this abstracts nicely the parts that need to remain a singleton (the Babel Goja VM and the Babel object itself), while allowing reuse of Let me know what you think, and if the configuration/validation can be improved in this PR (how?) or if it can wait for #883. Also if more tests should be added or if these baseline ones are enough. (I should probably add core.js tests...) |
@@ -114,14 +102,14 @@ func TestCompile(t *testing.T) { | |||
|
|||
t.Run("Invalid", func(t *testing.T) { | |||
src := `1+(function() { return 2; )()` | |||
_, _, err := c.Compile(src, "script.js", "", "", true) | |||
_, _, err := c.Compile(src, "script.js", "", "", true, CompatibilityModeES6) | |||
assert.IsType(t, &goja.Exception{}, err) | |||
assert.Contains(t, err.Error(), `SyntaxError: script.js: Unexpected token (1:26) | |||
> 1 | 1+(function() { return 2; )()`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was lying, well, still is. :) It's part of the "ES5" suite, yet this error is returned by Babel, not Goja (which returns a less descriptive script.js: Line 1:27 Unexpected token ) (and 2 more errors)
).
Should I just update the assert to reflect that? Right now I'm passing CompatibilityModeExtended
to make it pass.
To continue our discussion from last Friday re: Compiler, I did an experimental redesign of what I meant by wanting for Compiler to also compile core.js. Take a look at 4e52c78 (it's built on this branch). There's a few reasons I think this design is better:
Initially I wanted to modify the main goja.Program or ast.Program (and avoid the additional Let me know if you think this is an improvement or not, and if so, if it should be part of this PR or left for after |
bae2ae2
to
d1bacb2
Compare
Resolves: #1206 (comment) In order to be able to create a new test Bundle from both a filesystem *and* custom RuntimeOptions, this required some DRYing of the `getSimpleBundle*` test helper functions.
Resolves: #1206 (comment) In order to be able to create a new test Bundle from both a filesystem *and* custom RuntimeOptions, this required some DRYing of the `getSimpleBundle*` test helper functions.
13a68a0
to
9393a87
Compare
Resolves: #1206 (comment) In order to be able to create a new test Bundle from both a filesystem *and* custom RuntimeOptions, this required some DRYing of the `getSimpleBundle*` test helper functions.
9393a87
to
6953436
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong PR 🤦♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Partially implements #1049. This required a substantial refactor of `compiler.go`, mostly in order to be able to test a compiler with different compatibility mode values during the same test run, which was problematic since `compiler.Compiler` was a singleton. So the solution is to instead make a new `babel` struct the singleton, which encapsulates everything needed for Babel to run, while allowing several `Compiler` instances to exist. In the author's humble opinion, this has the added benefit of being a cleaner design (which was further experimentally expanded in 4e52c78).
Resolves: #1206 (comment) In order to be able to create a new test Bundle from both a filesystem *and* custom RuntimeOptions, this required some DRYing of the `getSimpleBundle*` test helper functions.
The errors actually come from NewBundle, and this is already tested in `TestNewBundle/CompatibilityModeBase`. Resolves: https://github.com/loadimpact/k6/pull/1206/files#r339089482
This ensures old archives that don't contain the "compatibilityMode" key in metadata.json will run with assumed "extended" JS compatibility.
6953436
to
3cd1799
Compare
|
||
// RuntimeOptions are settings passed onto the goja JS runtime | ||
type RuntimeOptions struct { | ||
// Whether to pass the actual system environment variables to the JS runtime | ||
IncludeSystemEnvVars null.Bool `json:"includeSystemEnvVars" envconfig:"K6_INCLUDE_SYSTEM_ENV_VARS"` | ||
|
||
// JS compatibility mode: "extended" (Goja+Babel+core.js) or "base" (plain Goja) | ||
CompatibilityMode null.String `json:"compatibilityMode"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a nit to fix in the future (i.e. #883), I'm wondering if the actual CompatibilityMode
type shouldn't be defined somewhere low-level (i.e. lib
or wherever we decide to put these foundational types) and then instead of using a string
here, we could just use that type (or some null-able wrapper of it).
Because right now, the stringy type here isn't very convenient. Even though it has been validated before we ever use it, we kind of have to cast it to the actual type if we ever want to use it, and then deal with the error that's never going to come...
Closes: #1049
This adds a new CLI
run --compatibility-mode
flag andK6_COMPATIBILITY_MODE
environment variable whose values can be:I used the following test script to test ES 5.1 runs:
I didn't do any performance comparisons, but those are summed up nicely in #1167.