Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Webpack dev-server: Faster Updating

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Before we keep going further with Vue, I want to show you a really fun feature of Webpack that Vue works perfectly with. It does require some setup, but I think you're going to love it!

Find your terminal. Right now, we're running yarn watch. Hit Control + C to stop it.

When you run yarn watch or yarn dev or yarn build - which builds your assets for production - Webpack reads the files in the assets/ directory, processes them, and dumps real files into public/build/. If you look at the HTML source of the page, our script and link tags point to these physical files. So we have a build process, but it builds real files and our browser ultimately downloads static CSS and JS content.

This is great, but there's another way to run Webpack while developing. It's called the dev-server. It should be easy to use but, as you'll see, if you have a more complex setup or use Docker, it might require extra messing around.

Running the dev-server

Anyways, let's try this fancy dev-server. Instead of yarn watch, run, you guessed it, yarn dino-server:

yarn 🦖-server

Nope, that won't work. But dang! I wish we had added that to Encore! Missed opportunity. Run:

yarn dev-server

Just like with yarn watch, this dev-server command works thanks to a scripts section in our package.json file, which Encore gives you when you install it. dev-server is a shortcut for encore dev-server.

Back at the terminal, interesting. It says "Project running at http://localhost:8080" and "webpack output is served from http://localhost:8080/build".

When you run the dev-server, Webpack does not output physical files into the public/build directory. Well, there are two JSON files that Symfony needs, but no JavaScript, CSS or anything else. These do not exist.

Instead, if you want to access these, you need to go to http://localhost:8080 - which hits a web server that the command just launched. Well, this "homepage" doesn't work - but we don't care. Try going to /build/app.js.

This is our built app.js JavaScript file! Here's the idea: instead of outputting physical files, Webpack makes everything available via this localhost:8080 server. If we, on our site, can change our script and link tags to point to this server, it will load them.

And... I've got a surprise! When we refresh the homepage... woh! The site still works! Check the HTML source. Nice! All the link and script tags automagically point to localhost:8080/.

So, on a high level, this is cool, but not that interesting yet. Instead of Webpack creating physical files, it launches a web server that hosts them... and our Symfony app is smart enough to point all of our script and link tags at this server. But the end result is more of less the same as yarn watch: when we update some JavaScript or CSS code, we can immediately refresh the page to see the changes.

dev-server & HTTPS

But... the dev-server opens up some interesting possibilities. First, you might notice that a bunch of Ajax requests are failing on this page. It's some sockjs-node thing from that dev server. One of the super powers of the dev server is that it can automatically update the JavaScript and CSS in your browser without you needing to reload the page. To do that, it makes a connection back to the dev-server to look for changes.

This if failing because it's trying to use https for the Ajax call and, unless you configure it, the dev-server only works for http. And it's trying to use https because our page is running on https.

So there are 2 ways to fix this. First, you could configure the Webpack dev server to allow https. If you're using the Symfony web server like we are, this is actually pretty easy - the yarn dev-server command just gets longer:

yarn dev-server --https --pfx=$HOME/.symfony/certs/default.p12

That tells the dev-server to allow https and to use the same SSL certificate as the Symfony dev server.

The other option, which is not quite as cool, but will definitely work, is to access your site with http so that this request also uses http.

When we originally started the Symfony web server, we started it with symfony serve -d and then --allow-http. This means that the web server supports https, but we're allowed to use http. Once we change to http in the URL... the Ajax call starts working!

If you have a more complex setup, like you need to change the host name or have CORS issues, check out the Encore dev-server docs or drop us a question in the comments. But ultimately, if the dev-server is giving you problems, don't use it! It's just a nice thing to have.

Automatic Reloading

Why? Head over to your terminal, open products.vue and... let's see... I'll make my favorite change: adding some exclamation points! I'll save then move back to my browser.

Tip

If you're using Webpack Encore 1.0 or higher, the page will not automatically reload anymore. But that's ok: that's been disabled to show something even cooler, which we'll talk about in the next video.

Nice! The page refreshed for me. If I remove those exclamation points and come back, it did it again! Ok, that's kinda cool: as soon as it detects a change, it automatically reloads.

But... we can get cooler! We can avoid the site from refreshing at all with one simple flag. Let's see that next.

Leave a comment!

14
Login or Register to join the conversation
Valentin-D Avatar
Valentin-D Avatar Valentin-D | posted 3 months ago | edited

Here's a quick fix for those of you using a virtual host:

` // webpack.config.js

.configureDevServerOptions(options => {
    options.proxy = {
        '/': {
            target: 'https://myproject.local',
            changeOrigin: true,
            logLevel: 'debug',
        },
    };
})`

Then run

yarn encore dev-server --host myproject.local
OR
yarn dev-server --host myproject.local

yarn dev-server --host myproject.local --hot

Reply

Thanks for posting that! The dev server can be a pain when it comes to this host stuff (that's why I show watch more often... even though dev-server is more awesome ;) )

Reply
davidmintz Avatar
davidmintz Avatar davidmintz | posted 1 year ago | edited

I am working on a Symfony 6 project and trying to get the Webpack/Encore dev server to use https. I have set it up exactly as indicated at https://symfony.com/doc/current/frontend/encore/dev-server.html#enabling-https-using-the-symfony-web-server, and when I run yarn dev-server, the output is

`yarn dev-server
yarn run v1.22.19
$ encore dev-server
Running webpack-dev-server ...

[webpack-dev-server] SSL certificate: /opt/www/shrinksoffice/node_modules/.cache/webpack-dev-server/server.pem
[webpack-dev-server] Project is running at:
[webpack-dev-server] Loopback: https://localhost:8080/, https://127.0.0.1:8080/
[webpack-dev-server] Content not from webpack is served from '/opt/www/shrinksoffice/public' directory
[webpack-dev-server] 404s will fallback to '/index.html'
DONE Compiled successfully in 1814ms `

which looks about right, doesn't it?

But when I load my app's main page into a browser, there is a CSS-less and JS-less skeleton -- because the output of my twig base template's encore_entry_link_tags() and encore_entry_script_tags() say http (not https), and the debug console says error loading failed for the <script> http://localhost/[etc]. When I do load, e.g., https://localhost:8080/build/runtime.js directly with my browser, boom! There it is, as it should be. So I guess I am having trouble getting -- Twig? Encore? -- to get the memo that we are using https.

HOWEVER! When I use the old deprecated --https option, yeah it works, but with a deprecation warning that I would like to be rid of.

Any suggestions? Thanks.

Reply

Hey davidmintz

I believe Symfony forgot how to read memos :p
I'd expect it to grab the URL schema from the request but it's not doing it for some reason. What you can do is to configure the base_url by adding this config


// framework.yaml
framework:
    assets:
        base_urls:
            - '%site_base_url%'

You only need to set up the site_base_url parameter to point to your domain (or localhost) e.g.


// services.yaml
parameters:
    site_base_url: 'https://localhost:8080'

you may want to use an environment variable instead so you can tweak its value easily when you deploy to production

Cheers!

Reply
davidmintz Avatar
davidmintz Avatar davidmintz | MolloKhan | posted 1 year ago | edited

Thanks for the reply!
So, in services.yaml I have added

site_base_url: 'https://localhost:8080'

under the key parameters.

In framework.yaml, under the key framework, I added:


assets:
     base_urls:
      - '%site_base_url%'

I cleared the cache just for good measure, and stopped and restarted dev-server and the symfony http server. The result I'm getting is still the same, i.e., symfony does not seem to be picking up the <b>https</b>; the template still says, e.g., http://localhost:8080/build/runtime.js. Don't know what I'm doing wrong, if anything.

This is with Symfony 6.0.10. Do you think upgrading to 6.1 might help?

Reply

Hey davidmintz

I had to do some research about this. I believe this is a bug on Webpack (or perhaps on Symfony Encore I couldn't get to the root of the problem), when you start Webpack's dev server using the new flag --server-type https the routes inside the file public/build/entrypoints.json are not pointing to HTTPS, but if you use the deprecated flag --https then, the routes will be generated as expected.
So, something inside Webpack is not detecting the HTTPS flag at the moment of generating the entrypoints.json file. I'd recommend using the deprecated flag and wait for the next Encore version, it may get fixed - or, if you feel proactive, you can create an issue on the Encore project :)

Cheers!

Reply
davidmintz Avatar

Isn't that interesting! Thanks.

1 Reply

It feels great when you find a bug in a core library :)

1 Reply
akincer Avatar
akincer Avatar akincer | posted 2 years ago | edited

The https option resulted in this error. It's not going to stop me from continuing since I can just use http.

Error: not enough data

Reply

Hey Aaron,

Thanks for sharing your workaround with others!

Cheers!

Reply
Sargath Avatar
Sargath Avatar Sargath | posted 3 years ago | edited

For those who prefer npm instead of yarn, use it like that npm run dev-server -- --https --pfx=$HOME/.symfony/certs/default.p12

Reply

Hey Sargath

Isn't there an extra `--`?

Reply
Sargath Avatar

Yes there should be an extra `--` https://stackoverflow.com/a...

1 Reply

Cool, great I just wanted to clarify :)

Reply
Cat in space

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

This course is also built to work with Vue 3!

What JavaScript libraries does this tutorial use?

// package.json
{
    "devDependencies": {
        "@symfony/webpack-encore": "^0.30.0", // 0.30.2
        "axios": "^0.19.2", // 0.19.2
        "bootstrap": "^4.4.1", // 4.5.0
        "core-js": "^3.0.0", // 3.6.5
        "eslint": "^6.7.2", // 6.8.0
        "eslint-config-airbnb-base": "^14.0.0", // 14.1.0
        "eslint-plugin-import": "^2.19.1", // 2.20.2
        "eslint-plugin-vue": "^6.0.1", // 6.2.2
        "regenerator-runtime": "^0.13.2", // 0.13.5
        "sass": "^1.29.0", // 1.29.0
        "sass-loader": "^8.0.0", // 8.0.2
        "vue": "^2.6.11", // 2.6.11
        "vue-loader": "^15.9.1", // 15.9.2
        "vue-template-compiler": "^2.6.11", // 2.6.11
        "webpack-notifier": "^1.6.0" // 1.8.0
    }
}
userVoice