Usage tips 💡
If you want to install the bundle without the community recipe, check the manual installation.
CSS file entrypoints
This section talks about FOUC (Flash of Unstyled Content) in development mode only. This phenomenon should not occur in production builds.
By default, if you import your css files from a js entry point, the vite dev server creates only one entrypoint (<script src="http://localhost:5173/build/assets/app.js" type="module"></script>
) for your js and css files. Your css content will be loaded after. This results in a small period of time where the content of the page will not be styled.
You can however provide a css/scss/... file as an entrypoint and it will be directly inserted as a link tag <link rel="stylesheet" href="http://localhost:5173/build/assets/theme.scss">
. This way, your browser will wait for the loading of your theme.scss
file before rendering the page.
export default defineConfig({
// ...your config
build: {
rollupOptions: {
input: {
theme: "./assets/theme.scss"
},
}
},
});
TIP
Make sure to still add the two Twig functions vite_entry_link_tags / vite_entry_script_tags even if the entry point is a css file because in development mode Vite will need to insert its js code to activate the HMR.
{% block stylesheets %}
{{ vite_entry_link_tags('theme') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('theme') }}
{% endblock %}
will render
<script src="http://localhost:5173/build/@vite/client" type="module">
<link rel="stylesheet" href="http://localhost:5173/build/assets/theme.scss">
during development.
Docker
If you are using Docker for your Symfony development and running your node commands in a container, you will need to make some configuration adjustments.
Let's take the example with an image node:21-alpine
.
docker run
--rm \
-ti \
--user $(id -u):$(id -g) \
-v $(pwd):/app \
-p 5173:5173 \
-w /app \
node:21-alpine \
npm run dev
// vite.config.js
export default defineConfig({
server: {
// Required to listen on all interfaces
host: '0.0.0.0'
},
plugins: [
symfonyPlugin({
// as we set `server.host` to 0.0.0.0
// we must explicitly set the server host name
viteDevServerHostname: 'localhost'
}),
],
build: {
rollupOptions: {
input: {
app: "./assets/app.js"
},
}
},
});
An example configuration with Docker can be found in the Symfony Vite Dev sandboxes.
You can learn more by following this Github discussion.
Dependency Pre-Bundling 🏃
In a standard Vite project, index.html
is the entry point to the application. When you run dev serve, Vite will crawl your source code and automatically discover dependency imports.
Because we don't have an index.html
in Symfony projects, Vite can't do this pre-bundling step when it starts. This means when you browse a page where it finds a package it does not already have cached, Vite will re-run the dep bundling process and reload the page.
This behavior can be annoying if you have a lot of dependencies because it creates a lot of page reloads before getting to the final render.
You can limit this by declaring your project's most common dependencies in vite.config.js
:
// vite.config.js
export default defineConfig({
server: {
// Set to true to force dependency pre-bundling.
force: true,
},
// ...
optimizeDeps: {
include: ["my-package"],
},
});
Configure splitting files per entry point 📦
Vite tries to split your js files into multiple smaller files shared between entry points. To configure the exact splitting one can define a manualChunks
function in rollupOptions
, refer to rollup docs on manual chunks for more details.
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: (id: string, {getModuleInfo, getModuleIds}) => {
// your code
},
},
},
},
});
https / http in Development 🔒
Your Vite dev server can cause unwanted reload (and mixed content warnings) if used in http and your Symfony application uses https (probably due to invalid certificates). Configuration is easier if you develop your application without https.
npm run dev
symfony serve --no-tls
browse : http://127.0.0.1:8000
If you still want to use https, you can use one of the two options below.
Use symfony cli certificate
First, enable symfony-cli TLS if you haven't done it yet.
// vite.config.js
import fs from "fs";
import { join } from 'node:path';
import { homedir } from 'node:os';
export default defineConfig({
// ...
server: {
https: {
pfx: join(homedir(), '.symfony5/certs/default.p12'),
},
cors: true
},
});
TIP
If you get TLS related errors when launching the dev server, this might be caused by an old symfony-cli version/node <17 version combination. To fix this, you can either:
- prepend
NODE_OPTIONS=--openssl-legacy-provider
to yourdev
npm script - delete your current certificate and restart your server (full details here)
Generate custom certificates
With mkcert
mkcert -install
mkcert -key-file certs/vite.key.pem -cert-file certs/vite.crt.pem localhost 127.0.0.1
// vite.config.js
import fs from "fs";
export default defineConfig({
// ...
server: {
https: {
key: fs.readFileSync('certs/vite.key.pem'),
cert: fs.readFileSync('certs/vite.crt.pem'),
},
cors: true
},
});
npm run dev
symfony serve
browse : https://127.0.0.1:8000