jeffijoe / awilix

Extremely powerful Inversion of Control (IoC) container for Node.JS
MIT License
3.53k stars 134 forks source link

loadModules not working on windows #225

Closed slavb18 closed 3 years ago

slavb18 commented 3 years ago

Following code not working on windows os (node 14.15.5) Same code on linux works

  await this.container.loadModules(
      ['src/repositories/**/*.mjs', 'src/usecases/**/*.mjs', 'src/providers/**/*.mjs'],
      {
        formatName: 'camelCase',
        esModules: true
      }
    );

Error:

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:782:11)
    at Loader.resolve (internal/modules/esm/loader.js:86:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:230:28)
    at Loader.import (internal/modules/esm/loader.js:165:28)

Following code show no error, but does not loads any modules

import url from 'url'
import path from 'path';

function resolve(pth){
  return url.pathToFileURL(path.resolve(pth)).toString();
}

...

  await this.container.loadModules(
      [resolve('src/repositories/**/*.mjs'), resolve('src/usecases/**/*.mjs'), resolve('src/providers/**/*.mjs')],
      {
        formatName: 'camelCase',
        esModules: true
      }
    );
jeffijoe commented 3 years ago

@richardsimko any ideas?

richardsimko commented 3 years ago

It sounds like the same issue as the comment here: https://github.com/jeffijoe/awilix/pull/211/files#r557012499

Sadly I don't have access to a Windows machine to test my hypothesis but if @WagnerSilveira or @slavb18 could that would be awesome, I think it should be fairly straightforward.

slavb18 commented 3 years ago

@richardsimko, what should I do test ?

richardsimko commented 3 years ago

In the load-modules.ts file you need to import the url package and then replace the commented line with:

importPromises.push(dependencies.require(URL.pathToFileURL(m.path)))

If my theory is correct this should work well on both Windows and nix. The test suite will take care of testing it on nix so if you can verify that it works on Windows then you have the fix right there :)

eithermonad commented 3 years ago

The changes made in 9fbd195f767506474d709fc65fc21528c8733139 work for me on Windows.

Additionally, as it stands, this test will always fail on Windows since the URLs of the modules after calling pathToFileURL will no longer match with the ones specified in the test:

https://github.com/jeffijoe/awilix/blob/7489ef56ff2bd832ee8c62975c87fd819e42bbaf/src/__tests__/load-modules.test.ts#L41-L66

richardsimko commented 3 years ago

I'm not sure there is a test suite running on Windows, which is probably why this problem occurred to begin with. So I guess that test not working on Windows is "fine".

Anyhow good to hear that there is a fix :)