Web development & API design
L04: Eject! Babel, Webpack, ESLint
Agenda
- Babel
- Webpack
- ESLint
- Assignment 1!

- Previously 6to5
- Modern JS (ES2017) => ES5
- import/export
- () => {}
- const/let
- const { name } = somePerson;
- …
yarn global add babel-cli
> babel script.js
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `This person is called ${this.name}!`;
}
}
const martin = new Person("Martin");
console.log(martin);- Takes one of more files as input
- Runs through all transforms
- Outputs transformed content (concatenated if more than one file)
No transforms
Use a transform
> babel script.js --plugins=transform-es2015-block-scoping
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `This person is called ${this.name}!`;
}
}
var martin = new Person("Martin");
console.log(martin);- Takes one of more files as input
-
Runs through all transforms
- Outputs transformed content (concatenated if more than one file)
> cat script.js
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `This person is called ${ this.name }!`;
}
}
const martin = new Person("Martin");
console.log(martin);Presets
- Babel is plugin-based
- A transform is needed to do anything (other than concatenate)
- Preset = set of transformations
- es2017 = full ES2017 spec
> babel script.js --presets es2015
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Person = function () {
function Person(name) {
_classCallCheck(this, Person);
this.name = name;
}
_createClass(Person, [{
key: "toString",
value: function toString() {
return "This person is called " + this.name + "!";
}
}]);
return Person;
}();
var martin = new Person("Martin");
console.log(martin);Configure Babel
- Flag(s) to babel-cli
- .babelrc in the repo
- package.json
// package.json
{
…,
"babel": {
"presets": [
"react-app"
]
},
…
}Webpack

Tie everything together

What does Webpack do?
-
Loads your source files using loaders
- babel-loader for ES2015 and JSX
-
stylus-loader for Stylus (to CSS)
-
"Bundles" them together into a single file (bundle.js)
-
… which is the only file you include in index.html
-
… which is the only file you include in index.html
-
Lets you import modules ES2015-style (import/export)
- (or require CommonJS or AMD-style)
Simplest possible use
// app.js
import bar from './bar';
bar();// bar.js
export default function bar() {
// do something
}// webpack.config.js
module.exports = {
entry: './app.js',
output: {
filename: 'bundle.js'
}
}//index.html
<html>
<head>
...
</head>
<body>
...
<script src="bundle.js"></script>
</body>
</html>Webpack loaders
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;- Transforms on the way in
- babel-loader applies babel transforms before bundling
- file-by-file basis
Webpack plugins
// …
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};- Do stuff to bundles (and more)
- Uglify all JS!
webpack-dev-server
- Serve your HTML and bundle from memory
- Automatically watch for changes & trigger build
- Gives you a fast feedback loop
- What lives on http://localhost:3000/ with yarn start
- A nice linter!
- Similar to Java's PMD + checkstyle
- Catches formatting and potential bugs

yarn eslint .
(config from package.json)
> yarn eslint .
yarn eslint v1.0.1
$ "/Users/marlehma/Desktop/pg6300-17/f04/code/demo-ejected-app/node_modules/.bin/eslint" "."
/Users/marlehma/Desktop/pg6300-17/f04/code/demo-ejected-app/src/index.js
7:7 warning 'a' is assigned a value but never used no-unused-vars
✖ 1 problem (0 errors, 1 warning)
✨ Done in 1.30s.yarn eslint . --fix
^ helps a lot
Assignment 1: Hello, world!
PG6300-17-04: Eject!
By theneva
PG6300-17-04: Eject!
- 547