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

[Feature Request] expose 'resolveModule' as an API #1773

Closed
hanayashiki opened this issue Nov 14, 2021 · 3 comments
Closed

[Feature Request] expose 'resolveModule' as an API #1773

hanayashiki opened this issue Nov 14, 2021 · 3 comments

Comments

@hanayashiki
Copy link

For a TS/JS interpreter using lazy loading has the following situation:

  1. Read a file
  2. Resolve, load and transpile its dependencies recursively.
  3. Execute the file, and possibly repeat the progress again when there's async import.

And that's what https://github.com/antfu/esbuild-node-loader is trying to do.

Currently, there's repeated problem with the 'resolve' function. We are now using the original typescript resolver, but it is not always the case it works, e.g., ts resolve eagerly accepts '.d.ts' result rather than '.js', which is useful with type-checking but incorrect if we want to resolve the runnable file. Bundling doesn't work because some libraries assume unbundled environment when executed with node.

Esbuild has done a good job resolving typescript and javascript modules, according to my experience, but as far as I know, it doesn't expose the API for resolving. I wish the author of this fantastic library could take this into consideration.

Thank you.

@hyrious
Copy link

hyrious commented Nov 16, 2021

Invoking the resolver in go requires additional IPC resource and must be async, maybe rewriting resolver.go in js is a better choice.

You can make a simple wrapper of esbuild to write an async resolver like such:

const esbuild = require('esbuild')

async function esbuildResolve(id, dir) {
  let result
  await esbuild.build({
    stdin: {
      contents: `import ${JSON.stringify(id)}`,
      resolveDir: dir,
    },
    write: false,
    bundle: true,
    plugins: [{
      name: 'resolve',
      setup({ onLoad }) {
        onLoad({ filter: /.*/ }, args => {
          result = args.path
          return { contents: '' }
        })
      }
    }]
  })
  return result
}

;(async () => {
  let a = await esbuildResolve('./a', __dirname)
  console.log(a)
})();

@hanayashiki
Copy link
Author

Invoking the resolver in go requires additional IPC resource and must be async, maybe rewriting resolver.go in js is a better choice.

You can make a simple wrapper of esbuild to write an async resolver like such:

const esbuild = require('esbuild')

async function esbuildResolve(id, dir) {
  let result
  await esbuild.build({
    stdin: {
      contents: `import ${JSON.stringify(id)}`,
      resolveDir: dir,
    },
    write: false,
    bundle: true,
    plugins: [{
      name: 'resolve',
      setup({ onLoad }) {
        onLoad({ filter: /.*/ }, args => {
          result = args.path
          return { contents: '' }
        })
      }
    }]
  })
  return result
}

;(async () => {
  let a = await esbuildResolve('./a', __dirname)
  console.log(a)
})();

smart hack! thank you for that

@evanw
Copy link
Owner

evanw commented Dec 23, 2021

Closing this as a resolve API has now been implemented: #1881. Path resolution depends on the build configuration so it's not something that makes sense to expose as a separate top-level API. It as been exposed as a plugin API instead.

@evanw evanw closed this as completed Dec 23, 2021
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

3 participants