vite-plugin-svelte icon indicating copy to clipboard operation
vite-plugin-svelte copied to clipboard

Support emitting preprocessed .svelte files

Open dominikg opened this issue 1 year ago • 3 comments

Describe the problem

svelte-package currently does not read vite config at all and doesn't understand our useVitePreprocess option as a result.

This can lead to a divergence in library projects that use vite plugins like unocss or windicss for styles which look just fine in the preview during pnpm dev, but preprocessed output isn't working and a companion global css file can't be created efficiently

See https://github.com/unocss/unocss/pull/1725 for a draft of a custom preprocessor to solve it for unocss, but the problem is of a more general nature and we might want to offer tooling so that it can be solved with less effort.

Describe the proposed solution

1. idea by @bluwy: a new ?preprocess directive

const server = createServer()
const output = await server.ssrLoadModule('/User/foo/Component.svelte?preprocess')
console.log(output.preprocessed)

Which allows svelte-package and friends to glob .svelte files and then call ssrLoadModule on them to get the preprocessed output of each one

2. a custom build option

add an option to output preprocessed .svelte files to a separate directory alongside compiled code via a rollup output hook The output of vite build can then be used to get the preprocessed code

Alternatives considered

Somehow add a preprocessor to svelte.config.js that allows uses vite+svelte under the hood, kind of the inverse of the above, but this risks inception

Importance

nice to have

dominikg avatar Oct 18 '22 20:10 dominikg

cc @bluwy @dummdidumm @ignatiusmb

dominikg avatar Oct 18 '22 21:10 dominikg

Thank you, @dominikg! Since Vite plugins are becoming so valuable and useful as of late, it would be great if they could be used for dev, build, and svelte-package.

For context here is my PR https://github.com/unocss/unocss/pull/1725 for the temporary svelte preprocessor wrapper I had to write which inits UnoCSS and then imports the transformSvelteSFC method. It actually wasn't too difficult to write this wrapper, but in the long run I'd rather use the Vite plugin instead for a few reasons:

  • no need to support two methods of using UnoCSS's svelte-scoped mode (a Vite plugin for normal projects, and a Svelte preprocessor for component libraries that will be packaged)
  • can take advantage of the Uno Inspector found at /__unocss when running the dev server. A Svelte preprocessor can't do this like a Vite plugin can.
  • UnoCSS's custom transform directives can all be used. Due to how they work in Uno, I was not able to support them in the preprocessor wrapper and manually added just the one I needed which handles @apply in style blocks.
  • A Vite plugin can behave differently based on serve vs. build. A Svelte preprocessor presently has no way to distinguish between these modes as the latest version of the Vite dev server does not consistently set process.env.NODE_ENV to development. In my context I would like to use this distinction for a small dev perk which is not important to explain here. Presently the mode must be set using cross-env NODE_ENV=... which just makes things more difficult for others who also want to implement UnoCSS in a component library.

I don't have enough knowledge to give advice on how to accomplish the task proposed in this issue but I can help test things out as helpful.

jacob-8 avatar Oct 19 '22 09:10 jacob-8

related work: https://github.com/sveltejs/vite-plugin-svelte/tree/preprocess-api contains an export for standalone preprocessors unsing vite config, these could be used to generate the preprocessed output without additional features in v-p-s.

It may still be nicer to offer a way to do this as part of a vite build to be able to produce extra resources alongside, eg the aforementioned styles generated by unocss.

dominikg avatar Nov 06 '22 10:11 dominikg