Graduate Program KB

Javascript Tools


Agenda

  1. Toolchain
  2. ESLint
  3. Babel
  4. Prettier

Toolchain

  • Set of software development tools used simultaneously
  • Each tool in the chain is a piece of software which serves a purpose
  • Designed to aid/enhance the user experience

ESLint

ESLint Docs: https://eslint.org/

  • Open-source utility originally created in 2013
  • Written using Node.js
  • Allows the user to define a set of rules or coding standards

ESLint: Benefits

  • Finds problems within JS/JSX code
  • Statically analyses (no need to run)
  • Automatic fixing
  • Useable for any application which runs JavaScript
  • With plugins, support for JSX and TypeScript can be reached

ESLint: Why Use It?

  • Creates a single standardised set of conventions
  • Useful in large teams of developers
  • Highlights issues before runtime

ESLint: Installing and Configuring

npm install eslint --save-dev # Install
npx eslint --init # Initialise
  • Running the second command will ask us questions about how we would like to use ESLint
  • Options include:
    1. Check syntax
    2. Check syntax and find problems
    3. Check syntax, find problems, and enforce code styles
  • Additional questions about how we will use ESLint (such as module types, framework used, where our code will be run, project style (standard for this presentation), and the format of our .eslint file)

ESLint: Configuration File

  • We should now have a .eslint{js, yml, json} file within our project directory.
  • This file contains a set of rules
  • Rules define how ESLint should operate

ESLint: Example

const helloYou = (name) => {
  console.log("Hello " + name + "!");
}

Using a 'standard' project style taken from a popular preset. Errors we may come across (using the 'standard' template)

  • helloYou is assigned a value but never read
  • Double quotes are used instead of single
  • Semi-colon added at the end

We can auto-fix these issues be either placing a script in our package.json (like we would place a jest script in), or using ctrl + shift + p in vscode, searching eslint auto, and selecting autofit errors.


ESLint: Updated Example

// prettier-ignore
const helloYou = (name) => {
    console.log('Hello' + name + '!')
}
  • Double quotes automatically changed to single quotes
  • Removed extra semicolons
  • helloYou still gives a warning

Note that ESlint will still give a warning for 'helloYou' as it's value still has not been read. We obviously do not want ESLint to call our functions for us, otherwise this would lead to major side effects. // prettier-ignore was also required in the code, this was to avoid causing conflict between prettier and ESLint, more solid solutions to fix this will be covered later.


ESLint: Rules

(Within our .eslint file)

modules.exports = {
  // ...
  rules: {
    quotes: ['error', 'double'],
    semi: ['error', 'always'],
  },
}
  • Now we have the same rules as prettier, no more conflicts
  • Tedious if many conflicts, especially with many plugins

ESLint: Rules Continued

  • Some rules have multiple options we can choose from
"comma-dangle": ["error", {
    "arrays": "never",
    "objects": "always",
    "imports": "always-multiline",
    "exports": "only-multiline",
    "functions": "ignore"
}]
  • We can get quite specific about certain situation
  • Each value is set to "never" by default

ESLint: Rules Continued

modules.exports = {
  // ...
  extends: ['Standard', 'prettier'],
  // ...
}
  • ESLint is configured to run with prettier as a formatter
  • The last item overrides all previous

ESLint: Running on Save

  • Go into VSCode settings
  • Search Code Actions on Save (then edit in settings.json)
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}
  • Now ESLint will fix all auto-fixable errors on each save

Babel: What is it?

Babel Docs: https://babeljs.io/docs/

  • Used to covert ECMAScript code (2015+ onward) into backward compatible versions of JavaScript
  • Allows newer code styles to be used in old browsers/environments
  • Ensures a greater range of compatibility

Babel: An Example

// 'Newer' code
;[1, 2, 3].map((x) => x + 1)

// Converted
;[1, 2, 3].map(function (x) {
  return x + 1
})
  • Can be thought of as passing in ES6 to babel, and the output is ES5
  • Babel transpiles our code

Babel: An Example Continued

  • Babel turns our code into the AST (Abstract syntax tree)
  • The AST is then modified to follow standards defined (Such as ES5)
  • An output of JS code is generated based on the modified AST

Babel: Why Use It?

  • Allows us to use ES6 syntactic sugar
  • Very useful when support is needed for old browsers or platforms
  • Babel always integrates new standards, we cannot be sure that browsers will
  • Can easily slot in with other toolchains

Babel: Installation

  • Installed a regular npm package
npm install --save-dev @babel/core @babel/cli @babel/preset-env
  • We can create a .babelrc file which will contain our presets and plugins

Babel: Plugins

  • Applying plugins/presets in our configuration file is what allows Babel's code transformations.
  • Ordering of plugins matter (like with ESLint)
    • Plugins before presets
    • Plugins run from first to last
    • Presets from last to first Note that presets are a set of plugins. Presets (such as react) will add support for jsx functionality

Babel: Plugins Continued

{
  "plugins": ["transform-decorators-legacy", "transform-class-properties"],
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

How would these be evaluated?


Babel: Targeting Browsers

    "@babel/preset-env",
    {
      "targets": {
        "firefox": "60",
        "chrome": "67",
        "safari": "11.1"
    }}
  • Checks if our environment supports certain JS syntax
  • Take a list of targets to be checked against preset-env's mappings to compile a list of required plugins

Babel: Examples

"babel": "babel src -d dist"
  • Place this into the 'scripts' section of our package.json
  • Will run files in /src directory and place the output of babel transformations into the /dist directory

Babel: Examples Continued

  • Using our earlier example:
const helloYou = (name) => {
  console.log(`Hello ${name}!`)
}
// Becomes:
;('use strict') // This is an option set in babel
var helloYou = function helloYou(name) {
  console.log('Hello '.concat(name, '!'))
}

Prettier

Prettier Docs: https://prettier.io/

  • A code formatter
  • Multi-language support
  • Will integrate with most editors
  • Released in 2017

Prettier: Why Use It?

  • Code formatting on save
  • Universal coding style
  • Saves time/energy

The Difference Between a Linter and Formatter

Linter

  • Meticulous code inspector which gives a warning when it is unhappy with something we have done
  • A likeness to a detective, analysing everything

Formatter

  • A magic wand
  • Our code gets formatter to simply look better
  • Likeness to a housekeeper
  • Typically faster than a linter

Prettier: Installation

  • Standard npm install
npm install --save-dev prettier
  • We then create a '.prettierrc' file with empty inside it
  • Additionally, create a '.prettierignore'

The .prettier-ignore file can be used to specify which files to not format using prettier. If this is omitted, prettier will default to using the .gitignore file (if it exists).


Prettier: Usage

npx prettier --write .
  • Will format all our files
  • We would rather our specific file to be run on save
  • Most development environments have some form of integration

VSCode has a 'prettier' extension which can be used. We can also change our 'format on save' options in vscode. We need to change our default formatter to prettier, then we can enable this feature.


Prettier: Example

// prettier-ignore
matrix(
  1, 0, 0,
  0, 1, 0,
  0, 0, 1,
)
matrix(1, 0, 0, 0, 1, 0, 0, 0, 1)

Prettier-ignore can be used in all languages that prettier supports. Simply place it within a comment.

Prettier: Plugins

  • Not all languages are supported
  • Can use plugins (official/community) to provide support
  • Easily added within the configuration file

Prettier: Options

  • We can add options within our configuration file (.prettierrc)
{
  "printWidth": 80,
  "semi": true
}

Options have default values which are used if none arte specified. These options tell prettier to make likes roughly 80 characters long, and to place semi-colons at the end of lines when possible.