Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Latest commit

 

History

History
357 lines (248 loc) · 17.3 KB

es6-4-polyfills-transpiling.md

File metadata and controls

357 lines (248 loc) · 17.3 KB

JavaScript Polyfills and Transpiling

Udacity logo

ES6 - JavaScript Improved course lesson 4/4

Udacity Google Mobile Web Specialist Nanodegree program part 3 lesson 07

Udacity Grow with Google Scholarship challenge course lesson 09

Brendon Smith

br3ndonland

Table of Contents

Intro

This lesson will show us how to write ES6 code, even when browsers haven't caught up to the latest features yet.

ES6 is also referred to as ES2015.

4.01. The Web is Growing Up

4.02. Old and New Browsers

Code doesn't work in old browsers

The code from the course throws errors in old browsers like Safari 9 and IE 11

ES6 Safari 9 error

ES6 IE 11 error

It makes sense that code doesn't work in older browsers that were developed prior to the release of ES6, but there are some browsers that have been released after ES6 that don't support the new JavaScript syntax and functionality yet.

Most of us don't think much about the browser and all it can do...until it doesn't work! But really, browser makers have a tough time. Think about HTML, CSS, and JavaScript - these languages are fluid and are always improving. Browser makers have to keep up with all of these changes.

But how do they know about these changes

They learn (or actually build) the language specifications!

Just like the World Wide Web Consortium (W3C) is the standards body for things like HTML, CSS, and SVG, Ecma International is an industry association that develops and oversees standards like JavaScript and JSON. You can find the specifications for ES6 here.

Further Info

Ecma International is an important industry community and definitely worth checking out in more detail:

NOTE: The code we've been looking at in this course is not supported by older browsers. Older browsers that were developed prior to the release of ES6 were developed to support the version of JavaScript at the time (which was ES5.1). If you try running any ES6 code in an older browser, it won't work.

4.03. ES6 Specification

Intro to ES6 Specification

The specification (commonly shortened to "spec") for ES6 can be found here. The spec lists the set of rules and guidelines on how the language is supposed to function. It doesn't give specific details on how browser makers are supposed to achieve functionality, but it does provide step-by-step instructions on how the language is supposed to work. While making this course, we repeatedly referred to this official spec.

Ok, so honestly, it can be a little difficult to decipher some of the cryptic wording of the spec. But when you have a question about ES6, we recommend checking out info on the topic like that provided by the Mozilla Developer Network and then also reviewing what the spec actually says.

Quiz Question

Check out the ES6 Specification. Which section in the spec covers arrow functions?

  • section 6
  • section 10.3.2
  • section 14.2
  • section 18.3.29
Solution

section 14.2

4.04. Supported Features

How Can You Know What Features Browsers Support

With new language specifications coming out every year and with browsers updating every other month, it can be quite challenging to know what browser supports which language features. Each browser maker (except for Safari) has a website that tracks its development status. Checkout the platform feature updates for each browser:

NOTE: Safari doesn't have its own platform status website. Under the hood, though, Safari is powered by the open source browser engine, Webkit. The status for Webkit features can be found here.

This can be a lot of information to track down. If you prefer a birdseye view of all the feature support for all JavaScript code, check out

You can also use the ECMAScript Compatibility Table built by @kangax:

4.04 Quiz Question

Looking at the ECMAScript Compatibility Table, what kind of information does the first colored column display?

  • The list of up-to-date browsers that support ES6.
  • The list of all ES6 features.
  • The status of all ES6 features supported by your current browser.
  • Links to each browser platform's status for the specific ES6 feature.
Solution

The status of all ES6 features supported by your current browser.

The very first column lists all of the ES6 features. The second column in the table is the first one that's colored and displays the support of each ES6 feature in your the current browser.

4.05. The Web is Eternal

As developers, we need to always be learning and adapting as the web does.

Polyfills

4.06. Polyfills

Richard and James use the analogy of filling a hole in the wall with spackling (UK brand name is Polyfilla).

In JavaScript, a polyfill is:

a JavaScript file that patches a hole by replicating some native feature that's missing.

4.07. Using Polyfills

What is a polyfill

A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively.

Coined by Remy Sharp - https://remysharp.com/2010/10/08/what-is-a-polyfill

We, as developers, should be able to develop with the HTML5 APIs, and scripts can create the methods and objects that should exist. Developing in this future-proof way means as users upgrade, your code doesn't have to change but users will move to the better, native experience cleanly. From the HTML5 Boilerplate team on polyfills - https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills

Further info

An example polyfill

The code below is a polyfill for the new ES6 String method, startsWith():

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0
    return this.substr(position, searchString.length) === searchString
  }
}

As you can see, a polyfill is just regular JavaScript.

This code is a simple polyfill (check it out on MDN), but there's also a significantly more robust one, here

4.07 Quiz Question

Why does the startsWith() polyfill begin with the following line?:

if (!String.prototype.startsWith)
  • Without it, the script would throw an error.
  • It checks to make sure the String.prototype exists.
  • It avoids overwriting the native startsWith method.
Solution

It avoids overwriting the native startsWith method.

I thought it would just check for startsWith, but didn't realize that overwriting would be a concern.

Remember that a polyfill is used to patch missing functionality. If the browser supports ES6 and has the native startsWith method, then there's no reason to polyfill it. If this check didn't exist, then this polyfill would overwrite the native implementation.

4.08. Polyfill Walkthrough

Remember that a polyfill is used to fill a hole in a browser that doesn't yet support the native feature.

This polyfill starts with a check to see if the native startsWith method actually exists. If it does exist then we don't want to override the native version with this one. If it doesn't exist then the browser will then run the code following.

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0
    return this.substr(position, searchString.length) === searchString
  }
}

;/- Sample usage */
"Udacity".startsWith("Udac") // returns `true`
"Udacity".startsWith("Udac", 2) // returns `false`
"Udacity".startsWith("ES6") // returns `false`

This adds a new method to String's prototype object. The function defaults to the position indicated by this second argument that's passed in or it'll be the first character of the string.

Then it returns true or false if the string that's passed in is the same as the string that we're looking at.

4.09. Other Uses for Polyfills

Polyfills aren't only for patching missing JavaScript features

JavaScript is the language used to create a polyfill, but a polyfill doesn't just patch up missing JavaScript features! There are polyfills for all sorts of browser features:

  • SVG
  • Canvas
  • Web Storage (local storage / session storage)
  • Video
  • HTML5 elements
  • Accessibility
  • Web Sockets
  • and many more!

For a more-complete list of polyfills, check out this link

Transpiling

4.10. Transpiling

  • Compiling: source code -> machine code. Reduces abstraction.
  • Transpiling: source code -> another source code at the same level of abstraction.

Quiz

To convert Java to JavaScript, would you use a compiler or a transpiler?

Solution

First try

Transpiler

Since both the Java source code and the JavaScript target code are of the same level of abstraction (they're both human-readable), a transpiler would be used.

4.11. Using Babel

Intro to Babel

The most popular JavaScript transpiler is called Babel.

Babel's original name was slightly more descriptive - 6to5. This was because, originally, Babel converted ES6 code to ES5 code. Now, Babel does a lot more. It'll convert ES6 to ES5, JSX to JavaScript, and Flow to JavaScript.

Before we look at transpiling code on our computer, let's do a quick test by transpiling some ES6 code into ES5 code directly on the Babel website. Check out Babel's REPL(Read-Eval-Print Loop) and paste the following code into the section on the left:

class Student {
  constructor(name, major) {
    this.name = name
    this.major = major
  }

  displayInfo() {
    console.log(`${this.name} is a ${this.major} student.`)
  }
}

const richard = new Student("Richard", "Music")
const james = new Student("James", "Electrical Engineering")

Babel REPL

Transpiling project in repo

If you check in the repo for this project, inside the Lesson 4 directory is a little project that's all set up for transpiling ES6 code to ES5 code. There's an "ES6" directory that contains the ES6 code we'll be transpiling (using Babel) to ES5 code that will be able to run in every browser.

The way Babel transforms code from one language to another is through plugins. There are plugins that transform ES6 arrow functions to regular ES5 functions (the ES2015 arrow function plugin). There are plugins that transform ES6 template literals to regular string concatenation (the ES2015 template literals transform). For a full list, check out all of Babel's plugins.

JavaScript ES6 code in project

Now, you're busy and you don't want to have to sift through a big long list of plugins to see which ones you need to convert your code from ES6 to ES5. So instead of having to use a bunch of individual plugins, Babel has presets which are groups of plugins bundled together. So instead of worrying about which plugins you need to install, we'll just use the ES2015 preset that is a collection of all the plugins we'll need to convert all of our ES6 code to ES5.

You can see that the project has a .babelrc file. This is where you'd put all of the plugins and/or presets that the project will use. Since we want to convert all ES6 code, we've set it up so that it has the ES2015 preset.

{
  "presets": ["es2015"]
}

JavaScript ES6 preset in project

WARNING: Babel uses both Node and NPM to distribute its plugins. So before you can install anything, make sure you have both of these tools installed:

  • install Node (which will automatically install NPM)

4.12. Transpiling Walkthrough

Note that Richard has selected the MIT license for his materials. I have correspondingly also selected the MIT license for my course repo.

The project's *package.json- file lists all of the NPM packages that this project depends on.

This project depends on

  • babel-cli
  • babel-preset-es2015

The babel 2015 preset is a collection of all es6 plugins. So these are the plugins that will be downloaded and installed.

Once they're installed we need to tell the Babel CLI which plugins it should use to do the transpiling. The CLI will check the *.babelrc- file for which plugins and presets to use.

So the _package.json- file lists what should be installed and the _.babelrc- file tells babel which plugins to use when it does its transpiling.

Now that babel knows to use this preset we need to tell it to actually transpile the code. To do that we've added a build script that will tell babel to take the files in the ES6 directory, transpile them using the es2015 preset, and then put the transformed code in the ES5 directory.

NPM dependencies of project

4.13. Transpiling Recap

NOTE: As of the creation of this course (circa Winter 2016), most of ES6 is supported by the current set of browsers. But that's "most", not "all", unfortunately. And that's also referring to "current" browsers. There are plenty of older browsers that do not support many, if any, of the new ES6 additions. However, it is safe to say that pretty much every browser supports the previous version of the language (ES5.1).

It's important to stay on top of all the changes JavaScript is going through. The best way to do that is to start making use of the new features that are added. The problem is that not all browsers support these new features.

So, to have your cake and eat it too, you can write in ES6 and then use a transpiler to convert it to ES5 code. This lets you transform your project's code base to the newest version of the language while still letting it run everywhere. Then, once all of the browsers your app has to run on fully support ES6 code, you can stop transpiling your code and just serve the straight ES6 code, directly!

4.14. Course Summary

Course Summary

Feedback on Lesson 9 (JavaScript ES6 lesson 4/4)

Informative and helpful lesson.

Previous lesson

(Back to top)