esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

Question: `transform` stage in plugins.

Open hyrious opened this issue 3 years ago • 5 comments

This question is about plugin composition, I used to be curious why rollup has 3 essential steps: resolveId, load, transform, now I have an answer: Plugins can be composited by doing different step.

Say we have a svelte plugin and a virtual icons plugin, which creates virtual module in your code and you just import it and use:

<script>
import PlusIcon from "virtual-icon:mdi-plus.svelte"
</script>
<PlusIcon />

If it is in rollup, the two plugins can be composited by:

icons plugin: resolve & load(virtual-name) => svelte code
svelte plugin: transform(svelte code) => js & css

Only the svelte plugin has to call svelte-compiler, so we can put compiler options (like whether to generate SSR code) in one place.

However, in esbuild plugins, we must do all works in onLoad, the icons plugin now has to call svelte-compiler, and we must pass compiler options to all of them.

There are other ways to deal with the same problem, for example:

  • let the svelte plugin export a global state called virtual files, then let the icons plugin put these virtual files into that state. Now the icons plugin has a dependency of svelte plugin.
  • let plugins can define custom loaders, like loader: 'svelte', so that its onLoad can receive contents from other plugins.

I'm not sure which is the correct way to handle this usage.

hyrious avatar Jan 02 '22 10:01 hyrious

Yes, I should do this. The general workaround right now is to have one plugin wrap the other and emulate esbuild's API but that sucks obviously.

evanw avatar Jan 07 '22 14:01 evanw

In addition to the plugin enhancement, I found another requirement that help to get rid of "bundle twice" -- by enforce the order.

Not too many, only an enforce: post should be enough. For example the unocss plugin generates a virtual css file in your final bundle, but it needs to wait for all sources to be scanned (in transform hook) to really load the generated css code.

hyrious avatar Jan 16 '22 06:01 hyrious

Sorry for the bump, but is there a package that handles the manual daisy-chaining of plugins for me?

edit: using esbuild-rna for now...

aleclarson avatar Feb 24 '23 01:02 aleclarson

I need this for a plugin I'm writing which minifies the contents of specific template strings.

easrng avatar May 06 '24 21:05 easrng

@easrng I wrote a package that might help you: https://github.com/aleclarson/esbuild-extra

aleclarson avatar May 06 '24 22:05 aleclarson