WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:02.006 --> 00:00:05.896 align:middle
The inline code in base.html.twig
isn't working anymore

00:00:06.256 --> 00:00:10.216 align:middle
because we've eliminated
the $ global variable: Woo!

00:00:10.216 --> 00:00:20.156 align:middle
To make it work, let's move all this code
into app.js: Instead of global variables,

00:00:20.336 --> 00:00:26.676 align:middle
we're importing $ and that's why it's called
$ down here: It's all just local variables.

00:00:27.616 --> 00:00:28.136 align:middle
Try it now.

00:00:29.496 --> 00:00:31.376 align:middle
Ok, it sorta works.

00:00:31.626 --> 00:00:32.496 align:middle
It logs...

00:00:32.496 --> 00:00:34.726 align:middle
then explodes.

00:00:35.376 --> 00:00:38.946 align:middle
The error has some Webpack stuff
on it, but it ultimately says:

00:00:39.366 --> 00:00:43.096 align:middle
dropdown is not a function
Click the app.js link.

00:00:43.526 --> 00:00:46.666 align:middle
Ah, it's having trouble with
the dropdown() function.

00:00:47.066 --> 00:00:51.286 align:middle
That is one of the functions
that Bootstrap adds to jQuery.

00:00:51.536 --> 00:00:56.646 align:middle
And... it makes sense why it's missing:
we're running all of our code here,

00:00:57.136 --> 00:01:02.756 align:middle
and then including Bootstrap: It's
simply not adding the function in time!

00:01:03.486 --> 00:01:06.466 align:middle
Well actually, it's a bit more than that.

00:01:07.396 --> 00:01:11.996 align:middle
Even if we moved this script
tag up, it still wouldn't work.

00:01:12.686 --> 00:01:17.306 align:middle
Why? Because when you include
Bootstrap via a script tag,

00:01:17.666 --> 00:01:21.466 align:middle
it expects jQuery to be a global variable...

00:01:21.636 --> 00:01:25.616 align:middle
and that - wonderfully - doesn't exist anymore.

00:01:26.376 --> 00:01:28.406 align:middle
Let's do this properly.

00:01:29.146 --> 00:01:34.226 align:middle
Oh, by the way, this popper.js thing is
here because it's needed by Bootstrap:

00:01:34.886 --> 00:01:37.436 align:middle
You'll see how this works
in Webpack in a moment.

00:01:38.026 --> 00:01:44.506 align:middle
Delete both of the script tags: Then, find
your terminal and run: yarn add bootstrap --

00:01:44.506 --> 00:01:49.056 align:middle
dev Oh, and how did I know that
the package name was bootstrap?

00:01:49.766 --> 00:01:52.856 align:middle
Just because I cheated and
searched for it before recording.

00:01:52.856 --> 00:01:57.136 align:middle
Go to https://yarnpkg.com/
and search for "Bootstrap".

00:01:57.476 --> 00:01:59.356 align:middle
9.7 million downloads...

00:01:59.696 --> 00:02:01.996 align:middle
in the last 30 days...

00:02:02.186 --> 00:02:03.896 align:middle
that's probably the right one.

00:02:04.756 --> 00:02:05.946 align:middle
And... it's done!

00:02:06.686 --> 00:02:14.056 align:middle
Oh, and there's a little notice: bootstrap has
an unmet peer dependency popper.js We'll come

00:02:14.056 --> 00:02:14.886 align:middle
back to that in a minute.

00:02:16.236 --> 00:02:19.656 align:middle
Back in app.js installing
Bootstrap isn't enough.

00:02:20.026 --> 00:02:28.606 align:middle
On top, add import 'bootstrap': Nope, we don't
need to say import $ from or anything like that.

00:02:29.126 --> 00:02:34.286 align:middle
Bootstrap is a jQuery plugin
and jQuery plugins are...

00:02:34.286 --> 00:02:35.546 align:middle
super weird.

00:02:36.176 --> 00:02:38.586 align:middle
They do not return a value.

00:02:39.036 --> 00:02:43.526 align:middle
Instead, they modify jQuery
and add functions to it.

00:02:44.196 --> 00:02:45.436 align:middle
I'll add a note here because...

00:02:45.586 --> 00:02:51.316 align:middle
it just looks strange: it's
weird that adding this allows me

00:02:51.316 --> 00:02:53.736 align:middle
to use the tooltip() function, for example.

00:02:54.736 --> 00:02:55.516 align:middle
But wait a second.

00:02:55.916 --> 00:02:58.546 align:middle
If Bootstrap modifies jQuery...

00:02:59.186 --> 00:03:06.376 align:middle
internally, how does it get the
jQuery object in order to do that?

00:03:06.376 --> 00:03:12.926 align:middle
I mean, jQuery is no longer global:
if we need it, we need to import it.

00:03:13.976 --> 00:03:20.796 align:middle
Well... because Bootstrap is a well-written
library, it does the exact same thing.

00:03:21.546 --> 00:03:27.296 align:middle
It detects that it's in a Webpack
environment and, instead of expecting there

00:03:27.296 --> 00:03:33.386 align:middle
to be a global jQuery variable, it
imports jquery, just like we are.

00:03:34.546 --> 00:03:40.896 align:middle
And, fun fact, when two different files import
the same module, they get back the same,

00:03:41.076 --> 00:03:44.566 align:middle
one instance of it - a lot
like Symfony's container.

00:03:45.276 --> 00:03:50.496 align:middle
We import jQuery and assign it
to $. Then, a microsecond later,

00:03:51.086 --> 00:03:57.776 align:middle
Bootstrap imports that same object and
modifies it: By the time we get past line 12,

00:03:58.006 --> 00:04:01.316 align:middle
the $ variable has the new tooltip() function.

00:04:02.106 --> 00:04:05.756 align:middle
But... you may have noticed
that, while I was talking

00:04:05.756 --> 00:04:08.156 align:middle
about how awesome this is all going to work...

00:04:08.406 --> 00:04:09.936 align:middle
my build was failing!

00:04:10.616 --> 00:04:16.716 align:middle
This dependency was not found: popper.js
in bootstrap.js This is awesome!

00:04:17.096 --> 00:04:24.056 align:middle
Bootstrap has two dependencies: jQuery
but also another library called popper.js.

00:04:25.006 --> 00:04:28.106 align:middle
Internally, it tries to import both of them.

00:04:28.526 --> 00:04:32.266 align:middle
But, because this is not
installed in our project, it fails.

00:04:32.896 --> 00:04:37.896 align:middle
By the way, if you're wondering: Why doesn't
Bootstrap just list this as a dependency

00:04:37.896 --> 00:04:42.676 align:middle
in its package.json so that it's
automatically downloaded for us?

00:04:43.146 --> 00:04:44.356 align:middle
Excellent question!

00:04:44.906 --> 00:04:48.426 align:middle
And that's exactly how we
would do it in the PHP world.

00:04:48.996 --> 00:04:56.416 align:middle
Short answer: Node dependencies are complicated,
and so sometimes it will work like this,

00:04:56.706 --> 00:05:04.626 align:middle
but sometimes it's a better idea for a library
to force us to install its dependency manually.

00:05:05.486 --> 00:05:07.526 align:middle
That's called a "peer" dependency.

00:05:08.486 --> 00:05:12.156 align:middle
Anyways, this is a great
error, and it even suggests how

00:05:12.156 --> 00:05:15.896 align:middle
to fix it: npm install -- save popper.js.

00:05:17.016 --> 00:05:20.436 align:middle
Because we're using Yarn, we'll
do our version of that command.

00:05:21.206 --> 00:05:29.086 align:middle
Back in your open terminal tab, run: yarn
add popper.js -- dev When that finishes...

00:05:31.346 --> 00:05:36.886 align:middle
ah. Because we haven't modified any files,
Webpack doesn't know it should re-build.

00:05:37.676 --> 00:05:40.066 align:middle
Let's go over here and just add a space.

00:05:40.676 --> 00:05:42.686 align:middle
That triggers a rebuild which is...

00:05:42.686 --> 00:05:43.966 align:middle
successful!

00:05:45.706 --> 00:05:47.196 align:middle
Try it out - refresh!

00:05:49.276 --> 00:05:50.706 align:middle
No errors.

00:05:51.356 --> 00:05:53.646 align:middle
Next! I have a surprise!

00:05:54.126 --> 00:05:58.816 align:middle
Webpack has already started
to silently optimize our build

00:05:58.956 --> 00:06:01.326 align:middle
through a process called code splitting.

00:06:02.026 --> 00:06:04.236 align:middle
Let's see what that means
and learn how it works.

