developit / microbundle

📦 Zero-configuration bundler for tiny modules.

Home Page:https://npm.im/microbundle

Repository from Github https://github.comdevelopit/microbundleRepository from Github https://github.comdevelopit/microbundle

Dymanic imports not working in next.js and webpack applications

jarkin13 opened this issue · comments

I am developing a node module that will be consumed by applications that use Webpack(more specifically CRA and CRACO to build) and Next.js. The node module uses microbundle when building and publishing the module.

The module imports a 3rd party library and uses a different URL based on the environment. Ideally, I would like the application consuming our module to pass a host for the 3rd party library. However, using any conditionals or passing any variables as the host causes the following error: Error: Cannot find module https://example.com/library.

Using tsc to build my module all of the solutions below work, but microbundle does something with dynamic imports causing the error.

This works

const importLibrary = async (env: 'dev' | 'prod'): Promise<LibraryType> => {
  const devHost = 'https://example-dev.com'
  const prodHost = 'https://example-prod.com'

  if (env === 'dev') {
    return await import(`${devHost}/library`)
  }

  return await import(`${prodHost}/library`)
}

Imports that cause an error

// Using a conditional in host
const importLibrary = async (env: 'dev' | 'prod'): Promise<LibraryType> => {
  const host = env === 'dev' 
     ? 'https://example-dev.com'
     : 'https://example-prod.com'

  return await import(`${host}/library`)
}

// Passing prop from application
type HostType = 'https://example-dev.com' | 'https://example-prod.com'
const importLibrary = async (host: HostType): Promise<LibraryType> => {
  return await import(`${host}/library`)
}

I am not using the importLibrary function directly in the consuming applications. I have a hook that imports the library and passes the env or host to the function from the consuming application.

If the node module is used in a vite application, all solutions above work.

In addition, I am simplifying my code, the actual code I am using does have a try statement. I do console.log the error and return undefined if it can't be imported.

Can you provide a complete reproduction? Nothing looks problematic from Microbundle's side from what I see. This might be an issue better solved in Webpack's repo.

Closing, happy to reopen if you can provide a reproduction but this doesn't seem like an issue on our side.