esmock icon indicating copy to clipboard operation
esmock copied to clipboard

What about Yarn PnP support?

Open koshic opened this issue 2 years ago • 12 comments

Any loader used in PnP mode can't resolve/load any packages except Node builtins. Yep, we have discussion in Node community how to improve loaders, how to redesign API, etc.

But now only one way - to have bundled loader. It works perfectly for me (I use simple esdbuild-based transpiler for .ts, as an example), but I can't use esmock 'out of box' (proxy bundle is the way, but...) to try node native test runner instead of Jest.

Can we remove single external dependency, 'resolvewithplus' here? Or, mark it optional and use import.meta.resolve (by flag / different import path like esmock/native or so on).

koshic avatar Oct 17 '22 18:10 koshic

It might be OK to embed resolvewithplus inside esmock. Maybe the prepublish script could copy resolvewithplus.js into the src folder then update esmock files to import './resolvewithplus.js' rather than 'resolvewithplus'. A new version could then be published with no dependencies.

@tripodsan @aladdin-add it would be good to know what you think of this idea.

iambumblehead avatar Oct 17 '22 22:10 iambumblehead

@koshic does resolvewithplus need to be removed from package.json? If resolvewithplus is not removed from package.json, but if esmock does something like this, would this work for your situation?

const resolver = typeof import.meta.resolve === 'function'
  ? import.meta.resolve
  : (await import('resolvewithplus')).default

iambumblehead avatar Oct 17 '22 22:10 iambumblehead

@jakebailey I think the second one is the best solution, ~~with marking resolvewithplus as optional peer dependency~~, thx!

ps it should work :)

koshic avatar Oct 17 '22 23:10 koshic

"import.meta.resolve" does not resolve subpaths. The test creates a call like await import.meta.resolve('#sub', parent)

import.meta.resolve is experimental and, to my understanding based on browsing various discussions in nodejs upstream, incomplete. If esmock is updated to rely on current import.meta.resolve, things may get messy in the future.

iambumblehead avatar Oct 18 '22 05:10 iambumblehead

there will be less maintenance, if we wait for import.meta.resolve to be stable and complete before using it.

iambumblehead avatar Oct 18 '22 05:10 iambumblehead

Or, mark it optional and use import.meta.resolve (by flag / different import path like esmock/native or so on).

a good idea BUT esmock tried exporting something like this a month or two ago and typescript does not support this sort of thing https://github.com/TypeStrong/ts-node/discussions/1877 even if typescript could (or can?) do this, the support is or will not be great and annoying complexity necessary to placate typescript

iambumblehead avatar Oct 18 '22 05:10 iambumblehead

"import.meta.resolve" does not resolve subpaths. The test creates a call like await import.meta.resolve('#sub', parent)

It supports: image

koshic avatar Oct 18 '22 10:10 koshic

thanks for making the demonstration. I'll try updating the PR later today and then respond afterward

iambumblehead avatar Oct 18 '22 15:10 iambumblehead

I think the problem at the PR is, "parent" is not in fileURL format that starts with "file:///" this can be fixed of course

iambumblehead avatar Oct 18 '22 15:10 iambumblehead

there will be less maintenance, if we wait for import.meta.resolve to be stable and complete before using it.

--experimantal-loaders is experimental too, so waiting can be looong )

koshic avatar Oct 18 '22 15:10 koshic

@koshic if you approve this PR, let's merge and use follow-up PRs to specifically resolve the two issues,

  1. https://github.com/iambumblehead/esmock/issues/178 use loader mechanism directly to detect esmock loader,
  2. https://github.com/iambumblehead/esmock/issues/176 (this ticket) make resolvewithplus an optional dependency

I have not used optional dependencies myself so am interested to see how it works. If resolvewithplus is an optional dependency, will npm continue to download it by default for esmock? My research indicates resolvewithplus will continue to be downloaded in the default case, but I haven't used optional dependencies before so am not certain.

@koshic if you still have test files you made for testing stub export, would you test if import.meta.resolve returns paths for moduleIds with extensions like "tsx" or "json"? If you're not interested to test this that's good and I can make a little test later this evening or tomorrow.

iambumblehead avatar Oct 19 '22 03:10 iambumblehead

@iambumblehead I will approve after few small fixes )

And yes, import.meta.resolve returns all paths: image

koshic avatar Oct 19 '22 11:10 koshic

changes are published and deployed https://github.com/iambumblehead/esmock/releases/tag/v2.0.7

feel free to re-open if there is any issue :)

iambumblehead avatar Oct 26 '22 09:10 iambumblehead