WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:02.026 --> 00:00:04.716 align:middle
View the HTML source and search for app.js.

00:00:07.036 --> 00:00:11.236 align:middle
Surprise! We have multiple script tags!

00:00:11.706 --> 00:00:15.496 align:middle
Actually, let me go to the
inspect - it's a bit prettier.

00:00:16.656 --> 00:00:18.366 align:middle
Black magic!

00:00:18.556 --> 00:00:25.736 align:middle
We have two script tags - one for
app.js but also one for vendors~app.js.

00:00:25.736 --> 00:00:28.456 align:middle
What the heck?

00:00:29.226 --> 00:00:31.236 align:middle
Go look at the public/build/ directory.

00:00:31.756 --> 00:00:35.716 align:middle
Yeah, there is a vendors~app.js file.

00:00:36.496 --> 00:00:38.466 align:middle
I love this feature.

00:00:39.446 --> 00:00:41.406 align:middle
Check out webpack.config.js.

00:00:42.066 --> 00:00:47.236 align:middle
One of the optional features that came
pre-enabled is called splitEntryChunks().

00:00:47.746 --> 00:00:49.566 align:middle
Here's how it works.

00:00:49.566 --> 00:00:53.966 align:middle
We tell Webpack to read app.js,
follow all the imports,

00:00:54.226 --> 00:01:00.066 align:middle
then eventually create one
app.js file and one app.css file.

00:01:00.756 --> 00:01:05.356 align:middle
But internally, Webpack uses an
algorithm that, in this case,

00:01:05.776 --> 00:01:10.846 align:middle
determines that it's more efficient
if the one app.js file is split

00:01:10.846 --> 00:01:15.466 align:middle
into two: app.js and vendors~app.js.

00:01:15.466 --> 00:01:20.786 align:middle
And then, yea, we need two
scripts tags on the page.

00:01:21.496 --> 00:01:23.436 align:middle
That may sound...

00:01:23.436 --> 00:01:24.606 align:middle
odd at first...

00:01:24.896 --> 00:01:31.186 align:middle
I mean, isn't part of the point of Webpack to
combine all our JavaScript into a single file

00:01:31.546 --> 00:01:35.726 align:middle
so that users can avoid making
a ton of web requests?

00:01:35.726 --> 00:01:38.296 align:middle
Yes... but not always.

00:01:38.986 --> 00:01:43.746 align:middle
The vendors~app.js file has some
Webpack-specific code on top,

00:01:43.966 --> 00:01:49.656 align:middle
but most of this file contains the
vendor libraries that we imported.

00:01:50.006 --> 00:01:52.196 align:middle
Stuff like bootstrap &amp; jquery.

00:01:52.846 --> 00:01:56.186 align:middle
When Webpack is trying to figure
out how to split the app.js file,

00:01:56.666 --> 00:01:59.726 align:middle
it looks for code that satisfies
several conditions.

00:01:59.796 --> 00:02:07.076 align:middle
For example, if it can find code from the
node_modules/ directory and that code is bigger

00:02:07.076 --> 00:02:15.146 align:middle
than 30kb and splitting it into a new file would
result in 3 or fewer final JavaScript files

00:02:15.146 --> 00:02:17.616 align:middle
for this entry, it will split it.

00:02:18.086 --> 00:02:20.216 align:middle
That's exactly what's happening here.

00:02:21.016 --> 00:02:26.416 align:middle
Webpack especially likes splitting "vendor"
code - that's the stuff in node_modules/ -

00:02:26.886 --> 00:02:32.896 align:middle
into its own file because vendor
code tends to change less often.

00:02:32.896 --> 00:02:39.256 align:middle
That means your user's browser can cache
the vendors~app.js file for a longer time...

00:02:39.676 --> 00:02:45.566 align:middle
which is cool, because those
files tend to be pretty big.

00:02:45.566 --> 00:02:51.956 align:middle
Then, the app.js file - which contains our code
that probably changes more often, is smaller.

00:02:52.646 --> 00:02:55.906 align:middle
The algorithm also looks for code re-use.

00:02:56.556 --> 00:02:58.956 align:middle
Right now, we only have one entry.

00:02:59.306 --> 00:03:02.816 align:middle
But in a little while, we're
going to create multiple entries

00:03:02.936 --> 00:03:06.196 align:middle
to support page-specific CSS and JavaScript.

00:03:06.976 --> 00:03:12.836 align:middle
When we do that, Webpack will automatically
start analyzing which modules are shared

00:03:12.836 --> 00:03:17.066 align:middle
between those entries and
isolate them into their own files.

00:03:17.166 --> 00:03:22.446 align:middle
For example, suppose our
get_nice_message.js file is imported

00:03:22.446 --> 00:03:25.696 align:middle
from two different entries: app and admin.

00:03:26.696 --> 00:03:34.006 align:middle
Without code splitting, that code would be
duplicated inside the final built app.js

00:03:34.006 --> 00:03:35.376 align:middle
and admin.js.

00:03:36.376 --> 00:03:41.346 align:middle
With code splitting, that code
may be split into its own file.

00:03:42.256 --> 00:03:47.316 align:middle
I say "may" because Webpack
is smart: if the code is tiny,

00:03:47.696 --> 00:03:51.476 align:middle
splitting it into its own file
would be worse for performance.

00:03:52.376 --> 00:03:56.666 align:middle
All of this craziness happens
without us even knowing or caring.

00:03:57.376 --> 00:04:01.346 align:middle
This feature comes from a part of
Webpack called the SplitChunksPlugin.

00:04:02.176 --> 00:04:05.276 align:middle
On top, it explains the logic it uses to split.

00:04:05.766 --> 00:04:08.226 align:middle
But you can configure all of this.

00:04:08.886 --> 00:04:10.686 align:middle
Oh, see this big example config?

00:04:11.016 --> 00:04:17.206 align:middle
This is a small piece of what Webpack's
config normally looks like without Encore:

00:04:18.216 --> 00:04:22.626 align:middle
your webpack.config.js would be
a big config object like this.

00:04:23.216 --> 00:04:28.356 align:middle
So, if we wanted to apply some of these
changes, how could we do that in Encore?

00:04:29.176 --> 00:04:32.056 align:middle
The answer lives at the bottom
of webpack.config.js.

00:04:32.056 --> 00:04:40.696 align:middle
At the end, we call Encore.getWebpackConfig(),
which generates standard, Webpack config.

00:04:40.696 --> 00:04:46.326 align:middle
If you need to, you can always set
this to a variable, modify some keys,

00:04:46.596 --> 00:04:49.326 align:middle
then export the final value
when you're finished.

00:04:49.326 --> 00:04:52.356 align:middle
But for most things, there's an easier way.

00:04:52.806 --> 00:04:57.166 align:middle
In this case, you can say
.configureSplitChunks()

00:04:57.236 --> 00:04:59.346 align:middle
and pass it a callback function.

00:05:00.126 --> 00:05:05.966 align:middle
Encore will pass you the default split chunks
configuration and then you can tweak it.

00:05:06.566 --> 00:05:09.336 align:middle
This is a common way to extend things in Encore.

00:05:12.136 --> 00:05:16.456 align:middle
But... Webpack does a pretty great job
of splitting things out-of-the-box.

00:05:16.816 --> 00:05:19.966 align:middle
And... if you look at the entrypoints.json file,

00:05:20.336 --> 00:05:25.756 align:middle
Encore makes sure that this file stays
up-to-date with exactly which script

00:05:25.756 --> 00:05:28.506 align:middle
and link tags each entry requires.

00:05:29.086 --> 00:05:33.246 align:middle
The Twig helpers are already reading
this file and taking care of everything.

00:05:33.796 --> 00:05:37.216 align:middle
Basically, code splitting is free performance.

00:05:38.046 --> 00:05:40.756 align:middle
Oh, and all of this applies to CSS too.

00:05:41.196 --> 00:05:44.486 align:middle
In a few minutes, after we've
made our CSS a bit fancier,

00:05:44.896 --> 00:05:48.286 align:middle
you'll notice that we'll
suddenly have multiple link tags.

00:05:48.286 --> 00:05:50.776 align:middle
Next, let's do that!

00:05:51.166 --> 00:05:55.966 align:middle
Let's take our CSS up a level by removing
the extra link tags from our base layout

00:05:56.216 --> 00:05:58.166 align:middle
and putting everything into Encore.

00:05:59.126 --> 00:06:05.106 align:middle
To do this, we'll start importing CSS files
from third-party libraries in node_modules/.

