jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.24k stars 508 forks source link

Request: Allow AMD builds #938

Open marciel-truesoft opened 3 years ago

marciel-truesoft commented 3 years ago

Current Behavior

UMD build doesn't support code-splitting and dynamic imports (rollup/rollup#3490, rollup/rollup#3491) due to Rollup current limitations, and tsdx cli don't accept the format option amd when creating build config

Suggested Solution

Consider support AMD module format, or at least accept amd option, so we can customize the build output using the tsdx.config.js

tsdx build --format amd

Who does this impact? Who is this for?

This behavior impact who need an AMD compatible bundle and code-splitting support

Describe alternatives you've considered

For now, the only alternative to having an AMD compatible bundle with code-splitting is to use Rollup directly

agilgur5 commented 3 years ago

Yes the lack of code-splitting in UMD also impacts #367; upstream in https://github.com/rollup/rollup/issues/3422#issuecomment-597822546 I was told it isn't currently supported as UMD lacks a way to load deps. I suppose the "ideas" mentioned there refer to the issues you linked.

Could you provide a rationale for why you want AMD output support as opposed to ESM or CJS? For a similar example, #788 was looking for IIFE support but found UMD usage satisfactory.

Each of the current build options has some of there own nuances, such as ESM not having dev/prod split vs CJS and UMD not being able to code-split. Adding another format option may add some more complexity if it has its own nuances as well (though I believe AMD can be treated the same way as CJS) which therein adds a maintenance and potential breakage burden (like #367 and UMD's lack of code-split). Browser ESM is fairly well-supported now and Node ESM support is growing, so I'm seeing less and less benefits of various formats over time in general as well.

marciel-truesoft commented 3 years ago

Hi, thanks for your time @agilgur5

Could you provide a rationale for why you want AMD output support as opposed to ESM or CJS?

I agree with you, as for today ESM is well-supported, but sometimes (and in my specific scenario) we need to deliver libraries to some fair old codebase that is heavily based on AMD, UMD output do this trick very well, though I still use tsdx and use to bundle targeting ESM (aka greenfield projects) the lack of code-split for UMD is really a blocker, so I keep a custom rollup config aside only for bundle targeting AMD.

agilgur5 commented 3 years ago

some fair old codebase that is heavily based on AMD

Gotcha, so basically just for legacy codebases. If your library does multiple formats (e.g. CJS, ESM, and AMD), how do you import AMD given the lack of ability to specify it in a package.json field? Or do you just import the build directly?

For CJS, TSDX uses the main field and outputs the dev/prod switch entry. That dev/prod entry is CJS so it would need a separate version for AMD. Support for just outputting the dev & prod AMD bundles can be added more simply I believe, but the package.json field I'm not sure about and an AMD dev/prod switch would take more time (I'm also in the middle of improving some issues with the dev/prod switch by rewriting it as a Rollup plugin). If you import the bundle directly, that shouldn't be a huge deal though.

A PR would be welcome for the simple version -- can see in #788 the place in the code that would need to be modified to add any new format (that and the build and watch CLIs need some small modifications). This would probably be less code than keeping a totally separate Rollup config 😅


Also, there are codemods to help convert AMD to ESM or CJS, e.g. jscodeshift + other scripts and this recast script. I had to do it a handful of years ago for a 10k+ LoC project before too.

jaredpalmer commented 3 years ago

Should we add iife? It's useful for building 3rd-party JS that is used in script tags (like embed widgets or analytics scripts)