Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

encore watch & Code Splitting

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Let's get Encore to build our assets! Do that by going back to the terminal and saying:

yarn watch

This reads our app.js file and outputs the final files into a public/build directory - you can see that here. Once it's done, it sits and watches for more changes. If we modify any files, it will rebuild the assets.

Let's try this! Find your browser and refresh! Woo! We have a gray background. That proves the CSS is being processed!

Seeing the Code Splitting

If you view the page source, you'll see one link tag for build/app.css and... cool! The JavaScript is already being split into three different files. The Twig function knows to render all of them. This is not something you really need to think or worry about - Webpack does this to help your users download the files faster and cache them better.

Moving our Styles

Before we keep going, let's move our real CSS - it's currently in public/styles/app.css - into the new app.css file that's being processed by Webpack. Open that up, copy everything inside, then delete the file entirely.

Now go to the new assets/styles/app.css, remove the gray background and paste!

@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap');
body {
font-family: 'Montserrat', sans-serif;
a, a:hover {
color: #000;
... lines 10 - 144

In base.html.twig, delete the link tag that pointed to the old static file.

Now... when we refresh, it still looks good! That's because, over at the terminal, Encore noticed that we changed the app.css file and automatically rebuilt things.

Installing Bootstrap CSS

While we're here, we also have a link tag that points to a Bootstrap CDN. That's okay, but we can now properly install bootstrap into our app. First, over at your terminal, open a new tab so that yarn watch can keep doing its thing in the background. Run:

yarn add 'bootstrap@^4.6' --dev

Two things. First, if you searched npmjs.com, you'd learn that the name of the package that gives you Bootstrap is... bootstrap! And second, that --dev flag isn't really important - it would be fine if you didn't include that.

This adds bootstrap to our package.json file and downloads it into the node_modules/ directory. Delete the old link tag... which temporarily will make our site look terrible.

Then go into app.css. On top, we can import this: import then ~bootstrap.

@import '~bootstrap';
... lines 2 - 145

That's it. Webpack will magically load all the bootstrap CSS and include it in the final, built app.css file. The tilde is a magic character that tells Webpack to look for a package in the node_modules/ directory. This is a special syntax that you only use inside CSS files.

Let's check it! Refresh now and... all better! View the source again. Woh! Even the CSS is being split into two files. I normally don't even think about this, but I wanted you to see it.

Oh, and these really long ugly filenames? When you build Encore for production, those will be very simple names, usually a number - like 55.js. It won't expose all these path details.

Next let's figure out how and where stimulus is installed and build our very first stimulus controller!

Leave a comment!

Login or Register to join the conversation
jmsche Avatar

As Boostrap 5 was not released when the tutorial was published, running yarn add bootstrap now installs Bootstrap 5.
Now you have to run yarn add bootstrap@^4.6.2 so it installs Bootstrap 4, which is used by the project.

1 Reply

Hey Jmsche,

Yeah, I agree, good catch! We will add a note about it, thanks for mentioning it


Macarena I. Avatar
Macarena I. Avatar Macarena I. | posted 2 years ago | edited

Hi!, I have the next error! Please help!
`macarena@macarena-HP-Laptop-15-dw2xxx:~/marie$ yarn watch
yarn run v1.22.10
$ encore dev --watch
Running webpack ...

Error: Encore.enableStimulusBridge is not a recognized property or m ethod.

  • webpack.config.js:27 Object.<anonymous>

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.


Hi Macarena I.!

Hmm. I'm not sure why you would be getting this, but I know the cause: your version of @symfony/webpack-encore is too old (it looks like you have a version from before the enableStimulusBridge() was added). Try running yarn upgrade "@symfony/webpack-encore" - you'll need at least version 0.32.0, but I'd highly recommend upgrading to the latest 1.4.

Let me know if that helps!


Macarena I. Avatar

Yes!!!! It Works!!!! Thanks!

Michael H. Avatar
Michael H. Avatar Michael H. | posted 2 years ago

When doing this course on Windows, i had to manually download the core-js node_module because the yarn install would only download folders that have one readme.md file and nothing else. This only happened for core-js, all other modules where downloaded fine.


Ohh Windows... when will it behave as it should? Are you on WSL or just Windows?

Default user avatar
Default user avatar Ondřej Frei | posted 2 years ago

Hello, thank you for this amazing tutorial! One thing puzzles me though - why is it recommended to add the dependency on Bootstrap with the --dev flag? Wouldn't that mean that with prod dependencies only, webpack would fail to build it?


Hey Ondřej Frei

That's a great question, in theory, the idea behind this is compiling your assets should be part of your deployment workflow and not rely on doing that directly on your production server, if you do that, then, you won't have to install Nodejs nor Yarn in your production server but that's up to you. You can move those assets to the non-dev key and it should not affect anything


Default user avatar
Default user avatar Ondřej Frei | MolloKhan | posted 2 years ago | edited

Thank you MolloKhan! So I suppose I just have too much of a composer-like view on it? Meaning that we only build the JS and do not run it on a node server, all of the dependencies could technically be --dev ones, because there is no "run" time?


Yes, exactly, all the JS deps can be required as dev. On deploy, you only have to run yarn install and after that, you can forget everything about Yarn. As I said, if you have a CD server, you could compile your assets there and then copy the whole node_modules directory to the production server, this is great because the prod server won't have to install Nodejs and else.

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial works perfectly with Stimulus 3!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "", //
        "doctrine/annotations": "^1.0", // 1.11.1
        "doctrine/doctrine-bundle": "^2.2", // 2.2.3
        "doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
        "doctrine/orm": "^2.8", // 2.8.1
        "phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
        "sensio/framework-extra-bundle": "^5.6", // v5.6.1
        "symfony/asset": "5.2.*", // v5.2.3
        "symfony/console": "5.2.*", // v5.2.3
        "symfony/dotenv": "5.2.*", // v5.2.3
        "symfony/flex": "^1.3.1", // v1.18.5
        "symfony/form": "5.2.*", // v5.2.3
        "symfony/framework-bundle": "5.2.*", // v5.2.3
        "symfony/property-access": "5.2.*", // v5.2.3
        "symfony/property-info": "5.2.*", // v5.2.3
        "symfony/proxy-manager-bridge": "5.2.*", // v5.2.3
        "symfony/security-bundle": "5.2.*", // v5.2.3
        "symfony/serializer": "5.2.*", // v5.2.3
        "symfony/twig-bundle": "5.2.*", // v5.2.3
        "symfony/ux-chartjs": "^1.1", // v1.2.0
        "symfony/validator": "5.2.*", // v5.2.3
        "symfony/webpack-encore-bundle": "^1.9", // v1.11.1
        "symfony/yaml": "5.2.*", // v5.2.3
        "twig/extra-bundle": "^2.12|^3.0", // v3.2.1
        "twig/intl-extra": "^3.2", // v3.2.1
        "twig/twig": "^2.12|^3.0" // v3.2.1
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.0
        "symfony/debug-bundle": "^5.2", // v5.2.3
        "symfony/maker-bundle": "^1.27", // v1.30.0
        "symfony/monolog-bundle": "^3.0", // v3.6.0
        "symfony/stopwatch": "^5.2", // v5.2.3
        "symfony/var-dumper": "^5.2", // v5.2.3
        "symfony/web-profiler-bundle": "^5.2" // v5.2.3

What JavaScript libraries does this tutorial use?

// package.json
    "devDependencies": {
        "@babel/preset-react": "^7.0.0", // 7.12.13
        "@popperjs/core": "^2.9.1", // 2.9.1
        "@symfony/stimulus-bridge": "^2.0.0", // 2.1.0
        "@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/Resources/assets", // 1.1.0
        "@symfony/webpack-encore": "^1.0.0", // 1.0.4
        "bootstrap": "^5.0.0-beta2", // 5.0.0-beta2
        "core-js": "^3.0.0", // 3.8.3
        "jquery": "^3.6.0", // 3.6.0
        "react": "^17.0.1", // 17.0.1
        "react-dom": "^17.0.1", // 17.0.1
        "regenerator-runtime": "^0.13.2", // 0.13.7
        "stimulus": "^2.0.0", // 2.0.0
        "stimulus-autocomplete": "^2.0.1-phylor-6095f2a9", // 2.0.1-phylor-6095f2a9
        "stimulus-use": "^0.24.0-1", // 0.24.0-1
        "sweetalert2": "^10.13.0", // 10.14.0
        "webpack-bundle-analyzer": "^4.4.0", // 4.4.0
        "webpack-notifier": "^1.6.0" // 1.13.0