WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:02.366 --> 00:00:05.246 align:middle
On the article show page,
if you check the console...

00:00:05.556 --> 00:00:07.046 align:middle
it's an error!

00:00:07.426 --> 00:00:10.886 align:middle
$ is undefined coming from article_show.js.

00:00:11.776 --> 00:00:13.216 align:middle
This shouldn't be surprising.

00:00:13.706 --> 00:00:17.006 align:middle
And not just because I seem
to make a lot of mistakes.

00:00:17.526 --> 00:00:20.946 align:middle
Open that template and go to the bottom.

00:00:20.946 --> 00:00:25.036 align:middle
Ah, this brings in a js/article_show.js file.

00:00:26.026 --> 00:00:29.936 align:middle
Go find that: in public/,
I'll close build/ and...

00:00:30.126 --> 00:00:30.626 align:middle
there it is.

00:00:31.746 --> 00:00:35.026 align:middle
This contains some traditional
JavaScript from a previous tutorial.

00:00:35.916 --> 00:00:39.556 align:middle
The problem is that the global $
variable doesn't exist anymore.

00:00:39.556 --> 00:00:44.656 align:middle
If you look closely on this page,
you'll see that, at the bottom,

00:00:44.846 --> 00:00:50.376 align:middle
we include the app.js file
first and then article_show.js.

00:00:51.506 --> 00:00:56.026 align:middle
And, of course, the app.js
file does import jQuery.

00:00:56.646 --> 00:01:03.826 align:middle
But as we learned, this does not create a global
variable and local variables in Webpack don't

00:01:03.826 --> 00:01:06.536 align:middle
"leak" beyond the file they're defined in.

00:01:06.966 --> 00:01:09.346 align:middle
So... this file is broken.

00:01:09.536 --> 00:01:13.766 align:middle
And that's fine because I want to
refactor it anyways to go through Encore

00:01:13.896 --> 00:01:16.766 align:middle
so that we can properly import
the variable on top.

00:01:18.186 --> 00:01:21.076 align:middle
Before we do that, let's
organize one tiny thing.

00:01:21.766 --> 00:01:24.716 align:middle
In assets/js, create a new
components/ directory.

00:01:25.746 --> 00:01:29.016 align:middle
Move get_nice_messages.js into that...

00:01:30.856 --> 00:01:33.166 align:middle
and because that breaks our build...

00:01:33.406 --> 00:01:36.696 align:middle
update the import statement
in app.js to point here.

00:01:38.326 --> 00:01:41.616 align:middle
Ok: I originally put this
code into a separate file

00:01:41.786 --> 00:01:44.776 align:middle
because it's only needed
on the article show page.

00:01:45.296 --> 00:01:49.046 align:middle
We could copy all of this, put it into app.js...

00:01:49.196 --> 00:01:50.696 align:middle
and that would work!

00:01:51.446 --> 00:01:54.846 align:middle
But sometimes, instead of
having one big JavaScript file,

00:01:55.106 --> 00:02:00.296 align:middle
you might want to split page-specific
CSS and JavaScript into their own files.

00:02:01.356 --> 00:02:04.966 align:middle
To do that, we'll create
a second Webpack "entry".

00:02:05.706 --> 00:02:09.516 align:middle
Move article_show.js into assets/js/.

00:02:11.026 --> 00:02:18.326 align:middle
Next, go into webpack.config.js
and, up here, call addEntry() again.

00:02:19.256 --> 00:02:24.166 align:middle
Name it article_show and point it at .

00:02:24.166 --> 00:02:27.056 align:middle
/assets/js/article_show.js.

00:02:28.466 --> 00:02:35.046 align:middle
Now when we build Webpack, it will still
load app.js, follow all the imports,

00:02:35.196 --> 00:02:39.336 align:middle
and create app.js and app.css files.

00:02:40.006 --> 00:02:46.796 align:middle
But now it will also load
article_show.js, follow all of its imports

00:02:47.026 --> 00:02:53.386 align:middle
and output new article_show.js
and article_show.css files.

00:02:54.226 --> 00:02:59.036 align:middle
Each "entry", or "entry point"
is like a standalone application

00:02:59.196 --> 00:03:01.696 align:middle
that contains everything it needs.

00:03:02.836 --> 00:03:07.656 align:middle
And now that we have this new
article_show entry, inside show.html.twig,

00:03:08.216 --> 00:03:13.846 align:middle
instead of our manual &lt;script&gt; tag, use {{
encore_entry_script_tags() }} article_show.

00:03:15.466 --> 00:03:17.516 align:middle
I don't have a link tag anywhere...

00:03:18.036 --> 00:03:19.976 align:middle
nope - it's not hiding on top either.

00:03:21.356 --> 00:03:28.186 align:middle
That's ok, because, so far,
article_show.js isn't importing any CSS.

00:03:28.396 --> 00:03:34.886 align:middle
And so, Webpack is smart enough to not
output an empty article_show.css file.

00:03:35.556 --> 00:03:37.516 align:middle
But you could still plan ahead if you wanted:

00:03:38.146 --> 00:03:42.586 align:middle
encore_entry_link_tags() will print
nothing if there's no CSS file.

00:03:42.876 --> 00:03:44.076 align:middle
So, no harm.

00:03:45.066 --> 00:03:46.596 align:middle
Ok: because we made a change

00:03:46.596 --> 00:03:53.386 align:middle
to our webpack.config.js file,
stop and restart Encore: And...

00:03:53.446 --> 00:03:57.456 align:middle
cool! The app entry caused these
three files to be created...

00:03:57.456 --> 00:04:03.616 align:middle
thanks to the split chunks stuff, and
article_show just made article_show.js.

00:04:03.686 --> 00:04:07.916 align:middle
If you find your browser and refresh now...

00:04:10.626 --> 00:04:11.816 align:middle
oh, same error...

00:04:12.356 --> 00:04:14.386 align:middle
because we still haven't imported that.

00:04:17.796 --> 00:04:23.436 align:middle
Back in article_show.js, import $ from 'jquery'.

00:04:26.096 --> 00:04:29.756 align:middle
Refresh again and...

00:04:30.186 --> 00:04:32.356 align:middle
boom! Error is gone.

00:04:33.156 --> 00:04:36.456 align:middle
We can click the fancy JavaScript-powered
heart icon.

00:04:37.386 --> 00:04:41.356 align:middle
Because we haven't imported any
CSS yet from article_show.js,

00:04:41.956 --> 00:04:47.866 align:middle
we already saw that Webpack was smart
enough to not output a CSS file.

00:04:47.866 --> 00:04:51.586 align:middle
But! Open up _articles.scss.

00:04:52.686 --> 00:04:56.326 align:middle
Part of this file is CSS
for the article show page...

00:04:56.456 --> 00:05:00.426 align:middle
which doesn't really need to
be included on every page.

00:05:01.696 --> 00:05:07.636 align:middle
Let's copy all of this code, remove it,
and, at the root of the css/ directory,

00:05:07.846 --> 00:05:12.056 align:middle
create a new file called
article_show.scss and...

00:05:12.356 --> 00:05:20.786 align:middle
paste! Both app.js and article_show.js are
meant to import everything that's needed

00:05:20.786 --> 00:05:24.006 align:middle
for the layout and for the article show page.

00:05:24.966 --> 00:05:30.336 align:middle
app.scss and article_show.scss
are kinda the same thing:

00:05:30.696 --> 00:05:34.816 align:middle
they should import all the CSS
that's needed for each spot.

00:05:35.946 --> 00:05:40.296 align:middle
At the top of article_show.scss,
we don't strictly need to do this,

00:05:40.296 --> 00:05:46.636 align:middle
but let's @import 'helper/variables
to drive home the point

00:05:46.636 --> 00:05:51.426 align:middle
that this is a standalone file
that imports anything it needs.

00:05:53.776 --> 00:05:58.446 align:middle
Finally, back in article_show.js add import '..

00:05:58.656 --> 00:06:01.186 align:middle
/css/article_show.scss'.

00:06:01.186 --> 00:06:05.576 align:middle
Ok, check your terminal!

00:06:06.686 --> 00:06:08.376 align:middle
Suddenly, gasp!

00:06:08.646 --> 00:06:13.106 align:middle
Webpack is outputting an article_show.css file!

00:06:13.596 --> 00:06:17.686 align:middle
And wow! You can really see
code splitting in action!

00:06:18.266 --> 00:06:25.936 align:middle
That vendors~app~article_show.js probably
contains jQuery, because Webpack saw

00:06:25.936 --> 00:06:33.506 align:middle
that it's used by both entries and so isolated
it into its own file so it could be re-used.

00:06:34.526 --> 00:06:39.546 align:middle
Anyways, back in show.html.twig
copy the javascripts block, paste,

00:06:39.906 --> 00:06:45.326 align:middle
rename it to stylesheets and then change
to {{ encore_entry_link_tags() }}.

00:06:46.996 --> 00:06:47.896 align:middle
That should do it!

00:06:48.206 --> 00:06:51.096 align:middle
Move over, refresh and...

00:06:51.736 --> 00:06:55.556 align:middle
cool! The page still looks
good and the heart still works.

00:06:55.556 --> 00:07:01.846 align:middle
If you inspect element on this page,
in the head, we have two CSS files:

00:07:02.336 --> 00:07:07.416 align:middle
app.css to power the layout and
article_show.css to power this page.

00:07:08.706 --> 00:07:14.046 align:middle
At the bottom, we have 4 JavaScript
files to power the two entrypoints.

00:07:14.826 --> 00:07:17.656 align:middle
By the way, WebpackEncoreBundle is smart enough

00:07:17.656 --> 00:07:26.266 align:middle
to not duplicate the vendors~app~article_show.js
script tag just because both entries need it.

00:07:26.796 --> 00:07:31.476 align:middle
Smart! Next: we are close to
having our whole app in Encore.

00:07:32.026 --> 00:07:35.416 align:middle
Let's refactor a bunch more
un-Webpack-ified code.

