﻿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,760
‫and the module exports are returned.

56
00:02:09,760 --> 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,560
‫Makes sense?

203
00:08:33,560 --> 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.

