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

Hooking resolution helper functions in multiple loaders #104

Open
cspotcode opened this issue Jul 26, 2022 · 1 comment
Open

Hooking resolution helper functions in multiple loaders #104

cspotcode opened this issue Jul 26, 2022 · 1 comment

Comments

@cspotcode
Copy link
Contributor

Extracting these ideas into a separate thread, since #94 is not focused on the challenges of using the helper functions in multiple loaders.

#94 (comment)

You could use them in a sorta-compositional way by having one loader override these helpers, so that when the next loader imports them they get the custom versions.

I'm worried that we don't realize how complex this is, and if anyone sits down to attempt it in a loader, they'll realize they don't like it, and they'll propose that we offer a better API for composition.

Maybe I'm thinking about this wrong, but to customize a single export of a native module, you need to redirect incoming resolutions to a virtual wrapper, but allow the wrapper to itself import the un-wrapped native version. (or a wrapped version from a subsequent loader)

// pseudo-code

// Goals:
// Wrap a single helper function
// Be compatible with other loaders before or after us in the chain that also wrap helper functions

const guid = `${ Math.random() }`; // avoid conflicts with other loaders

function resolve(specifier, ctx, next) {
  if(specifier === 'node:module') return next(`node:module-wrapper-${guid}`, ctx);
  if(specifier === `node:module-next-${guid}`) return next(`node:module`, ctx);
  return next(specifier, ctx);
}
function load(url, ctx, next) {
  if(url === `node:module-next-${guid}`) return next(`node:module`, ctx);
  if(url === `node:module-wrapper-${guid}`) return wrapperText;
  return next(url, ctx);
}
const wrapperText = `
    export * from 'node:module-next-${guid}';
    import {functionToWrap as _functionToWrap} from 'node:module-next-${guid}';
    export functionToWrap(a) {
      if(conditional) return _functionToWrap(a + 1);
      return _functionToWrap(a);
    }
`;
@GeoffreyBooth
Copy link
Member

You could use them in a sorta-compositional way by having one loader override these helpers, so that when the next loader imports them they get the custom versions.

I’m worried that we don’t realize how complex this is, and if anyone sits down to attempt it in a loader, they’ll realize they don’t like it, and they’ll propose that we offer a better API for composition.

What I meant there is that you could do this, overriding the helpers for subsequent loaders to use, not that you should. In general I think we should provide specific APIs for customizations rather than expecting or encouraging people to monkey-patch or override. The nature of the module hooks we already have is that just about anything can be overridden, so that’s an option, but it’s a sucky one. We absolutely should provide dedicated APIs for customizing filesystem calls if that’s a use case that we want to support.

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

No branches or pull requests

2 participants