nodejs / import-in-the-middle

Like `require-in-the-middle`, but for ESM import
https://www.npmjs.com/package/import-in-the-middle
Apache License 2.0
52 stars 20 forks source link

parentResolve is not a function #99

Closed gajus closed 3 weeks ago

gajus commented 3 weeks ago

Expected Behavior

import-in-the-middle to work.

Actual Behavior

at 20:24:19 ❯ node --import @sentry/node/preload ./dist/bin/server.js

node:internal/modules/run_main:125
    triggerUncaughtException(
    ^
TypeError [Error]: parentResolve is not a function
    at processModule (/Users/x/Developer/contra/gaia/node_modules/.pnpm/import-in-the-middle@1.8.0/node_modules/import-in-the-middle/hook.js:154:30)
    at async processModule (/Users/x/Developer/contra/gaia/node_modules/.pnpm/import-in-the-middle@1.8.0/node_modules/import-in-the-middle/hook.js:160:23)

This is the line where it happens:

        // Bare specifiers need to be resolved relative to the parent module.
        const result = await parentResolve(modFile, { parentURL: srcUrl })

If I inject console.log({parentResolve, modFile}); before, it prints:

{
  parentResolve: [AsyncFunction: nextResolve],
  modFile: '@envelop/types'
}
{
  parentResolve: [AsyncFunction: nextResolve],
  modFile: '@graphql-yoga/logger'
}

Appears to be some sort of race condition.

async function processModule ({ srcUrl, context, parentGetSource, parentResolve, excludeDefault }) {
+  console.log({parentResolve});

  const exportNames = await getExports(srcUrl, context, parentGetSource)
  const duplicates = new Set()
  const setters = new Map()

  const addSetter = (name, setter) => {
    // When doing an `import *` duplicates become undefined, so do the same
    if (setters.has(name)) {
      duplicates.add(name)
      setters.delete(name)
    } else if (!duplicates.has(name)) {
      setters.set(name, setter)
    }
  }

  for (const n of exportNames) {
    if (n === 'default' && excludeDefault) continue

    if (isStarExportLine(n) === true) {
      const [, modFile] = n.split('* from ')

      let modUrl
      if (isBareSpecifier(modFile)) {
+        console.log({parentResolve, modFile});

        // Bare specifiers need to be resolved relative to the parent module.
        const result = await parentResolve(modFile, { parentURL: srcUrl })
{ parentResolve: [AsyncFunction: nextResolve] }
{ cachedResolve: [AsyncFunction: nextResolve] }
{ parentResolve: [AsyncFunction: nextResolve] }
{ parentResolve: undefined }
{
  parentResolve: [AsyncFunction: nextResolve],
  modFile: '@envelop/types'
}
{ parentResolve: undefined }

Steps to Reproduce the Problem

N/A

Specifications

gajus commented 3 weeks ago

Actually, this invocation is coming from:

const setters = await processModule({
  srcUrl: modUrl,
  context,
  parentGetSource,
  excludeDefault: true
})

parentResolve is not passed here, so it is indeed undefined.