1
00:00:02,330 --> 00:00:03,740
So we added linting,

2
00:00:03,810 --> 00:00:11,200
let's now have a look at bundling our code, so combine all these individual code files,

3
00:00:11,210 --> 00:00:17,660
these individual scripts into one large script so that we can write our code in a distributed way, so

4
00:00:17,660 --> 00:00:21,500
that we can write our code like this with multiple code files

5
00:00:21,710 --> 00:00:27,560
but that in the end they are merged together so that we don't send all these unnecessary HttpRequests

6
00:00:27,910 --> 00:00:33,960
and for that, we'll use a tool called webpack. Webpack is a bundling tool,

7
00:00:33,980 --> 00:00:39,160
it's also more than that, it helps us orchestrate our entire build workflow as you will see

8
00:00:39,440 --> 00:00:45,670
but to get started we'll just use it, with its core task in mind, as a bundler.

9
00:00:45,740 --> 00:00:50,840
Now webpack has a really good documentation at webpack.js.org,

10
00:00:50,870 --> 00:00:57,440
there you can dive into the docs, go through all these guides here to have detailed instructions on all

11
00:00:57,440 --> 00:01:03,200
the different things you can set up, dive into the different concepts to understand how webpack thinks

12
00:01:03,200 --> 00:01:08,420
and what the different building blocks of webpack are and maybe also dive into the configuration to

13
00:01:08,420 --> 00:01:14,810
dive into all the nitty-gritty details you can configure because and I will say this right away, webpack

14
00:01:14,870 --> 00:01:18,080
is a complex tool. To get started with it,

15
00:01:18,080 --> 00:01:21,830
you don't need to configure much and we'll actually be able to do a lot with it

16
00:01:21,830 --> 00:01:28,280
in this module already but to truly master it and fine tune it for all the requirements more advanced

17
00:01:28,280 --> 00:01:29,750
projects might need,

18
00:01:29,750 --> 00:01:35,540
you should definitely check out this documentation because you could easily create an entire course

19
00:01:35,570 --> 00:01:39,980
just on webpack and that's just not what this course is about

20
00:01:39,980 --> 00:01:47,150
so we'll keep it fairly simple and focus on its core tasks, its core strengths and for that, we first

21
00:01:47,150 --> 00:01:48,400
of all need to install it.

22
00:01:48,410 --> 00:01:54,850
So back in our project, open up this integrated terminal, navigate it into your folder therefore

23
00:01:55,360 --> 00:02:02,580
and there we need to install the webpack again with npm as a development dependency of this project.

24
00:02:02,750 --> 00:02:08,770
For that, we run npm install --save-dev and then it's webpack

25
00:02:08,840 --> 00:02:17,550
and also one other tool, webpack-cli. So I'm installing two tools here, webpack and then unfortunately

26
00:02:17,550 --> 00:02:20,810
with a line break in between, webpack-cli,

27
00:02:20,850 --> 00:02:23,630
these two packages are getting installed now.

28
00:02:23,630 --> 00:02:29,490
Now simply hit enter and this will now go ahead and fetch these packages, store them in the node modules

29
00:02:29,490 --> 00:02:36,770
folder which we already talked about and make them available to us. So let's wait for that to finish,

30
00:02:37,490 --> 00:02:39,370
it should finish without an error,

31
00:02:39,380 --> 00:02:43,580
if you're getting a warning in between, you can ignore that, in the end it should finish with a message

32
00:02:43,580 --> 00:02:48,830
that looks something like this, confirming the versions that were installed and it should update the

33
00:02:48,830 --> 00:02:52,880
package.json file to add these two new packages as a dependency.

34
00:02:52,880 --> 00:02:56,330
The exact versions of course will differ at the point of time you're viewing this,

35
00:02:56,330 --> 00:02:59,840
the idea behind webpack and how you use it will not.

36
00:02:59,840 --> 00:03:03,920
So now we've got a webpack installed, how do we now use it?

37
00:03:03,920 --> 00:03:11,600
Well to use webpack, we typically create a configuration file where we tell webpack, that webpack tool,

38
00:03:11,900 --> 00:03:13,360
what to do. For that

39
00:03:13,400 --> 00:03:20,180
I'll add a new file on my top level next to the eslintrc.json file and the package.json file

40
00:03:20,630 --> 00:03:29,000
and this is a webpack.config.json file, not .json but .js. This is a file which webpack

41
00:03:29,000 --> 00:03:34,260
will use to do its thing, to do its job

42
00:03:34,280 --> 00:03:39,100
and now here in this file, we have to provide a configuration for webpack.

43
00:03:39,200 --> 00:03:47,990
Now this file under the hood uses or is executed by Node.js. We haven't learned Node.js yet but generally

44
00:03:47,990 --> 00:03:54,830
Node.js is also just Javascript with some extra features but therefore you'll understand the syntax because

45
00:03:54,860 --> 00:03:57,020
it's just Javascript.

46
00:03:57,170 --> 00:04:03,920
The one thing which is new though is how we export something in Node.js world? Instead of using the

47
00:04:04,010 --> 00:04:08,140
export keyword to make something available outside of this file,

48
00:04:08,300 --> 00:04:14,970
we use module.exports and set this equal to a Javascript object here.

49
00:04:14,990 --> 00:04:16,550
Now this is new,

50
00:04:16,550 --> 00:04:18,340
we haven't seen that before,

51
00:04:18,350 --> 00:04:27,050
this simply is the syntax Node.js uses for exposing this object outside of this file and webpack, the

52
00:04:27,050 --> 00:04:28,560
webpack tool we installed,

53
00:04:28,730 --> 00:04:30,980
will go ahead and import this object,

54
00:04:31,010 --> 00:04:36,210
so this will be our configuration object where we configure webpack.

55
00:04:36,350 --> 00:04:44,240
Now here I'm getting an error, module is not defined with the no-undef rule and we can quick fix this

56
00:04:44,240 --> 00:04:55,370
to disable no undefined for this line, alternatively we add the no undefined rule here and set it

57
00:04:55,370 --> 00:04:57,620
to off to disable it entirely.

58
00:04:57,620 --> 00:04:59,960
That's an alternative and this is what I'm doing here

59
00:04:59,960 --> 00:05:02,500
so that we don't face any issues with that.

60
00:05:02,540 --> 00:05:06,000
So now with that, I'm exporting this configuration object.

61
00:05:06,170 --> 00:05:10,460
Now webpack needs to know where the starting point of your app is,

62
00:05:10,460 --> 00:05:18,500
so it needs to know where in your source files the entry point of your project is and it will then take

63
00:05:18,500 --> 00:05:26,210
that entry point, in our case that would be app.js, analyse this file, most importantly analyse the imports

64
00:05:26,300 --> 00:05:33,770
of that file and then resolve all the dependencies of that file and the files related to that file.

65
00:05:33,800 --> 00:05:38,130
So in this example, webpack would go into app.js, look at its imports,

66
00:05:38,270 --> 00:05:42,770
see that we import the project list and therefore go to the project list file,

67
00:05:42,800 --> 00:05:48,170
look at this files imports and therefore see project item and the DOM helper,

68
00:05:48,170 --> 00:05:50,270
look at these files and so on,

69
00:05:50,360 --> 00:05:56,710
this is what webpack would do here to analyse your script and understand what's happening there.

70
00:05:57,930 --> 00:06:04,170
So therefore we need to inform webpack what our entry file is and this now actually is the part where

71
00:06:04,170 --> 00:06:10,890
we will also need to reorganise our folder structure a little bit because now we'll have to split it

72
00:06:11,070 --> 00:06:16,810
into our input source files and our output generated files

73
00:06:17,220 --> 00:06:24,420
and for that, I'll add a new folder here and name it src, it's not a must use but it's a convention

74
00:06:24,420 --> 00:06:30,340
to use src which stands for source as the folder that holds your input files

75
00:06:30,600 --> 00:06:36,240
and then I'll grab the content of the scripts folder, so the app folder, the utility folder and app.js

76
00:06:36,420 --> 00:06:41,970
and drag that into source so that the scripts folder in assets is empty.

77
00:06:41,970 --> 00:06:49,230
So now this is dragged over here and with that dragged over, we now want to specify this app.js file

78
00:06:49,230 --> 00:06:56,380
in the source folder as the entry point and specify assets scripts as the output point

79
00:06:56,430 --> 00:07:02,400
so to say. For that we go back into the webpack.config.js file and now here in this exported

80
00:07:02,430 --> 00:07:10,050
object, you specify an entry key and this can just be a string where you point at your entry file,

81
00:07:10,050 --> 00:07:12,380
it could also be a more complex object,

82
00:07:12,420 --> 00:07:18,240
you can also use multiple entry points but here in this simple project and in many projects you're working

83
00:07:18,240 --> 00:07:21,310
on, you'll have one central entry point.

84
00:07:21,360 --> 00:07:26,980
So here we specify a relative path from this webpack config file to the entry file,

85
00:07:27,030 --> 00:07:33,180
so in my case that's dot slash, which means start in the same folder as the webpack config file, then

86
00:07:33,270 --> 00:07:39,150
source and then in there, app.js, this is my entry file and that's an important piece of information

87
00:07:39,150 --> 00:07:40,590
to webpack.

88
00:07:40,640 --> 00:07:46,860
Now besides the entry file, we also need to specify where the output should be written to and for that, we

89
00:07:46,860 --> 00:07:54,090
can add an output key here and that can now be a Javascript object where we for one specify the file name

90
00:07:54,120 --> 00:07:55,590
that should be generated

91
00:07:55,730 --> 00:08:01,080
and here I'll stick to app.js let's say and the second thing is of course the path where we want

92
00:08:01,080 --> 00:08:02,600
to generate that file in.

93
00:08:02,640 --> 00:08:05,070
Now keep in mind, this will be our bundled code,

94
00:08:05,070 --> 00:08:12,320
this will be one code file in the end which contains all the other merged code files. Now to generate

95
00:08:12,320 --> 00:08:22,840
that path here, we can use a utility module, a utility package built into Node.js which you have available

96
00:08:22,840 --> 00:08:26,840
as well because you installed Node.js and that's the path package.

97
00:08:26,850 --> 00:08:32,880
Now we need to import that package here and if you import, in Node.js you don't do it with import, just

98
00:08:32,880 --> 00:08:35,850
as we also didn't use export to export something,

99
00:08:36,240 --> 00:08:41,010
instead you import like this. We want to use the path package so we store it in a constant, path and

100
00:08:41,010 --> 00:08:47,850
we import it with the require function here where we simply pass the package name to path and path is

101
00:08:47,850 --> 00:08:49,830
a package built into Node.js.

102
00:08:49,860 --> 00:08:55,820
So this imports the path package and stores its features under the path constant and now down there

103
00:08:55,830 --> 00:09:02,820
where we need a path, we can use path.resolve to basically build an absolute path with

104
00:09:02,820 --> 00:09:08,940
the help of that tool, where we want to start in our current path and for that, Node.js has a global

105
00:09:08,940 --> 00:09:15,540
constant, __dirname, this simply gives us access to this current path where the config

106
00:09:15,540 --> 00:09:23,190
file lives in and then ,assets, scripts.

107
00:09:23,590 --> 00:09:29,770
What this does is it constructs a new absolute path and output needs an absolute path, not a relative

108
00:09:29,770 --> 00:09:32,890
one, starting at our current file,

109
00:09:32,890 --> 00:09:40,330
so the absolute path to our current file, adding /assets to this path, adding /scripts to this

110
00:09:40,330 --> 00:09:46,860
path, so that in the end we generate our output here in the scripts folder. And now with that if we save

111
00:09:46,890 --> 00:09:53,310
that, we have a basic webpack setup. Now to use it, let's go to package.json and there you have

112
00:09:53,310 --> 00:09:58,760
this script section. This allows you to set up some scripts which you can run through the command line,

113
00:09:59,010 --> 00:10:03,900
so here you can simply add a new script by adding a comma and then between double quotes any name of

114
00:10:03,900 --> 00:10:12,120
your choice, for example build, now and then a colon and then also between double quotes, the instructions

115
00:10:12,120 --> 00:10:18,120
you want to run and there we can type webpack and this will use this webpack-cli tool under the hood

116
00:10:18,240 --> 00:10:25,000
which in turn will use the webpack tool to do its thing and webpack will automatically search for

117
00:10:25,020 --> 00:10:25,810
such a

118
00:10:25,830 --> 00:10:31,170
webpack.config.js file which is why it's important that you name it exactly like this and take this

119
00:10:31,170 --> 00:10:33,450
configuration into account.

120
00:10:33,480 --> 00:10:39,360
So now we just have to save the package.json file and now let's try running it with npm run build,

121
00:10:41,190 --> 00:10:46,610
this now it starts webpack and here it actually quits with an error.

122
00:10:46,650 --> 00:10:51,840
Now you see, here what it doesn't like is this projects equal thing here,

123
00:10:51,840 --> 00:10:55,140
it doesn't like this syntax.

124
00:10:55,140 --> 00:11:01,120
It tells us we might need an appropriate loader to use this Javascript feature.

125
00:11:01,260 --> 00:11:05,970
Now the thing indeed is that in project list and project item where we have this syntax,

126
00:11:05,970 --> 00:11:14,320
this is very new syntax which at the point of time I'm recording this is not part of the Javascript specification.

127
00:11:14,370 --> 00:11:21,010
It works in Chrome already but not all browsers support it and officially, it's still in draft state,

128
00:11:21,030 --> 00:11:27,120
this class field syntax here which is why webpack out of the box does not understand it and not support

129
00:11:27,130 --> 00:11:29,380
it, ESLint by the way also doesn't,

130
00:11:29,400 --> 00:11:35,880
I'm getting an error here. So this works but it's on the edge so to say and therefore not fully supported

131
00:11:35,880 --> 00:11:37,350
by all tools yet.

132
00:11:37,350 --> 00:11:42,480
Now we could make it work with a so-called loader but that is something I'll dive into a bit little

133
00:11:42,480 --> 00:11:43,440
bit later,

134
00:11:43,440 --> 00:11:49,520
also in the browser support section and therefore for now, the fix simply is to comment this out here and

135
00:11:49,530 --> 00:11:56,850
instead add this project as a property here in the constructor. We can also comment out this unused code

136
00:11:56,850 --> 00:12:02,940
here by the way to make this file error-free, this was a technical error but ESLint also doesn't

137
00:12:02,940 --> 00:12:04,690
like unused code.

138
00:12:04,880 --> 00:12:11,820
Now here in project item, it's the same, we can comment this out and instead add it here, has active tooltip

139
00:12:12,030 --> 00:12:17,870
and set it to false. With that, let's retry this and let's rerun npm run build and

140
00:12:17,890 --> 00:12:19,350
let's see what we get

141
00:12:19,440 --> 00:12:21,950
and again we failed but now with a different error.

142
00:12:22,050 --> 00:12:27,900
If we scroll up a bit to the first red message, we see that it can't resolve projectitem.js.js.

143
00:12:27,900 --> 00:12:31,600
So indeed and that's just something you have to know,

144
00:12:31,690 --> 00:12:38,250
webpack as an extra utility feature doesn't require you to add the extension to your imports,

145
00:12:38,280 --> 00:12:41,550
we needed that when we ran the code like this in the browser

146
00:12:41,700 --> 00:12:48,390
but webpack actually just wants to import without any extension and it then looks for files with .js

147
00:12:48,390 --> 00:12:54,660
at the end automatically. So the fix here is to go through all our files and remove the .js

148
00:12:54,660 --> 00:12:55,350
at the end.

149
00:12:55,350 --> 00:12:59,220
So here in app.js, I remove it at the end of the import in this file,

150
00:12:59,280 --> 00:13:01,080
same in analytics.js,

151
00:13:01,180 --> 00:13:02,910
okay there we have no imports,

152
00:13:02,910 --> 00:13:06,840
same for DOM helper, there we also have no imports, tooltip, there

153
00:13:06,840 --> 00:13:10,400
I did have .js at the end, so I'll remove it there as well.

154
00:13:10,680 --> 00:13:15,630
Projectlist, remove it at the end at as well,

155
00:13:15,630 --> 00:13:19,120
same here, projectitem,

156
00:13:19,190 --> 00:13:19,840
get rid of it

157
00:13:19,840 --> 00:13:23,120
there, also here for our dynamic import

158
00:13:23,120 --> 00:13:23,620
by the way

159
00:13:27,070 --> 00:13:28,810
and that should be it.

160
00:13:28,810 --> 00:13:38,280
If we now save that and we again run this, we get yet another error from the tooltip.js file, line 13,

161
00:13:38,700 --> 00:13:41,220
this close tooltip function.

162
00:13:41,220 --> 00:13:43,350
If we have a look at the tooltip file, in the end,

163
00:13:43,350 --> 00:13:50,330
this is the same syntax I just removed before, where we have that cutting edge class field syntax and

164
00:13:50,330 --> 00:13:51,460
that's the same here,

165
00:13:51,480 --> 00:13:56,150
this in the end is a class field where we store a function instead of another value.

166
00:13:56,370 --> 00:14:03,060
Therefore the fix here as well is to get rid of it here and instead add it here, with this.close

167
00:14:03,060 --> 00:14:04,200
tooltip.

168
00:14:04,350 --> 00:14:09,170
Let's save that and again retry npm run build and now this looks better.

169
00:14:09,170 --> 00:14:09,840
We get a warning,

170
00:14:09,840 --> 00:14:15,900
we can ignore that for now but what we also get are two files here in the scripts folder, in the assets

171
00:14:15,900 --> 00:14:19,720
folder, an app.js file which is quite unreadable,

172
00:14:19,740 --> 00:14:25,070
so it looks like we already got optimization going on and a 1.app.js file.

173
00:14:25,110 --> 00:14:31,420
Now we get two files as output because I do have that lazy loading as it's also sometimes called

174
00:14:31,440 --> 00:14:38,340
in project item, where we only load the tooltip code when we need it and therefore this tooltip code

175
00:14:38,490 --> 00:14:44,760
and all the dependencies that only belong to the tooltip are packed into its own bundle, so that this

176
00:14:44,820 --> 00:14:47,040
still is only loaded when we need it,

177
00:14:47,100 --> 00:14:52,880
instead of upfront in one big bundle, so that we get the best of both worlds. Load some code

178
00:14:52,920 --> 00:14:58,230
only when we need it but load the code we need right from the start in one go instead of dozens of

179
00:14:58,230 --> 00:15:00,280
individual HttpRequests,

180
00:15:00,540 --> 00:15:02,930
that's why we have two bundles.

181
00:15:02,940 --> 00:15:05,000
Now why is it looking like this then?

182
00:15:05,100 --> 00:15:09,820
Because webpack by default built this for production mode and already optimized it,

183
00:15:09,930 --> 00:15:11,730
so let's see how we can change that.
