vite-encore-plugin Svelte Themes

Vite Encore Plugin

A vite plugin to use Symfony Encore with Vite

Vite Encore Plugin

This is an experimental vite plugin to use Symfony Encore with Vite instead of Webpack. It produces an Encore compatible output but using Vite, so you can still using symfony/webpack-encore-bundle without additional dependencies.

Features

Installation

npm install -D vite-encore-plugin

Setup

After installing the plugin, add it to your vite config like follows:

// vite.config.mjs (ESM)
import { defineConfig } from "vite";
import viteEncorePlugin from "vite-encore-plugin";

export default defineConfig({
    // ...
    plugins: [viteEncorePlugin()],
});
// vite.config.cjs (CJS)
const { defineConfig } = require("vite");
const viteEncorePlugin = require("vite-encore-plugin");

module.exports = defineConfig({
    // ...
    plugins: [viteEncorePlugin()],
});

If you are using the Vite Dev Server, make sure the Vite Client script is rendered before the rest of entrypoints, otherwise they won't work. This plugin provides the @vite/client entrypoint if the dev server is enabled, so you can use it like follows:

{# templates/example.html.twig #}
{% if encore_entry_exists('@vite/client') %}
    {{ encore_entry_script_tags('@vite/client', attributes = { type: "module" }) }}
{% endif %}

Migration from Webpack Encore

Let's say you have the following webpack encore configuration

// webpack.config.cjs
const Encore = require('@symfony/webpack-encore');

if (!Encore.isRuntimeEnvironmentConfigured()) {
    Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}

Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .addEntry('app', './assets/app.js')
    .copyFiles({
        from: './assets/files',
    })
    .splitEntryChunks()
    .enableSingleRuntimeChunk()
    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    .enableVersioning(Encore.isProduction())
    ;

module.exports = Encore.getWebpackConfig();

The equivalent Vite config would be

// vite.config.cjs
const { defineConfig } = require("vite");
const viteEncorePlugin = require("vite-encore-plugin");

module.exports = defineConfig((config) => {
    return {
        appType: "custom",
        base: "/build",
        publicDir: "assets/files",
        build: {
            outDir: "public/build",
            rollupOptions: {
                input: {
                    "app": "./assets/app.js",
                }
            },
            sourcemap: config.mode !== "production",
        },
        plugins: [viteEncorePlugin()],
    };
});

Vite targets modules by default, so, you have the update your twig files to use module scripts like follows:

{# templates/example.html.twig #}
{{ encore_entry_script_tags('app', attributes = { type: "module" }) }}

Stimulus Bridge

If you're using the stimulus bridge with UX components, you probably have the following option in your webpack encore config.

// webpack.config.cjs
Encore.
    // ...
    .enableStimulusBridge('./assets/controllers.json');

This plugin also supports it, just update your code like follows:

// vite.config.cjs
viteEncorePlugin({
    enableStimulusBridge: {
        enabled: true,
        controllerJsonPath: "./assets/controllers.json"
    },
    // or just
    // enableStimulusBridge: true
}

If you're importing local controllers, your old bootstrap.js probably looks like this:

// bootstrap.js
import { startStimulusApp } from '@symfony/stimulus-bridge';

const app = startStimulusApp(require.context(
    '@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
    true,
    /\.(j|t)sx?$/
));

However, require.context only works with Webpack, so you have to update your code to import the controllers in the vite way.

/// <reference types="vite-encore-plugin/stimulus-bridge/overrides" />
// bootstrap.js
import { startStimulusApp } from '@symfony/stimulus-bridge';

const app = startStimulusApp(
    // @see https://vite.dev/guide/features.html#glob-import
    import.meta.glob("./controllers/**/*.{js,jsx,ts,tsx}", { import: "default" })
    // Or eager
    // import.meta.glob("./controllers/**/*.{js,jsx,ts,tsx}", { import: "default", eager: true })
);

The plugin overrides the @symfony/stimulus-bridge package to support Vite. However, you may prefer to use the plugin directly and remove the @symfony/stimulus-bridge dependency.

// bootstrap.js
import { startStimulusApp } from 'vite-encore-plugin/stimulus-bridge';

const app = startStimulusApp(
    import.meta.glob("./controllers/**/*.{js,jsx,ts,tsx}", { import: "default" })
);

Top categories

Loading Svelte Themes