If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeBefore 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.
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.
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.
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.
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 ;) )
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.
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!
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?
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!
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
For those who prefer npm
instead of yarn
, use it like that npm run dev-server -- --https --pfx=$HOME/.symfony/certs/default.p12
// 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
}
}
Here's a quick fix for those of you using a virtual host:
` // webpack.config.js
Then run
yarn encore dev-server --host myproject.local
OR
yarn dev-server --host myproject.local
yarn dev-server --host myproject.local --hot