artillery icon indicating copy to clipboard operation
artillery copied to clipboard

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME] when using a artillery runner file with a `.mjs` extension

Open thrandale opened this issue 10 months ago • 1 comments

Artillery is supposed to support ES Modules. Per the documentation, the way of doing this is to have your artilleryRunner file have the .mjs extension instead of the .js extension. I am using an artillery.yaml file to pass in the processor:

config:
  ...
  processor: "artilleryRunner.mjs"
  ...

When running artillery it gives the error Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'

In doing some tracing, this error is Coming from core/lib/runner.js when it is trying to load the artilleryRunner.mjs file. Per this) Stack Overflow Post: the import() function [only works with file:// and data:// URLs](https://nodejs.org/api/errors.html#err_unsupported_esm_url_scheme), but path.resolve() only returns an absolute path (not a URL)

This can be fixed by doing a pathToFileURL() before doing the import() of the module

Version info:

Artillery: 2.0.10
Node.js:   v18.17.1
OS:        win32

thrandale avatar Apr 22 '24 01:04 thrandale

This is impacting me too. Windows paths are getting detected as urls

ShaunLawrie avatar Jun 04 '24 21:06 ShaunLawrie

This is making the artillery completely unusable on windows if we have typescript configured to compile playwright tests to esm modules.

ggecy avatar Jul 18 '24 10:07 ggecy

tests.yml

config:
  target: 'https://something.com'
  phases:
    - duration: 1
      arrivalRate: 1
  processor: '../auth.mjs'
  variables:
    user: 'tester'
scenarios:
  - name: 'Get'
    flow:
      - get:
          beforeRequest: 'auth'
          url: '/path'
          headers:
            Authorization: 'Bearer {{ token }}'

auth.mjs

export async function auth(requestParams, context, events) {
  const user = context.vars.user;
  console.log(`user: ${user}`);
  context.vars.token = 'test';
}

Facing the same error with above settings. This error renders it completely unusable on Windows.

cwongmt avatar Jul 24 '24 13:07 cwongmt

Hi @cwongmt and others,

I'm looking into this currently and working on getting some windows tests in CI 👋 . We'll hopefully have it solved for next release.

bernardobridge avatar Jul 24 '24 14:07 bernardobridge

I also have this problem. My processor aint want to work :( .mjs processor, windows environment, package version 2.0.18

ZirionNeft avatar Jul 26 '24 14:07 ZirionNeft

Hello @ZirionNeft, @cwongmt, @ggecy and @ShaunLawrie 👋 . A fix for this is now released in Artillery v2.0.19.

Thanks to @thrandale for the report and fix!

bernardobridge avatar Aug 06 '24 17:08 bernardobridge

@bernardobridge I am seeing that there is still an issue for this. On line 99, there is another require(processorPath).

} else { // CJS (possibly transplied from TS) script.config.processor = require(processorPath); }

My error: Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Dev\Artillery-Performance-Framework\tests\PartsTrader.InsurerTicketing.PerformanceTests\dist\perfTest.js from C:\Dev\Artillery-Performance-Framework\tests\PartsTrader.InsurerTicketing.PerformanceTests\node_modules@artilleryio\int-core\lib\runner.js not supported. Instead change the require of perfTest.js in C:\Dev\Artillery-Performance-Framework\tests\PartsTrader.InsurerTicketing.PerformanceTests\node_modules@artilleryio\int-core\lib\runner.js to a dynamic import() which is available in all CommonJS modules.

A possible fix would be to use something like

(async () => { script.config.processor = await import(processorPath); })();

Guzikowski avatar Aug 07 '24 02:08 Guzikowski

Hello @Guzikowski. That feels like it might possibly be a separate (but related) issue.

You shouldn't be getting to that part of the logic with an .mjs processor anymore. Are you using Typescript? Could you perhaps share your config?

bernardobridge avatar Aug 07 '24 06:08 bernardobridge

@bernardobridge Yeah, I can adjust my code to force the .mjs, but just came across this path when attempting to use ES Modules with typescript. I should be able to go through the corrected path, should I raise this as separate issue or would this be not supported?

Guzikowski avatar Aug 07 '24 18:08 Guzikowski

@Guzikowski sounds like you might be running into this https://github.com/artilleryio/artillery/discussions/3296 (correct me if I'm wrong). We'll be tackling that one soon, so just keep an eye on that thread. If you feel like your issue is different (for example, if your project isn't setting the files as ESM), then you can open another issue.

bernardobridge avatar Aug 07 '24 18:08 bernardobridge

@bernardobridge That is similar to my issue, I managed to perform a work around to build my NPM package with file extensions that artillery is looking for. I managed to get referenced packages working. I understand this is still a WIP, but I was unable to get artillery working via ES module fully. I rolled back to commonJS, and now my NPM packages are working. Interested in the ES module, my existing project the beforeScenario works fine, but the beforeRequest indicates it is not a function. I did not have the proper time to verify why things were not working and rolled back to previous version.

Guzikowski avatar Aug 11 '24 22:08 Guzikowski