Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,390 --> 00:00:03,570
As the last part in this section,
2
00:00:03,570 --> 00:00:06,660
let's talk about how NODE.JS modules actually work
3
00:00:06,660 --> 00:00:07,623
behind the scenes.
4
00:00:09,220 --> 00:00:11,980
First of all in the NODE.JS module system
5
00:00:11,980 --> 00:00:15,660
each JavaScript file is treated as a separate module.
6
00:00:15,660 --> 00:00:18,120
And we already played around a bit with modules
7
00:00:18,120 --> 00:00:19,722
in the intersection,
8
00:00:19,722 --> 00:00:21,780
'specially by using the require function
9
00:00:21,780 --> 00:00:23,920
and exporting data from modules.
10
00:00:23,920 --> 00:00:27,150
So that's the fundamentals of Common JS modules
11
00:00:27,150 --> 00:00:29,770
which is the module system that node uses.
12
00:00:29,770 --> 00:00:33,010
Because it works especially well on the server.
13
00:00:33,010 --> 00:00:35,930
Now, there's also the native ECMA script
14
00:00:35,930 --> 00:00:37,620
or ES module system that
15
00:00:37,620 --> 00:00:39,870
you might already be familiar with,
16
00:00:39,870 --> 00:00:42,060
'specially if you took my JavaScript course,
17
00:00:42,060 --> 00:00:43,950
or if you have been writing JavaScript
18
00:00:43,950 --> 00:00:45,840
on the front end lately.
19
00:00:45,840 --> 00:00:49,270
This ES module system that I was talking about was developed
20
00:00:49,270 --> 00:00:53,310
to work in the browser using the import export syntax.
21
00:00:53,310 --> 00:00:55,640
So, I just wanted to make it clear that these are
22
00:00:55,640 --> 00:00:57,980
two different module systems that you will see
23
00:00:57,980 --> 00:00:59,030
in different situations,
24
00:00:59,030 --> 00:01:00,950
so don't be confused.
25
00:01:00,950 --> 00:01:03,110
There have also been attempts to implement
26
00:01:03,110 --> 00:01:05,699
native ES modules in NODE.JS,
27
00:01:05,699 --> 00:01:07,280
'specially using file extensions
28
00:01:07,280 --> 00:01:09,130
like .mjs.
29
00:01:09,130 --> 00:01:10,870
But so far, it's not really become
30
00:01:10,870 --> 00:01:12,940
a popular thing to use.
31
00:01:12,940 --> 00:01:14,630
So unless you're watching this course
32
00:01:14,630 --> 00:01:16,140
in the far future,
33
00:01:16,140 --> 00:01:17,970
you will probably always be using
34
00:01:17,970 --> 00:01:20,223
the Common JS system with node.
35
00:01:21,070 --> 00:01:23,600
Now, you might be wondering why in NODE.JS
36
00:01:23,600 --> 00:01:26,350
each and every module actually gets access
37
00:01:26,350 --> 00:01:28,420
to the require function in order
38
00:01:28,420 --> 00:01:30,780
to import modules in the first place.
39
00:01:30,780 --> 00:01:31,700
Right?
40
00:01:31,700 --> 00:01:34,570
I mean, it's not a standard JavaScript function.
41
00:01:34,570 --> 00:01:36,040
So where does it come from?
42
00:01:36,040 --> 00:01:39,080
And how exactly does it work behind the scenes?
43
00:01:39,080 --> 00:01:40,763
Well, let's find out.
44
00:01:42,070 --> 00:01:43,780
So the question here is,
45
00:01:43,780 --> 00:01:45,930
what happens each time that we require
46
00:01:45,930 --> 00:01:48,540
a module by calling the require function
47
00:01:48,540 --> 00:01:51,620
with a module name, is the argument.
48
00:01:51,620 --> 00:01:53,270
As a very broad overview,
49
00:01:53,270 --> 00:01:56,270
the following steps are executed behind the scenes.
50
00:01:56,270 --> 00:01:58,890
First, the path to the required module
51
00:01:58,890 --> 00:02:01,600
is resolved and the file is loaded.
52
00:02:01,600 --> 00:02:04,290
Then a process called wrapping happens
53
00:02:04,290 --> 00:02:05,130
after that,
54
00:02:05,130 --> 00:02:07,210
the module code is executed
55
00:02:07,210 --> 00:02:09,759
and the module exports are returned.
56
00:02:09,759 --> 00:02:12,963
And finally the entire module gets cached.
57
00:02:14,300 --> 00:02:17,550
So let's now look at each step in more detail.
58
00:02:17,550 --> 00:02:20,570
First off, how does node know which file to load
59
00:02:20,570 --> 00:02:22,640
when we require a module?
60
00:02:22,640 --> 00:02:24,970
Because remember, we can actually load
61
00:02:24,970 --> 00:02:27,410
three different kinds of modules.
62
00:02:27,410 --> 00:02:29,030
Node's core modules,
63
00:02:29,030 --> 00:02:32,400
our own modules or third party modules from npm
64
00:02:32,400 --> 00:02:34,990
like express which is the node framework that we're
65
00:02:34,990 --> 00:02:37,380
going to use throughout most of the course.
66
00:02:37,380 --> 00:02:40,940
So this process is known as resolving the file path.
67
00:02:40,940 --> 00:02:42,820
And here is how it works.
68
00:02:42,820 --> 00:02:45,500
When the require functions receives the module name
69
00:02:45,500 --> 00:02:46,810
as its input,
70
00:02:46,810 --> 00:02:50,280
it will first try to load a core module with that name.
71
00:02:50,280 --> 00:02:52,860
Like for example, the http module.
72
00:02:52,860 --> 00:02:55,570
It will automatically find a path to that module
73
00:02:55,570 --> 00:02:57,130
and then load it.
74
00:02:57,130 --> 00:02:59,150
Now if the path starts with a dot,
75
00:02:59,150 --> 00:03:00,160
or two dots,
76
00:03:00,160 --> 00:03:02,280
it means that it's a developer module.
77
00:03:02,280 --> 00:03:06,010
Because we indicate the relative path to our file.
78
00:03:06,010 --> 00:03:08,380
So node will try to load that file,
79
00:03:08,380 --> 00:03:11,130
but if there is no file with that name,
80
00:03:11,130 --> 00:03:13,180
then it will look for a folder instead
81
00:03:13,180 --> 00:03:16,870
and load index.js if it's in that folder.
82
00:03:16,870 --> 00:03:18,060
So in this example,
83
00:03:18,060 --> 00:03:21,370
it will try to load lib/controller.js.
84
00:03:21,370 --> 00:03:23,600
Remember that we can drop the dot js
85
00:03:23,600 --> 00:03:25,600
when requiring a module.
86
00:03:25,600 --> 00:03:28,570
In case there is no file at this path,
87
00:03:28,570 --> 00:03:30,360
it will then, instead, try to open
88
00:03:30,360 --> 00:03:34,450
index.js from the lib/controller folder instead.
89
00:03:34,450 --> 00:03:35,900
Make sense?
90
00:03:35,900 --> 00:03:37,890
And finally, if the required module
91
00:03:37,890 --> 00:03:39,330
is neither a core module,
92
00:03:39,330 --> 00:03:41,290
nor a developer module,
93
00:03:41,290 --> 00:03:44,470
node will assume it's a module from npm.
94
00:03:44,470 --> 00:03:47,910
And remember, on a module that we load from npm,
95
00:03:47,910 --> 00:03:51,050
we actually don't need to write the path when we require it.
96
00:03:51,050 --> 00:03:52,150
Just the module name,
97
00:03:52,150 --> 00:03:55,130
just the way it works on a core module.
98
00:03:55,130 --> 00:03:57,470
So these third party modules are stored
99
00:03:57,470 --> 00:03:59,250
in a node module folder,
100
00:03:59,250 --> 00:04:02,280
so node will step into that folder and try to find
101
00:04:02,280 --> 00:04:04,960
a module there and then load it.
102
00:04:04,960 --> 00:04:07,860
And of course, if the file can't be found anywhere,
103
00:04:07,860 --> 00:04:10,410
then an error is thrown and the execution
104
00:04:10,410 --> 00:04:12,043
of the app is stopped.
105
00:04:13,861 --> 00:04:16,450
Moving on, after the module is loaded,
106
00:04:16,450 --> 00:04:20,230
the module's code is wrapped into a special function
107
00:04:20,230 --> 00:04:24,098
which will give us access to a couple of special objects.
108
00:04:24,098 --> 00:04:27,370
So this step is where the magic happens.
109
00:04:27,370 --> 00:04:30,260
It is here where we get the answer to the question,
110
00:04:30,260 --> 00:04:33,290
where does the require function actually come from
111
00:04:33,290 --> 00:04:35,403
and why do we have access to it?
112
00:04:36,290 --> 00:04:38,190
It's because the nodejs run time,
113
00:04:38,190 --> 00:04:39,860
takes the code off our module
114
00:04:39,860 --> 00:04:42,450
and puts it inside the immediately invoked
115
00:04:42,450 --> 00:04:46,390
function expression, or IIFE that you can see here.
116
00:04:46,390 --> 00:04:48,330
So node does actually not directly
117
00:04:48,330 --> 00:04:51,500
the execute the code that I rewrite into a file,
118
00:04:51,500 --> 00:04:54,530
but instead, the wrapper function that will contain
119
00:04:54,530 --> 00:04:56,770
our code in it's body.
120
00:04:56,770 --> 00:05:00,010
It also passes the experts require module,
121
00:05:00,010 --> 00:05:03,360
file name and dir objects into it.
122
00:05:03,360 --> 00:05:05,820
So that is why in every module
123
00:05:05,820 --> 00:05:07,730
we automatically have access
124
00:05:07,730 --> 00:05:10,450
to stuff like the require function.
125
00:05:10,450 --> 00:05:12,870
So these are basically like global variables
126
00:05:12,870 --> 00:05:15,703
that are injected into each and every module.
127
00:05:17,150 --> 00:05:21,420
Now by doing this, node achieves two very important things.
128
00:05:21,420 --> 00:05:24,010
First, of course, is giving developers access
129
00:05:24,010 --> 00:05:26,450
to all these variables we just talked about,
130
00:05:26,450 --> 00:05:28,520
which is very helpful.
131
00:05:28,520 --> 00:05:31,160
Second, it keeps the top-level variables that we
132
00:05:31,160 --> 00:05:33,320
define in our modules private.
133
00:05:33,320 --> 00:05:36,080
So it's scoped only to the current module
134
00:05:36,080 --> 00:05:39,690
instead of leaking everything into the global object.
135
00:05:39,690 --> 00:05:41,060
So imagine for a second,
136
00:05:41,060 --> 00:05:44,640
that we declared a variable x in one of our modules
137
00:05:44,640 --> 00:05:48,050
and then included an npm module that also used
138
00:05:48,050 --> 00:05:49,840
a variable called x.
139
00:05:49,840 --> 00:05:51,640
Without this mechanism,
140
00:05:51,640 --> 00:05:54,080
our own variable would then get overridden
141
00:05:54,080 --> 00:05:56,600
and the entire app would just not work.
142
00:05:56,600 --> 00:05:59,370
So each module having its private scope
143
00:05:59,370 --> 00:06:01,950
is absolutely crucial and is achieved
144
00:06:01,950 --> 00:06:05,000
through this clever trick of wrapping our code
145
00:06:05,000 --> 00:06:06,423
into this special function.
146
00:06:08,080 --> 00:06:10,400
Let's now take a quick look at each object
147
00:06:10,400 --> 00:06:11,960
that our module gets.
148
00:06:11,960 --> 00:06:13,710
First the require function,
149
00:06:13,710 --> 00:06:15,290
which we already know about.
150
00:06:15,290 --> 00:06:17,260
Then, there is a module object,
151
00:06:17,260 --> 00:06:19,760
which is just a reference to the current module
152
00:06:19,760 --> 00:06:21,410
and which for us is most important
153
00:06:21,410 --> 00:06:23,800
when it comes to exporting data.
154
00:06:23,800 --> 00:06:26,230
The same applies to the export's object
155
00:06:26,230 --> 00:06:28,520
which we're gonna discuss in a moment.
156
00:06:28,520 --> 00:06:30,490
Finally, there are the convenience
157
00:06:30,490 --> 00:06:33,150
variables file name and dir name
158
00:06:33,150 --> 00:06:35,240
which simply contain the absolute path
159
00:06:35,240 --> 00:06:36,890
to the current module's file
160
00:06:36,890 --> 00:06:40,200
as well as the current directory name.
161
00:06:40,200 --> 00:06:44,023
And that is how the wrapping step of loading a module works.
162
00:06:45,060 --> 00:06:47,280
Next up, the code in the module,
163
00:06:47,280 --> 00:06:48,840
or to be more precise,
164
00:06:48,840 --> 00:06:50,940
in the module's wrapper function,
165
00:06:50,940 --> 00:06:54,240
actually gets executed by the NODE.JS runtime.
166
00:06:54,240 --> 00:06:55,693
So, nothing fancy here.
167
00:06:57,460 --> 00:06:58,810
Up until this point,
168
00:06:58,810 --> 00:07:01,980
the require function has been called with a module name
169
00:07:01,980 --> 00:07:03,559
as the argument the path
170
00:07:03,559 --> 00:07:07,200
to the module's file has been resolved into file loaded,
171
00:07:07,200 --> 00:07:10,370
all the code has been wrapped into the wrapper function
172
00:07:10,370 --> 00:07:12,461
which has then been executed.
173
00:07:12,461 --> 00:07:15,190
Now, it's time for the require function
174
00:07:15,190 --> 00:07:17,320
to actually return something.
175
00:07:17,320 --> 00:07:21,840
And what it returns is the exports of the required module.
176
00:07:21,840 --> 00:07:25,503
These exports are stored in the module.exportsobjects.
177
00:07:26,860 --> 00:07:29,260
It might look a little bit like this.
178
00:07:29,260 --> 00:07:32,300
So, again, in each module we can export variables,
179
00:07:32,300 --> 00:07:36,300
which will, in the end be returned by the require function.
180
00:07:36,300 --> 00:07:40,490
And we do that by assigning variables to module.exports
181
00:07:40,490 --> 00:07:42,190
or simply to exports
182
00:07:42,190 --> 00:07:45,600
where it is just a pointer to module.export.
183
00:07:45,600 --> 00:07:47,600
We will do this in practice in the next video,
184
00:07:47,600 --> 00:07:50,250
because I know this sounds kind of confusing
185
00:07:50,250 --> 00:07:52,270
when I just say it like this.
186
00:07:52,270 --> 00:07:54,140
Anyway, here's what you need to know
187
00:07:54,140 --> 00:07:58,370
about when to use module.export or just export.
188
00:07:58,370 --> 00:08:02,220
So if all you want to do is to export one single variable,
189
00:08:02,220 --> 00:08:04,460
like one class or one function,
190
00:08:04,460 --> 00:08:07,890
you usually use module.exports and set it equal
191
00:08:07,890 --> 00:08:10,050
to the variable that you want to export.
192
00:08:10,050 --> 00:08:12,010
Just like in this example.
193
00:08:12,010 --> 00:08:13,000
On the other hand,
194
00:08:13,000 --> 00:08:16,120
if you're looking to export multiple named variables
195
00:08:16,120 --> 00:08:18,300
like multiple functions, for example,
196
00:08:18,300 --> 00:08:19,330
then you should create these
197
00:08:19,330 --> 00:08:22,280
as properties of the export object.
198
00:08:22,280 --> 00:08:25,690
For example, if we were doing a calculator module
199
00:08:25,690 --> 00:08:27,690
you could create exports.add,
200
00:08:27,690 --> 00:08:29,260
exports.multiply,
201
00:08:29,260 --> 00:08:32,490
exports.divide and so on and so forth.
202
00:08:32,490 --> 00:08:33,559
Makes sense?
203
00:08:33,559 --> 00:08:35,960
Again, we're gonna do this in the next video
204
00:08:35,960 --> 00:08:38,110
and it will make more sense to you by then.
205
00:08:39,230 --> 00:08:42,530
This is effectively how we export and import data
206
00:08:42,530 --> 00:08:44,980
from one module into the other.
207
00:08:44,980 --> 00:08:47,410
Of course, this is also why we usually assign
208
00:08:47,410 --> 00:08:51,500
the result of a require function called to a new variable.
209
00:08:51,500 --> 00:08:54,003
So that we can save the returned exports.
210
00:08:55,140 --> 00:08:57,570
Now, just to finish this video real quick,
211
00:08:57,570 --> 00:09:00,500
the last step is that modules are actually cached
212
00:09:00,500 --> 00:09:03,090
after the first time they are loaded.
213
00:09:03,090 --> 00:09:05,850
What this means is that if you require the same module
214
00:09:05,850 --> 00:09:08,890
multiple times, you will always get the same result.
215
00:09:08,890 --> 00:09:12,490
And the code in the modules is actually only executed
216
00:09:12,490 --> 00:09:13,640
in the first call.
217
00:09:13,640 --> 00:09:15,100
In subsequent calls,
218
00:09:15,100 --> 00:09:18,470
the result is simply retrieved from cache.
219
00:09:18,470 --> 00:09:19,520
Perfect.
220
00:09:19,520 --> 00:09:21,730
So I hope that all the logic behind
221
00:09:21,730 --> 00:09:23,390
how to work with modules
222
00:09:23,390 --> 00:09:25,860
doesn't really look like magic anymore.
223
00:09:25,860 --> 00:09:28,570
It's really important to know how all of this works,
224
00:09:28,570 --> 00:09:30,130
in order to become a great,
225
00:09:30,130 --> 00:09:31,390
and above all,
226
00:09:31,390 --> 00:09:33,833
a more independent NODE.JS developer.
17290
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.