aws/aws-lambda-nodejs-runtime-interface-client

Imports and requires may not be using Node Loaders/Registration for ESM

Downchuck opened this issue · 1 comments

The Yarn PNP mechanism uses loaders and/or registration for CJS and ESM support.

Presently using -r .pnp.cjs works appropriately in AWS SAM but using --loader runs into a host of issues as detailed in:

yarnpkg/berry#6604

I'm not clear why the two are not working together, as they work in other contexts - but in the AWS SAM index.mjs it seems that the tryRequire path goes through a route where pnp.setup(); is unable to monkey patch calls once it is working within the CJS loader by route of the ESM loader.

Cross posting the current work-around as a loader, using -r /opt/nodejs/.pnp.cjs --loader /var/task/hackey-hack.mjs:

/*
- Our .pnp.loader.mjs uses the parentURL, to try to pickup .pnp.cjs which fails.
- It does not seem to use any of our env variables to set the yarn cache either.
- Pretend we are in /opt/nodejs/ so it picks up .pnp.cjs and the .yarn folder.
*/
const esmpnp = await import("/opt/nodejs/.pnp.loader.mjs");

export async function resolve(specifier, context, nextResolve) {
  const parentURL = context.parentURL?.replace("file:///var/task/", "file:///opt/nodejs/");
  const contexts = { ...context, parentURL };
  const resolve = await esmpnp.resolve(specifier, specifier.startsWith("./") ? context : contexts, nextResolve);
  return resolve;
}

export async function load(urlString, context, nextLoad) {
  const load = await esmpnp.load(urlString, context, nextLoad);
  if(urlString === "file:///var/runtime/index.mjs") {
    const prepend = 'const { default: pnp } = await import("/opt/nodejs/.pnp.cjs"); pnp.setup(); const esmpnp = await import("/opt/nodejs/.pnp.loader.mjs");';   
    load.source = prepend + "\n" + load.source;
  }
  return load;
}