Skip to content
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

Added support for native Node ES6 modules #211

Merged
merged 8 commits into from
Nov 24, 2020

Conversation

richardsimko
Copy link
Contributor

@richardsimko richardsimko commented Nov 20, 2020

Fixes #210

Sadly it's not possible to test the native specific parts since jest doesn't do mocks of the native import() function. However since I broke all the logic out to separate functions the real difference between loading modules using ES modules and CJS is negligible.

@coveralls
Copy link

Coverage Status

Coverage decreased (-3.3%) to 96.654% when pulling f38d858 on richardsimko:master into 10ab656 on jeffijoe:master.

@coveralls
Copy link

coveralls commented Nov 20, 2020

Coverage Status

Coverage remained the same at 100.0% when pulling 820daa7 on richardsimko:master into 10ab656 on jeffijoe:master.

Copy link
Owner

@jeffijoe jeffijoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Would you mind restoring coverage to 100%? 😄

@jeffijoe
Copy link
Owner

jeffijoe commented Nov 20, 2020

You can pass in the import function in the load modules options to stub it out in a unit test. Feel free to add the load-modules.js to coverage ignore.

@richardsimko
Copy link
Contributor Author

Coverage restored 🎉

Copy link
Owner

@jeffijoe jeffijoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are really close! Few little things left 😄

@@ -564,6 +566,10 @@ export function createContainer<T extends object = any, U extends object = any>(
return resolver.resolve(container)
}

function loadModules<ESM extends boolean = false>(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these 2 signatures not the same? You should be able to get away with just using this one.

Copy link
Contributor Author

@richardsimko richardsimko Nov 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly not, I'm not quite sure why but if I try to use only the definition with the optional return it doesn't work claiming it doesn't match the interface:

Type 'Promise<{ options: ContainerOptions; cradle: T; inspect: (depth: number, opts: any) => string; cache: Map<string | symbol, CacheEntry<any>>; loadModules: <ESM extends boolean = false>(globPatterns: (string | ... 1 more ... | [...])[], opts: LoadModulesOptions<...>) => ESM extends false ? AwilixContainer<...> : Promi...' is not assignable to type 'ESM extends false ? AwilixContainer<any> : Promise<AwilixContainer<any>>'.ts(2322)

And of course using only the type union doesn't work since it doesn't match the condition. This suggests the same issue: https://stackoverflow.com/a/55059896/1091402

load-modules.ts has the same issue.

@jeffijoe
Copy link
Owner

I’ll take a look when I’m back Monday, thanks!

@jeffijoe
Copy link
Owner

How come load-module-native.js is in the external list for Rollup?

Have you by any chance tested that the Browser builds work after this change?

@richardsimko
Copy link
Contributor Author

It's external because it's just copied as-is, it should not be touched by the TS compiler since it will convert import() to CommonJS (This is also why it's a separate .js file). I've removed it as an external from the browser build, since it should never get imported there.

The browser build works to the extend that there is a file generated, but I haven't used it for anything. That said since loadModules gets removed none of these changes should impact the browser.

Copy link
Owner

@jeffijoe jeffijoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@jeffijoe jeffijoe merged commit cee31e7 into jeffijoe:master Nov 24, 2020
@jeffijoe
Copy link
Owner

jeffijoe commented Nov 24, 2020

Merged and released as v4.3! 🥳 Thank you!

): Promise<LoadModulesResult> {
const importPromises = []
for (const m of modules) {
importPromises.push(dependencies.require(m.path))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got a bug in this part when using in windows

Uncaught 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

While debuging i could fix by adding these lines

    const isWindows = process.platform === 'win32';
    const _path = isWindows? `file://${m.path}`: m.path;
    importPromises.push(dependencies.require(_path))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jeffijoe and @richardsimko
Should i open this comment as a new issue, did you get what i mean?

I used the following glob that throws that error in windows
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! I thought node would handle that automatically! It does on macOS at least, since the path that import() gets called with (Which is at the top of the stack from this call) is a file:// URL. I sadly don't have access to a Windows computer to test but reading this nodejs/node#31710 the recommended approach seems to be to use URL.pathToFileURL https://nodejs.org/api/url.html#url_url_pathtofileurl_path.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@richardsimko, how could i use it in loadModules method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can do anything as a consumer, but you can submit a PR here to fix it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for node ES6 modules
4 participants