microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.29k stars 12.39k forks source link

Allow module resolution Bundler with module NodeNext #59756

Closed a88zach closed 2 weeks ago

a88zach commented 3 weeks ago

🔍 Search Terms

NodeNext Bundler

✅ Viability Checklist

⭐ Suggestion

Allow the use of module: "NodeNext" with moduleResolution: "Bundler"

If you are building an application with Typescript that is going to run in Node.js and you want to output an ES module, you will need to use a bundler like Webpack to transform the Typescript output into a format that will run in Node.js if you are using .ts extension when importing other modules

Currently, you can use moduleResolution: "NodeNext" with allowImportingTsExtensions: true and then use a bundler to transform the .ts extensions into .js extensions. However, if you use are using a bundler anyways, then using moduleResolution: "Bundler" will also allow you to write imports without the .ts extension and without having to set allowImportingTsExtensions: true,

📃 Motivating Example

You can now use the new module resolution of Bundler with NodeNext

💻 Use Cases

  1. What do you want to use this for? Creating Node.js application in esm format
  2. What shortcomings exist with current approaches? You cannot use the module resolution of Bundler with NodeNext
  3. What workarounds are you using in the meantime? Setting allowImportingTsExtensions: true and then use a bundler to rewrite the .ts extensions to .js
andrewbranch commented 2 weeks ago

What exactly do you want from --module nodenext --moduleResolution bundler that you’re not getting out of --module preserve --moduleResolution bundler?

a88zach commented 2 weeks ago

@andrewbranch I'm currently working in a NX mono repo and I'm converting my applications and libraries to esm. Currently all my apps have been converted to esm, but my libraries are still using --module commonjs --moduleResolution node.

Here is a compare of how one of the library files is output using the different options 59756-diff.pdf

With NodeNext, my circular references are resolved correctly. With Preserve, my application won't start up because of accessing references before initialization. Obviously, it would be preferred to unwind all circular references, but it's easier said than done when using typegoose and typegraphql :)

a88zach commented 2 weeks ago

@andrewbranch here is a repo to demonstrate: https://github.com/a88zach/ts-59756

Instructions in the README.md

andrewbranch commented 2 weeks ago

When you’re talking about the output, are you looking at the output of tsc or the output of Webpack?

a88zach commented 2 weeks ago

The attached file above is the compare of the tsc output.

I'll also update the example provided to emit the output so that it's clear this is about the tsc output and not the webpack output

Edit: updated the repo with quick script to produce thetsc output. Just run yarn tsc with each configuration to see the output in ./dist/out-tsc

andrewbranch commented 2 weeks ago

Can you clarify, for each TS project in the example repo, all the ways you intend to build, publish, import, and/or run the code? With the mix of tsc, webpack, --module nodenext and --moduleResolution bundler, I'm struggling to understand all the requirements here.

a88zach commented 2 weeks ago

The short answer here is that I want to build a Node app that uses ESM format. I'm developing the code with Typescript and I don't want to use extensions with my import statements.

Currently, I'm using .ts extensions with my import statements because I have to use --module nodenext and --moduleResolution nodenext in order to produce an app that actually runs.

I have tried to use --module preserve and --moduleResolution bundler but the TSC output is different than when using the above options and the application errors on startup (demonstrated in the repo above)

As far as the example repo:

I know I need to use --module nodenext to get the output I want. I also know that I'm using a bundler (Webpack). Are there any technical reasons not to allow --moduleResolution bundler with --module nodenext as long as the end user knows that the final TSC output will be bundled?

andrewbranch commented 2 weeks ago

You’re seeing a bug or limitation of Webpack, or your particular setup with Webpack. I don’t know what the Nx plugins/config for Webpack are doing under the hood, but it’s actually weird to me that module is even affecting its output. Most bundlers/loaders these days don’t depend on tsc’s module output. There’s no reason they should, since the result of bundling is the removal of module constructs. The bundlers/loaders typically just read and understand the imports in the input files and produce a bundle with no imports/requires in the output. You shouldn’t really have to worry about what tsc would produce here at all. That’s why it doesn’t make sense to allow --module nodenext --moduleResolution bundler. The module output constructs from tsc should be completely irrelevant any time you’re bundling.

typescript-bot commented 2 weeks ago

This issue has been marked as "External" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

code30x58 commented 2 weeks ago

AWS cloud tools codices intervened leak on QR codes seen as a error message with a endless connection report buffering page to a file structure ms dos

<ms-store-badge       productid=""       window-mode="full"       theme="auto"       language="en-us"       animation="on">


From: TypeScript Bot @.> Sent: Friday, September 6, 2024 6:35:35 PM To: microsoft/TypeScript @.> Cc: Subscribed @.***> Subject: Re: [microsoft/TypeScript] Allow module resolution Bundler with module NodeNext (Issue #59756)

Closed #59756https://github.com/microsoft/TypeScript/issues/59756 as not planned.

— Reply to this email directly, view it on GitHubhttps://github.com/microsoft/TypeScript/issues/59756#event-14168094918, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A45VJTKUUE37JXIKHHO5L7TZVJJ6PAVCNFSM6AAAAABNEFVCXKVHI2DSMVQWIX3LMV45UABCJFZXG5LFIV3GK3TUJZXXI2LGNFRWC5DJN5XDWMJUGE3DQMBZGQ4TCOA. You are receiving this because you are subscribed to this thread.Message ID: @.***>