1
00:00:02,480 --> 00:00:05,950
For some features, you can't use feature detection,

2
00:00:05,960 --> 00:00:10,110
you can't use fallback codes you can't use polyfills and you can't ignore them,

3
00:00:10,130 --> 00:00:17,190
typically that's the case for core Javascript syntax features like let, const, async await, arrow functions,

4
00:00:17,330 --> 00:00:22,790
all of that. These are features you as a developer might want to use because they allow you to write

5
00:00:22,790 --> 00:00:28,430
cleaner code, work around certain issues you have with older Javascript code and so on,

6
00:00:28,430 --> 00:00:34,700
so you want to use this modern code but you also need to support browsers that might not support these

7
00:00:34,700 --> 00:00:36,800
Javascript syntax features.

8
00:00:36,800 --> 00:00:43,070
Let's take let or const as an example here, if we search for it on caniuse, we see const has decent

9
00:00:43,070 --> 00:00:49,730
browser support, even Internet Explorer partially supports it but older versions of Internet Explorer

10
00:00:49,760 --> 00:00:55,970
don't for example and that might be an issue if you need to target these top 0.3% of users.

11
00:00:55,970 --> 00:01:00,920
If you search for arrow functions here, you see there it's even a bit worse,

12
00:01:00,920 --> 00:01:03,900
Internet Explorer for example doesn't support this at all,

13
00:01:03,920 --> 00:01:05,090
not even in version

14
00:01:05,100 --> 00:01:06,970
11.

15
00:01:07,040 --> 00:01:12,830
Now what do you do if you still want to write modern code with all these features and you still want

16
00:01:12,830 --> 00:01:13,480
to support

17
00:01:13,520 --> 00:01:16,040
let's say Internet Explorer in this example

18
00:01:16,040 --> 00:01:18,800
or these older FIrefox or Chrome versions,

19
00:01:18,830 --> 00:01:20,470
what can you do in that case?

20
00:01:20,600 --> 00:01:24,170
You can't use a polyfill because it's a core language feature

21
00:01:24,230 --> 00:01:30,240
and if the let keyword is not recognized there is no way of making it work, unlike promises and fetch,

22
00:01:30,260 --> 00:01:32,500
these are not functions you call after all,

23
00:01:32,510 --> 00:01:40,070
instead const really is just a keyword that tells the engine what the code after it is all about, that

24
00:01:40,070 --> 00:01:44,960
it creates a variable that does not change and in the example of const for example and therefore this

25
00:01:44,960 --> 00:01:48,440
is a functionality that can't be rebuilt with other tools,

26
00:01:48,470 --> 00:01:54,230
it's just missing the const keyword, it's not recognized and therefore browsers that don't know it, that

27
00:01:54,230 --> 00:01:56,000
use a Javascript engine that doesn't know it

28
00:01:56,000 --> 00:02:00,050
I should say will just crash when they detect this keyword.

29
00:02:00,050 --> 00:02:06,440
Now to still make that code work or to still ship, so deploy code that does work,

30
00:02:06,440 --> 00:02:09,330
you can use transpilation.

31
00:02:09,620 --> 00:02:17,030
The idea behind transpilation is that you transpile, transform your code, your modern code into older

32
00:02:17,030 --> 00:02:22,430
code and this of course is not done manually because if it would be done manually, you could just write

33
00:02:22,550 --> 00:02:24,330
older code right from the start,

34
00:02:24,350 --> 00:02:30,290
instead you have tools for that, most prominently Babel is a tool that does that for you,

35
00:02:30,290 --> 00:02:36,500
it can even be integrated into your webpack workflow so that that all happens in one step.

36
00:02:36,500 --> 00:02:43,160
This allows you to write modern code, use cutting Edge Javascript language features and still ship, so

37
00:02:43,170 --> 00:02:51,350
deploy, cross browser code that for example still uses var instead of const and let or that uses normal

38
00:02:51,380 --> 00:02:54,210
functions instead of arrow functions.

39
00:02:54,260 --> 00:02:56,710
So how would that look like?

40
00:02:56,720 --> 00:03:01,380
Well for that, we need to quit our development server and now install that transpiler,

41
00:03:01,460 --> 00:03:07,270
you do that with npm install --save-dev and now let's see which transpiler we need.

42
00:03:08,370 --> 00:03:12,620
For that, you can just google for Babel and you should find babeljs.io,

43
00:03:12,720 --> 00:03:19,650
now actually let's search for Babel loader, this is the webpack integration and go to that GitHub repository

44
00:03:19,650 --> 00:03:25,440
we find there, on babeljs.io however, you can learn more about the Babel project and all its

45
00:03:25,440 --> 00:03:27,440
rich configuration options and so on,

46
00:03:27,450 --> 00:03:33,630
so definitely also check this out. Now here on Babel loader, you learned how you can install it and

47
00:03:33,630 --> 00:03:40,350
you will actually need to install Babel loader, @babel/core, @babel/preset-env, and webpack

48
00:03:40,350 --> 00:03:45,510
we don't need that, we already got this in our project setup but we need the other three packages, so

49
00:03:45,510 --> 00:03:52,050
you can just copy that and add this here after --save-dev, by the way --save-dev

50
00:03:52,050 --> 00:03:55,850
is just a longer form of just -d here.

51
00:03:56,280 --> 00:04:01,530
So now hit enter and this will now install these three packages into your project and we can then tweak

52
00:04:01,530 --> 00:04:07,800
the webpack configuration to use them. In the end what we got here is Babel loader, which is the integration

53
00:04:07,800 --> 00:04:12,190
into webpack which basically does the connection of webpack and the Babel tool,

54
00:04:12,360 --> 00:04:15,080
we got Babel core which is that Babel tool,

55
00:04:15,090 --> 00:04:22,320
so the tool that actually knows how to translate modern code to older code and Babel preset env is a

56
00:04:22,650 --> 00:04:27,780
preset that controls which features are compiled in which way,

57
00:04:27,780 --> 00:04:32,100
so actually this is the package with the concrete translation rules

58
00:04:32,100 --> 00:04:36,700
you could say. So now we have these three packages,

59
00:04:36,710 --> 00:04:37,820
now how can we use them?

60
00:04:37,820 --> 00:04:45,080
Well just as explained here, you have to add this entry here to your webpack configuration, so let's copy

61
00:04:45,080 --> 00:04:52,310
that actually and then go to webpack.config.js and there let's say above the plugins, though

62
00:04:52,310 --> 00:04:54,210
the exact position does not matter,

63
00:04:54,260 --> 00:04:56,730
you paste this in and add a comma after it.

64
00:04:56,810 --> 00:05:02,900
This adds a module entry which basically gives instructions to webpack how to transform your different

65
00:05:02,900 --> 00:05:06,950
modules and a module in webpack world is just a file,

66
00:05:07,040 --> 00:05:09,670
so it basically tells webpage what to do with the files

67
00:05:09,680 --> 00:05:15,590
it's managing, then you can add a rules entry here and that takes multiple rules because you can control

68
00:05:15,860 --> 00:05:20,380
different kinds of files with different so-called loaders.

69
00:05:20,390 --> 00:05:24,260
A rule is a Javascript object where you have a test property, there

70
00:05:24,350 --> 00:05:29,240
you define how the file you want to translate should be identified.

71
00:05:29,240 --> 00:05:35,750
This is a regular expression, you learned about these briefly in the strings and numbers section of this

72
00:05:35,750 --> 00:05:36,500
course

73
00:05:36,560 --> 00:05:44,570
and here we're basically saying any file ending with .js or mjs, so with an extension of js or

74
00:05:44,570 --> 00:05:51,170
mjs, should be treated or should be handled by this rule, other files ending with a different extension

75
00:05:51,500 --> 00:05:52,480
of which we have none

76
00:05:52,490 --> 00:05:58,220
but if we had them would be ignored. Now we also want to exclude any files that are in those

77
00:05:58,220 --> 00:06:03,240
modules or power components which is another package manager which we don't have here,

78
00:06:03,260 --> 00:06:09,170
so we can actually remove that, will be ignored so that we don't start transpiling code which is part

79
00:06:09,170 --> 00:06:10,730
of third-party packages,

80
00:06:10,730 --> 00:06:16,550
these should be ready to use out of the box and then we have the concrete action that should be taken

81
00:06:16,700 --> 00:06:18,240
with the use key here.

82
00:06:18,290 --> 00:06:24,110
It's again an object where we configure the loader that should be applied, so that Babel loader should

83
00:06:24,110 --> 00:06:32,800
take care about such Javascript files and that as an option, it should use that preset-env ruleset.

84
00:06:32,930 --> 00:06:38,750
This is now what we're doing here and we also should do that by copying that in the webpack config

85
00:06:38,760 --> 00:06:39,560
profile.

86
00:06:39,950 --> 00:06:46,130
Arguably there it's even more important because this is the code we ultimately want to ship to our users.

87
00:06:46,130 --> 00:06:51,620
So here under testing, we might test this in modern browsers anyways, though you should still compile it

88
00:06:51,620 --> 00:06:55,970
there so that you have the same experience as the users who use your actual code

89
00:06:56,090 --> 00:07:00,950
but it's the users who get your production ready code that actually needs that code that works in older

90
00:07:00,950 --> 00:07:02,830
browsers as well.

91
00:07:02,900 --> 00:07:04,370
So now that's a first step,

92
00:07:04,370 --> 00:07:05,900
now we're not entirely done though,

93
00:07:05,930 --> 00:07:10,820
we need to configure which browsers we want to support because that's the cool thing about 

94
00:07:10,820 --> 00:07:11,720
@babel/preset-env,

95
00:07:12,020 --> 00:07:19,100
I said it's a set of rules that controls which features are translated to which older code, for example

96
00:07:19,130 --> 00:07:22,140
that let and const are translated to var.

97
00:07:22,370 --> 00:07:27,100
Now of course the exact translation you want depends on which browsers you're targeting,

98
00:07:27,110 --> 00:07:33,440
this is where we come back to our market analysis because keep in mind if you revisit this compat table

99
00:07:33,860 --> 00:07:39,080
that the different features modern Javascript offers have different browser support,

100
00:07:39,080 --> 00:07:42,470
for example const and let have quite decent browser support

101
00:07:42,470 --> 00:07:48,800
so we might not even need to compile them if all we want to target is Internet Explorer 11 and higher

102
00:07:49,190 --> 00:07:54,860
and these partial features which are missing are not a problem to us. On the other hand, there might be

103
00:07:54,920 --> 00:08:00,740
other features which are also important to us which are not supported in the browser

104
00:08:00,740 --> 00:08:03,290
we want to target and therefore they should be compiled.

105
00:08:03,290 --> 00:08:09,800
So we want to tell Babel and this preset-env package for which browser is the compilation should

106
00:08:09,800 --> 00:08:13,740
be fine tuned and thankfully, Babel works exactly like that,

107
00:08:13,790 --> 00:08:19,100
it wants this information and then it really gives you code that is fine tuned to the browsers you want

108
00:08:19,100 --> 00:08:20,500
to support.

109
00:08:20,510 --> 00:08:22,820
Now how do we pass that information to Babel

110
00:08:22,820 --> 00:08:24,960
however? We can do that with the package.json,

111
00:08:24,970 --> 00:08:34,100
there simply add a new entry, let's say here which you name browser list, like this. The value it holds

112
00:08:34,100 --> 00:08:41,030
is also a string with double quotes and now in here, you can specify a browser list configuration string,

113
00:08:41,030 --> 00:08:47,570
browser list is a separate package and tool that is used under the hood by @babel/preset-env and attached,

114
00:08:47,570 --> 00:08:51,840
you find a detailed description of which options you can set there.

115
00:08:51,890 --> 00:08:59,300
You can do stuff like set > 2% which means you want to output code that works in browsers

116
00:08:59,510 --> 00:09:05,450
that have a market share of greater than 2% and of course every time you build, this is checked

117
00:09:05,450 --> 00:09:12,650
and this under the hood taps into a source which is always kept up-to-date so that you build code that

118
00:09:12,650 --> 00:09:16,900
works in browsers with greater than 2% market share.

119
00:09:16,910 --> 00:09:21,690
Now with that, that should be browsers list by the way with an s after browser,

120
00:09:21,710 --> 00:09:29,000
now with that we can run npm run build prod or just build to get the unoptimized output

121
00:09:29,000 --> 00:09:34,880
and now in scripts here we see an app.js file with our code and yet now the interesting thing is of

122
00:09:34,880 --> 00:09:36,220
course this is the webpack world

123
00:09:36,230 --> 00:09:41,900
so it has all this webpack extra code but what we can see if we scroll down a bit is for example here,

124
00:09:41,900 --> 00:09:44,690
we see const button equals document query selector.

125
00:09:44,690 --> 00:09:47,900
This is our code and webpack then does some stuff with it

126
00:09:47,900 --> 00:09:52,870
but this is our code and you'll see for example const was kept here.

127
00:09:52,880 --> 00:09:57,950
Now if I change this to let's say we want to support browsers with a market share greater than 0.2 which

128
00:09:57,950 --> 00:10:04,710
of course includes way older and smaller browsers and I now rebuild this, let's check the output again.

129
00:10:04,940 --> 00:10:08,510
If we now go down there, we see we get a var in there.

130
00:10:08,510 --> 00:10:14,270
So now our code really was translated to code that would work in older browsers as well

131
00:10:14,270 --> 00:10:21,920
and this all happens magically with the help of webpack Babel loader and the browsers list and again,

132
00:10:22,100 --> 00:10:28,130
attached you find the link to the documentation of which options you can set there because you can not

133
00:10:28,130 --> 00:10:34,370
just target market shares, you can also be specific about different browser versions, so you could say

134
00:10:34,490 --> 00:10:36,470
Chrome version 58,

135
00:10:36,500 --> 00:10:41,990
Internet Explorer version 11 or higher and so on, so you can also set stuff like that.

136
00:10:42,080 --> 00:10:49,120
You can also combine multiple queries or multiple instructions, for example you can add not dead here,

137
00:10:49,160 --> 00:10:52,870
this means only browsers that still have official support,

138
00:10:52,940 --> 00:10:58,220
for example Internet Explorer 10 at the point of time recording this would be considered dead because

139
00:10:58,220 --> 00:11:00,840
it's not receiving any official support anymore,

140
00:11:00,860 --> 00:11:04,830
Internet Explorer 11 is at least receiving some support still.

141
00:11:05,000 --> 00:11:10,220
So these are some things you can set up there and this will influence how your code is transpiled and

142
00:11:10,220 --> 00:11:16,790
how you can make your modern code which does use constant arrow functions also work in older browsers

143
00:11:16,910 --> 00:11:24,170
because const and let is translated to var and an arrow function for example is translated into a normal

144
00:11:24,170 --> 00:11:25,400
function.

145
00:11:25,400 --> 00:11:31,670
Now one problem we still might have in this example here for example is that we still use then, so we

146
00:11:31,670 --> 00:11:39,920
still use promises and now we have code that works in older browsers from a Javascript syntax perspective

147
00:11:40,280 --> 00:11:46,580
but it still might not really work there because whilst we transpiled core syntax features like

148
00:11:46,580 --> 00:11:53,870
let and const, other features like promises might still not be working in these older browsers. So we might

149
00:11:53,870 --> 00:11:59,810
want to combine this approach with a polyfill and as it turns out, this is also rather simple.
