Note: I wrote this draft quite awhile ago. Rather than leave it in a draft forever, I’m going to publish the incomplete version.
A few weeks ago I heard that Svelte 3 had been released. After poking around with it, Svelte is quickly becoming my favorite JavaScript framework. While I was playing around I setup Svelte and Symfony to work together. If you aren’t interested in reading a post and just want to see the code, it’s in voldemortensen/symfony-svelte-example on my GitHub.
The rest of this post assumes that you already have composer and npm (or yarn) installed.
Let’s use symfony/website-skeleton to get started. In terminal:
composer create-project symfony/website-skeleton symfony-svelte-example && cd symfony-svelte-example
For the Svelte bits let’s use Encore to configure Webpack. Encore is a great tool for using Webpack to build assets for use with Symfony. In terminal:
composer require symfony/webpack-encore-bundle
then
npm i
then
npm i --save-dev svelte-loader svelte
At this point everything we need to install is installed. Now let’s get the config setup. In webpack.config.js add this after .setOutputPath and .setPublicPath:
.addLoader({
test: /\.svelte$/,
loader: 'svelte-loader',
})
and this at the end of the file after removing the default module.exports line:
let config = Encore.getWebpackConfig(); config.resolve.mainFields = ['svelte', 'browser', 'module', 'main']; config.resolve.extensions = ['.mjs', '.js', '.svelte']; let svelte = config.module.rules.pop(); config.module.rules.unshift(svelte); module.exports = config;
With all the configuration setup, let’s get to the code. We need to get a route setup. In terminal:
php bin/console make:controller
This will prompt you to give a name for the controller. Personally, I use DefaultController for /.
In src/Controller/DefaultController.php find the line with @Route("/default", name="default") and change it to @Route("/", name="default).
In templates/default/index.html.twig, delete everything and replace it with this:
{% extends 'base.html.twig' %}
{% block title %}Hello Symfony + Svelte!{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block body %}
{% endblock %}
In assets/js/app.js, delete the console.log line and add this at the end of the file:
import App from './App.svelte';
const app = new App({
target: document.body,
});
And for the final bit, create assets/js/App.svelte and add this:
<h1>Symfony + Svelte = <3</h1>
<style>
h1 {
text-align: center;
color: #D26D26;
}
</style>
<script>
import { onMount } from 'svelte';
onMount(() => {
console.log(`Hello, Symfony + Svelte!`);
});
</script>