Skip to content

Fix require to be specification compliant in respect to what it resolves relative to #3534

@mstoykov

Description

@mstoykov

Brief summary

k6's require has always resolved specifiers relative to the current "root of execution" module/script instead of to relative to the script/module the file is in.

An example below will help illustrate what "root of execution" is.

This behavior has been around forever and is against the specification for commonJS and is not how dynamic import works or to be honest anything else I have come around.

The same issue is true for open, but:

  1. this is issues is require specific to limit it scope
  2. open is not based on any specification

For the rest of the issue I might add "Also relevant to open" as reminder for this, but open is not what we discuss here.

This is extracted from #2674 within a more actionable issue

k6 version

all

OS

all

Docker version and image (if applicable)

No response

Steps to reproduce the problem

Have 3 files:
main.js

const s = require("./A/a.js")
if (s() != 5) {
	throw "Bad"
}
module.exports.default = () =>{} // just to not error

/A/a.js:

module.exports =  function () {
  return require("./b.js");
}

/A/b.js

module.exports = 5

This should not throw an exception - but it does. As at the time s() is executed the "root of the execution" is main.js not /A/a.js and consequently k6 resolves ./b.js based on that and then loading it from disk doesn't find it leading to

ERRO[0000] GoError: The moduleSpecifier "./b.js" couldn't be found on local disk. Make sure that you've specified the right path to the file. If you're running k6 using the Docker image make sure you have mounted the local directory (-v /local/path/:/inside/docker/path) containing your script and modules so that they're accessible by k6 from inside of the container, see https://k6.io/docs/using-k6/modules#using-local-modules-with-docker.
        at go.k6.io/k6/js.(*requireImpl).require-fm (native)
        at file:///home/mstoykov/work/k6io/k6/path-based-tests-playground/issue-example/A/a.js:3:16(3)
        at file:///home/mstoykov/work/k6io/k6/path-based-tests-playground/issue-example/main.js:3:6(7)  hint="script exception"

Expected behaviour

Script runs as expected and there is no exception.

Actual behaviour

ERRO[0000] GoError: The moduleSpecifier "./b.js" couldn't be found on local disk. Make sure that you've specified the right path to the file. If you're running k6 using the Docker image make sure you have mounted the local directory (-v /local/path/:/inside/docker/path) containing your script and modules so that they're accessible by k6 from inside of the container, see https://k6.io/docs/using-k6/modules#using-local-modules-with-docker.
        at go.k6.io/k6/js.(*requireImpl).require-fm (native)
        at file:///home/mstoykov/work/k6io/k6/path-based-tests-playground/issue-example/A/a.js:3:16(3)
        at file:///home/mstoykov/work/k6io/k6/path-based-tests-playground/issue-example/main.js:3:6(7)  hint="script exception"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions