vite and vite-plugin-svelte can be made more verbose by using the debug mode (powered by and following the conventions of the debug library):
DEBUG=vite-plugin-svelte:config vite dev: logvite-plugin-sveltedebug info related to the configDEBUG=vite-plugin-svelte:* vite dev: log allvite-plugin-sveltedebug infoDEBUG=* vite dev: log all debug info
Preservation of local component state after JS updates is disabled to avoid unpredictable and error-prone behavior. Since svelte-5, hmr is integrated in compileOptions, but the sentiment in the previously used svelte-hmr docs still applies.
Please note that if you only edit the <style> node, a separate CSS update can be applied where component state is 100% preserved.
The <style> node should be last to ensure optimal HMR results. This is also the default order with prettier-plugin-svelte.
Good:
<script></script>
<div></div>
<style></style>Bad:
<script></script>
<style></style>
<!-- this template element is below the style node and may cause extra HMR updates -->
<div></div>You have to use the lang="ts" attribute for Vite to parse it. Never lang="typescript" or type="text/typescript".
Good:
<script lang="ts"></script>Bad:
<!-- These are not detected by Vite -->
<script lang="typescript"></script>
<script type="text/typescript"></script>The output of this function is part of the js module for the component. If the hash changes when css changes, every css update also triggers a js update. These js updates can lead to application state resetting in your browser, which is a worse developer experience than only css updating. It must also be different between different components to ensure that styles are scoped and updates applied correctly.
So it is recommended to keep the pattern defined by Svelte itself. If you want to customize the prefix, use this:
// svelte.config.js
export default {
compilerOptions: {
cssHash: ({ hash, filename, css }) => `my-custom-prefix-${hash(filename ?? css)}`
}
};If you don't want the hash to depend on filename, either accept the worse dx or customize cssHash only during build.
You don't have to anymore. See advanced usage for examples how to put transform hooks before or after Svelte preprocess or compile
Prebundling dependencies is an optimization in Vite.
We only use prebundling during development, the following does not apply to or describe the built application
It is required for CJS dependencies, as Vite's development server only works with ES modules on the client side. Importantly for Svelte libraries and ES modules, it also reduces the number of http requests when you load a page from the dev server and caches files so subsequent starts are even faster.
The way prebundling Svelte libraries affects your dev-server load times depends on the import style you use, index or deep:
Offers better DX but can cause noticable delays on your machine, especially for libraries with many files.
import { SomeComponent } from 'some-library'
+ only one request per library
+ intellisense for the whole library after first import
- compiles the whole library even if you only use a few components
- slower build and dev-server ssrOffers snappier dev and faster builds for libraries with many files at the expense of some DX
import SomeComponent from 'some-library/src/SomeComponent.svelte'
+ compiles only the components you import
+ faster build and dev-server ssr
- one request per import can slow down initial load if you use a lot of components
- intellisense only for imported componentsDo not use it in combination with prebundling!
Prebundling works by reading your .svelte files from disk and scanning them for imports. It cannot detect
added/changed/removed imports and these then cause extra requests, delays and render the prebundled files from the initial scan moot.
If you prefer to use these tools, please exclude the libraries you use them with from prebundling.
If you want to disable prebundling for a single library, use optimizeDeps.exclude
// vite.config.js
export default defineConfig({
optimizeDeps: {
exclude: ['some-library'] // do not pre-bundle some-library
}
});Or disable it for all Svelte libraries
// svelte.config.js
export default {
vitePlugin: {
prebundleSvelteLibraries: false
}
};There is no golden rule, but you can follow these recommendations:
- Never combine plugins or preprocessors that rewrite imports with prebundling
- Start with index imports and if your dev-server or build process feels slow, run the process with
DEBUG="vite-plugin-svelte:stats"to check compile stats to see if switching to deep imports can improve the experience. - Do not mix deep and index imports for the same library, use one style consistently.
- Use different import styles for different libraries where it helps. E.g. deep imports for the few icons of that one huge icon library, but index import for the component library that is heavily used.
This warning only occurs if you use non-default settings in your vite config that can cause problems in combination with prebundleSvelteLibraries. You should not use prebundleSvelteLibraries during build or for ssr, disable one of the incompatible options to make that warning (and subsequent errors) go away.
You really shouldn't. Svelte and Vite are esm first and the ecosystem is moving away from commonjs and so should you. Consider migrating to esm.
In case you have to, you can rely on node's "require esm" feature available in v20.19+
// vite.config.cjs
const { defineConfig } = require('vite');
const { svelte, vitePreprocess } = require('@sveltejs/vite-plugin-svelte');
module.exports = defineConfig({
plugins: [svelte({ preprocess: vitePreprocess() })]
});If you see a warning logged for this when using a Svelte library, please tell the library maintainers.
Using the svelte field in package.json to point at .svelte source files is deprecated and you must use a svelte export condition.
vite-plugin-svelte 3 still resolves it as a fallback, but in a future major release this is going to be removed and without exports condition resolving the library is going to fail.
Example:
// package.json
"files": ["dist"],
"svelte": "dist/index.js",
+ "exports": {
+ ".": {
+ "svelte": "./dist/index.js"
+ }
}You can also add individual exports of .svelte files in the exports map which gives users a choice to also use deep imports. See the faq about vite and prebundling why they can be useful at times.
Library authors are highly encouraged to update their packages to add the new exports condition as outlined above. Check out svelte-package which already supports it.
For backwards compatibility, you can keep the
sveltefield in addition to theexportscondition. But make sure that both always resolve to the same files.
This is not supported out of the box. To resolve assets, you have to either import them like this:
<script>
import assetUrl from './asset.png';
</script>
<img src="{assetUrl}" />or use a separate tool to add this functionality. The 2 recommended solutions are sveltejs/enhanced-img (only for image elements) and svelte-preprocess-import-assets (for all asset URLs).