unjs / unbuild

📦 A unified JavaScript build system
MIT License
2.36k stars 90 forks source link

TypeScript Files Not Automatically Converted to ECMAScript Modules (.mjs) #350

Open productdevbook opened 11 months ago

productdevbook commented 11 months ago

When importing a TypeScript file using the .ts extension, the build process does not automatically convert it to an ECMAScript module with the .mjs extension. This leads to import errors, as the expected file format is not found.

await import(_resolver.resolve("./seed/index.ts"))

After import build there is a problem because .ts does not convert to mjs. How can I do this

await import(_resolver.resolve("./seed/index.mjs"))
pi0 commented 10 months ago

Can you please make a runnable reproduction so I can test? 🙏🏼

angelhdzdev commented 9 months ago

Can you please make a runnable reproduction so I can test? 🙏🏼

I replied to this Issue but then deleted the reply to have a better understanding.

After so much playing around, I reached the conclusion that this Issue matches mine.

unbuild is failing to add the .mjs extension to the source code of the built files for dynamic imports without extension await import("/path/to/module") should convert to await import("/path/to/module.mjs") so that it can be loaded with node at runtime. But then Node throws an error that the module is not found because of the missing extension. Adding the extension manually solves this apparently.

In my case I'm building a nuxi add/nuxi new inspired CLI to add more templates and using inquirer package to select templates and configurations, it's a binary/executable, so I don't know how to tell Node to use some loader that adds the extension. So my only option is after running unbuild, adding the .mjs everywhere I import dynamically. Yes, I modified build.config.ts to pack the ~/src/templates and ~/src/utils directories and they are being generated and their .ts files converted to .mjs.

My drastic workaround was, instead of loading the templates .ts files at runtime, I imported them statically in the ~/src/templates/index.ts (the same way nuxi does), so now there's no issue with it. You can check it here: https://github.com/angelhdzmultimedia/ahdz-nuxt-scaffold.

Any info will be highly appreciated. 🔥💚🤝😊

s3xysteak commented 3 months ago

Both import('./one') and import('./one.ts') work well:

// ./utils/one.ts
export const one = 1

// index.ts
export async function getOne() {
  return await import(`./utils/one.ts`).then(m => m.one)
}

After compiling:

// index.mjs
async function getOne() {
  return await import('./chunks/one.mjs').then((m) => m.one);
}

export { getOne };

I think the problem is that it seems unbuild do not support dynamic import with variables, which is a feature of Vite:

const module = await import(`./dir/${file}.ts`)

To confirm that, use the code below:

// index.ts
export async function getOne() {
  const path = 'one'
  return await import(`./utils/${path}.ts`).then(m => m.one)
}

After compiling:

// index.mjs
async function getOne() {
  const path = "one";
  return await import(`./utils/${path}.ts`).then((m) => m.one);
}

export { getOne };