Lesson Tuesday

Most students use Chrome at Epicodus. Chrome is an evergreen browser; evergreen browsers are constantly (and automatically) being updated.

One nice thing about Chrome is that it's almost entirely compatible with ES6. However, many browsers aren't. Because of this, we need to transpile our ES6 code to ES5 code that all browsers can read. Transpilation is the process of compiling code from one language to another (or in this case, one version to another).

Introduction to Babel

To do this, we'll use Babel, a popular JavaScript transpiler. Babel is hands-down one of the most popular JavaScript compilers available. It's considered a source-to-source compiler, because it translates source code of one language (like ES6) into source code of another language (ES5, in our case).

This means Babel allows developers to write the latest JavaScript syntax (ES6, ES7, JSX, and more) even if all browsers don't support it yet. Babel handles translating this syntax back down into the ES5 that's compatible with nearly all browsers.

Installation

We need to install three more packages to get Babel up and running:

$ npm install [email protected] [email protected] [email protected] --save-dev

babel-core is Babel itself. You might be able to make an educated guess about babel-loader... if you guessed it allows Babel to work with webpack, you're correct. (The key hint here is "loader," since loaders are a big part of webpack.)

Last, we need to actually install the preset (babel-preset-es2015) that specifies how Babel can convert ES2015 (also known as ES6) to ES5 code that our browsers can read.

Next, we need to add a new rule to webpack.config.js:

webpack.config.js
...
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader"
      },
      // new rule
      {                         
        test: /\.js$/,
        exclude: [
          /node_modules/,
          /spec/
        ],
        loader: "babel-loader",
        options: {
          presets: ['es2015']
        }
      }
    ]
  }
};

It's pretty similar to our other loaders: we'll check all JS files except for files in nodemodules_ and spec folders. We also include the preset we need as an option.

However, if we run $ npm run build, we'll get an error:

  3:1   error  'require' is not defined  no-undef
  5:17  error  'require' is not defined  no-undef

✖ 2 problems (2 errors, 0 warnings)

ERROR in ./src/ping-pong.js

  3:23  error  'exports' is not defined  no-undef
  6:1   error  'exports' is not defined  no-undef

✖ 2 problems (2 errors, 0 warnings)

Updating ESLint

Now our linter is mad at us again! This is because Babel took our import and export statements (ES6) and converted them to require statements under the hood. We haven't specified that ESLint should be okay with require statements. It's a quick fix. We just need to update our ESLint configuration in .eslintrc:

.eslintrc
{
    ...
    "env": {
      "browser": true,
      "jquery": true,
      "node": true
    },
    ...
}

We just need to add "node": true to the environment section of our ESLint configuration. That's because require statements are native to Node; now that ESLint knows that our environment uses Node features, it will no longer complain.

We can now build, test and lint ES6 code. Let's move on to learning more ES6 features!