# Vite plugin tricks
* [**`resolveConfig`**](https://github.com/brillout/vite-plugin-ssr/blob/v0.4.131/vite-plugin-ssr/node/plugin/plugins/config/index.ts): In `configResolved` with `enforce: 'pre'`, add a promise to resolve config object with the plugin's own config. This allows queueing some async operations AFTER resolving the config. In any later `configResolved` stage, use `await` on that async func. to get and memoize the "grand final" config object
* [**buildConfig.ts**](https://github.com/brillout/vite-plugin-ssr/blob/v0.4.131/vite-plugin-ssr/node/plugin/plugins/buildConfig.ts): Normalize `rollupOptions.input` from `string | string []| { [entryName: string]: string }` to Object
[**distFileNames.ts**](https://github.com/brillout/vite-plugin-ssr/blob/v0.4.131/vite-plugin-ssr/node/plugin/plugins/distFileNames.ts): Similar, but wrap single-element `output` to array
... for further tweaking; addition options can be attached with an Array.map
* [**packageJsonFile.ts**](https://github.com/brillout/vite-plugin-ssr/blob/v0.4.131/vite-plugin-ssr/node/plugin/plugins/packageJsonFile.ts): Add a `package.json` to out dir so that ESM can be correctly detected
* To discrimate between `build` and `dev`, let a variable `isDev = false` and set it to `true` in `configureServer` stage (only when a dev server is spinned up). It must be used in a later stage like `transform`.
Seen in **extractExportNamesPlugin.ts**.
> In `devConfig/index.ts` it is mentioned that ++"There doesn't seem to be a straightforward way to discriminate between `$ vite preview` and `$ vite dev`."++ The value of the `command` argument is "serve" in both cases.
# HTML transformations
> @ v4.4.7
**Hooks**: Default hooks are (where ... are collected through plugins in the resolved config):
1. Pre: `preImportMapHook` -> ... -> `htmlEnvHook`
2. Post: ... -> `postImportMapHook`
Hooks can be specified with `order` property being one of {pre/normal/post} to workaround that `enforce` property does not support the value "normal".
Import maps are `<script type="importmap">`.
HTML env is replacement of `%VITE_PREFIXED_ENV%`.
**[[html-proxy]]**: a reflection for adding/extracting some strings associated with the document, URL (matched against a regex!) being one form of
* #0 `foo.html?html-proxy&index=<index>.js`
* #1 `foo.html?html-proxy&inline-css&style-attr&index=<index>.css`
* #2 `foo.html?html-proxy&inline-css&index=<index>.css`
At the function `buildHtmlPlugin`, the working is tentatively described as following sections:
### To transform HTML
* Pre-transform: apply pre hooks
* Traverse over HTML AST generated through `parse5`, handling the cases:
* **A script tag**:
* public file: prefix public path, leave it as-is
* module: add the JS to entry point as an import statement
if external, extract the src
if inline, reference through [[html-proxy]] form #0
--> merge all modules to an equivalent single entry
* (not module && external && not public file): bail out (Vite only accepts ES modules)
* (not module && inline): collect inline import URLs through regex (*), stored as `scriptUrls`
> regex? seriously?
* A tag that **has attrs that are meant to be URLs** (img src, link href, ...): These are the *only* "assets", besides JS, the HTML directly depends on. Others are indirectly through CSS.
* For CSS, specifically `<link rel="stylesheet" src="...">`: Rewrite (eagerly) to JS import, stored in `styleUrls`.
> Ineffective link tags are ignored (with attr `media` or `disabled`).
> Original tag is not deleted. Which way to load it is determined later in (**-1).
* For others, store them as `assetUrls` and rewrite that URL to public path *later* (**-2).
* A tag **with "style" attr and inline style contains URL**: `url()` and `image-set()`: virtualize through [[html-proxy]] form #1, and add back a class.
> Q: changes (demotes) specificity?
* A **non-empty `<style>` tag**: Apply [[html-proxy]] form #2.
* Rewrite assets in (**-2) to built URLs if it is not empty and NOT referencing named output passed to rollup.
> This is complicated to explain here. See code!
* Rewrite script URLs (*) to built URLs or public path.
* Try to resolve stylesheet URLs in (**-1).
success: Remove corresponding `<link>`
failure: Undo; Remove the import statement already inserted.
* Prepend module preload polyfill if the `build.modulePreload.polyfill` is set and there are async/deferred script tags.
### To generate a bundle:
* Get base of HTML.
* "inject chunk asset links". (***)
An ES module can be inlined if it contains solely imports
* "inject css link when cssCodeSplit is false".
* Transform CSS stored through [[html-proxy]] of form #2.
* Apply normal and post hooks.
* "Resolve asset[/public] url references".
* Emit the HTML
* Remove all modules collected in (***) from bundle.
## Vite undocumented config:
`ssrEmitAssets: true`
https://github.com/vitejs/vite/blob/v4.3.9/packages/vite/src/node/build.ts#L228