Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Heitor Tashiro Sergent <heitortsergent@gmail.com>
  • Loading branch information
mstoykov and heitortsergent authored Aug 13, 2024
1 parent f518631 commit 037573d
Showing 1 changed file with 29 additions and 25 deletions.
54 changes: 29 additions & 25 deletions release notes/v0.53.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ k6 `v0.53.0` is here 🎉! This release includes:
- Native ECMAScript modules support
- New experimental OpenTelemetry metrics output
- Blob support in experimental websockets module
- Consolidating cloud features and commands under `k6 cloud`
- Consolidate cloud features and commands under `k6 cloud`
- Breaking change: remove magic URL resolutions

## Breaking changes

### Require is now specification compliant and always resolve based on the file it is written in [#3534](https://github.com/grafana/k6/issues/3534)
### Require is now specification compliant and always resolves based on the file it is written in [#3534](https://github.com/grafana/k6/issues/3534)

`require` in k6 used to resolve identifiers based on the current "root of execution" (more on that later). In a lot of cases that aligns with the file the `require` is written in or a file in the same folder, which leads to the same result. In a small subset of cases, this isn't the case.
The `require` function in k6 used to resolve identifiers based on the current "root of execution" (more on that later). In a lot of cases, that aligns with the file the `require` is written in or a file in the same folder, which leads to the same result. In a small subset of cases, this isn't the case.

Every other implementation and more or less by the CommonJS specification - require should always be relative to the file it is written in.
In every other implementation, and more or less by the CommonJS specification, `require` should always be relative to the file it is written in.

This also aligns with how ESM and dynamic `import` also work. In order to align with them `require` now uses the same underlying implementation.

Expand All @@ -23,7 +23,7 @@ There was a warning message for the last 2 releases trying to tease out cases wh

This is very much an implementation detail that has leaked and likely a not intended one.

Whenever a file is `require`-ed it become the "root of execution" and both `require` and `open` become relative to it. Once the `require` finishes, the previous "root of execution" gets restored. During not init context execution, the main file is the "root of execution".
Whenever a file is `require`-ed it becomes the "root of execution", and both `require` and `open` become relative to it. Once the `require` finishes, the previous "root of execution" gets restored. During the `init` context execution, the main file is the "root of execution".

Example:

Expand Down Expand Up @@ -51,11 +51,11 @@ In this example when `require` is called in `/A/a.js` the `main.js` is once agai

</details>

You might want to use the newly added `import.meta.resolve()` if you want to create a path that is relevant to the currently calling module. This will let you call it outside a helper class and provide the path to it.
You can use the newly added `import.meta.resolve()` function if you want to create a path that is relevant to the currently calling module. That will let you call it outside of a helper class and provide the path to it. Refer to [docs](https://grafana.com/docs/k6/next/javascript-api/import.meta/resolve/) for more details.

### ECMAScript Modules(ESM) Native Support related breaking changes:
### ECMAScript Modules (ESM) Native Support related breaking changes

As part of the implementation, two common patterns broken in the ecosystem became apparent.
As part of the ESM native support implementation, two common broken patterns in the ecosystem became apparent.

One is arguably a developer experience improvement, and the other is a consequence of the previous implementation.

Expand All @@ -65,7 +65,7 @@ Previously, k6 used a transpiler (Babel) internally to transpile ESM syntax to C

As k6 (or the underlying JS VM implementation) did not understand ESM in itself and that CommonJS is a 100% during execution feature, this was not easy to detect or prevent.

We added a [warning](https://github.com/grafana/k6/pull/3807) in v0.52.0 to give users time for migration.
We added a [warning](https://github.com/grafana/k6/pull/3807) in v0.52.0 to give users time for migration.

To fix this - all you need is to stick to either CommonJS or ESM within each file.

Expand All @@ -80,23 +80,25 @@ module.exports.default = func() { ...}

In the example above both ESM and CommonJS are used in the same file.

Either replace
You can either replace:

```javascript
module.exports.default = func() {}
```

with the ESM syntax
With the ESM syntax:

```javascript
export default func() {}
```

or replace
Or replace:

```javascript
import { sleep } from "k6";
```
with the CommonJS:

With CommonJS:

```javascript
const sleep = require("k6").sleep;
Expand All @@ -106,21 +108,22 @@ const sleep = require("k6").sleep;

#### Imported identifier that can't be resolved are now errors

Previously to this if you were using the ESM syntax but imported identifier `foo` but the exporting file didn't export it - there will be no error.
Previous to this, if you were using the ESM syntax and imported the `foo` identifier, but the exporting file didn't export it, there wouldn't be an error.

bar.js:
```javascript
export const notfoo = 5;
```
main.js

main.js
```javascript
import { foo } from "./bar.js"
export default function () {
foo.bar(); // throws exception here
}
```
It would not error out, but when it is accessed, there will be an exception as it will be `undefined`.

The example would not error out, but when it is accessed, there would be an exception as `foo` would be `undefined`.

With native ESM support, that is an error as defined by the specification and will occur sooner.

Expand All @@ -132,21 +135,22 @@ The solution, in this case, is to stop importing the not exported identifiers.

For a long time, k6 has supported special _magic_ URLs that aren't really that.

Those were URLs without a scheme, that:
1. started with `github.com` that if pasted in a browser will not open you the file. Their appeal was that you can more easily write them by hand if you know the path within a github repo.
2. started with `cdnjs.com` that if pasted in a browser will open an web page with all the versions of the library. The appeal here is that you will get the latest version.
Those were URLs without a scheme that:

1. Started with `github.com`, and if pasted to a browser won't open to a file. Their appeal was that you can more easily write them by hand if you know the path within a GitHub repo.
2. Started with `cdnjs.com`, and if pasted to a browser will open a web page with all the versions of the library. The appeal here is that you will get the latest version.

Both of them had problems though.

The github ones seemed to have never be used by users, likely because you need to guess what the path should look like, and you can always just go get a real URL to the raw file.
The GitHub ones seemed to have never been used by users, likely because you need to guess what the path should look like, and you can always just go get a real URL to the raw file.

While the cdnjs ones have some more usage, they are both a lot more complicated to support, as they require multiple requests to figure out what needs to be loaded. They also change over time. In addition the only known use at the moment is based on a very old example from an issue and it is even pointing to concrete, old version, of a library.

Given that this can be done with a normal URL, we have decided to drop support for this and have warned users for the last couple of versions.

### Deprecated `k6/experimental/tracing` in favor of a JavaScript implementation

`k6/experimental/tracing` is arguably not very well named, and there is good chances we would like to use the name for actual trace and span support within k6 in the future.
`k6/experimental/tracing` is arguably not very well named, and there is a good chance we would like to use the name for actual trace and span support within k6 in the future.

On top of that it can now be fully supported in js code, which is why [http-instrumentation-tempo
](https://grafana.com/docs/k6/latest/javascript-api/jslib/http-instrumentation-tempo/) was created.
Expand Down Expand Up @@ -210,25 +214,25 @@ After ESM now being natively supported, compatibility-mode `base` vs `extended`

For the purposes of having less intrusive changes and shipping this earlier a few things have not been implemented in k6. That includes top-level-await and dynamic import support. Both of them are likely to land in the next version.

### `import.meta.resolve()` get URL from a relative path the same way `import` or `require` does [#3873](https://github.com/grafana/k6/pull/3873)
### `import.meta.resolve()` gets an URL from a relative path the same way `import` or `require` does [#3873](https://github.com/grafana/k6/pull/3873)

As part of the move to ESM a lot of cases where k6 currently do not resolve the same relative path to the same file were found. Some of those were fixed - as those in `require`, but others haven't.

It also became apparent some users do use the relativity of `require`, but also `open`. As we move to make this consistent among uses, we decided to let users have a better transition path forward.

Using `import.meta.resolve` will give you just a new URL that can be used in all functions and it will give you the same result.

`import.meta.resolve` uses the same algorithm and relativity as ESM import syntax.
`import.meta.resolve` uses the same algorithm and relativity as ESM import syntax. Refer to [docs](https://grafana.com/docs/k6/next/javascript-api/import.meta/resolve/) for more details.

### Blob support in the experimental websockets module [grafana/xk6-websockets#74](https://github.com/grafana/xk6-websockets/pull/74)

In order to support the default `WebSocket.binaryType` type as per spec (`"blob"`), we have added support for the [`Blob` interface](https://developer.mozilla.org/en-US/docs/Web/API/Blob) as part of the features included in the `xk6-websockets` module.

So, from now on it can be used with `import { Blob } from "k6/experimental/websockets";`. In the future, apart from graduating this module to stable, we might also want to expose the `Blob` interface globally (no imports will be required). But for now, please remind that its support is still experimental, as the entire module is.
So, from now on it can be used with `import { Blob } from "k6/experimental/websockets";`. In the future, apart from graduating this module to stable, we might also want to expose the `Blob` interface globally (no imports will be required). But for now, please remind that its support is still experimental, as the entire module is. Refer to the [docs](https://grafana.com/docs/k6/next/javascript-api/k6-experimental/websockets/blob/) for more details.

### Experimental OpenTelemetry Output [#3834](https://github.com/grafana/k6/pull/3834)

This release introduces a new experimental output for OpenTelemetry. This allows users to send k6 metrics to any OpenTelemetry-compatible backends. More details and usage examples could be found in the [documentation](https://grafana.com/docs/k6/latest/results-output/real-time/opentelemetry/).
This release introduces a new experimental output for OpenTelemetry. This allows users to send k6 metrics to any OpenTelemetry-compatible backends. More details and usage examples can be found in the [documentation](https://grafana.com/docs/k6/latest/results-output/real-time/opentelemetry/).

To output metrics to OpenTelemetry, use the `experimental-opentelemetry` output option:

Expand Down

0 comments on commit 037573d

Please sign in to comment.