Book Image

Modern JavaScript Web Development Cookbook

By : Federico Kereki
Book Image

Modern JavaScript Web Development Cookbook

By: Federico Kereki

Overview of this book

JavaScript has evolved into a language that you can use on any platform. Modern JavaScript Web Development Cookbook is a perfect blend of solutions for traditional JavaScript development and modern areas that developers have lately been exploring with JavaScript. This comprehensive guide teaches you how to work with JavaScript on servers, browsers, mobile phones and desktops. You will start by exploring the new features of ES8. You will then move on to learning the use of ES8 on servers (with Node.js), with the objective of producing services and microservices and dealing with authentication and CORS. Once you get accustomed to ES8, you will learn to apply it to browsers using frameworks, such as React and Redux, which interact through Ajax with services. You will then understand the use of a modern framework to develop the UI. In addition to this, development for mobile devices with React Native will walk you through the benefits of creating native apps, both for Android and iOS. Finally, you’ll be able to apply your new-found knowledge of server-side and client-side tools to develop applications with Electron.
Table of Contents (15 chapters)

Adding Flow for data types checks

Let's finish this chapter by considering a tool that turns JS into a (sort of) new language, a typed one. One of the characteristics of JS is being untyped; for example, a variable can hold, or a function may return, any kind of value, there's no way to declare what type(s) should be stored in a variable or returned from a function. In this section, we will add Flow, a tool developed by Facebook, which allows for data type controls.

Angular developers do not go for Flow, and opt for TypeScript instead. (OK, not Angular developers only; you can use TypeScript practically everywhere!) This version of JS was developed by Microsoft, and also includes data typing in a style very similar to Flow. TypeScript has its own transpiler, and you won't need Babel or Flow, so configuration will be a tad simpler. Instead of ESLint, you'll use TSLint, but you need not forego ESLint's rules: install tslint-eslint-rules; (see https://github.com/buzinas/tslint-eslint-rules) and you'll get the best of both worlds.

We will be getting into how to fully use Flow in the Adding types section of Chapter 2, Using JavaScript Modern Features, but let me give you a preview of what we expect; then, we'll get to install all the needed packages, and afterwards we'll go into more details. Imagine you wrote a highly complex function to add two numbers:

function addTwoNumbers(x, y) {
return x + y;
}

console.log(addTwoNumbers(22, 9)); // 31, fine

However, since JS won't check types and has some conversion rules, the following two lines would also work:

console.log(addTwoNumbers("F", "K")); // FK - oops...
console.log(addTwoNumbers([], {})); // [object Object]! more oops...

You could, on principle, add a lot of data type checking code to your function to verify typeof(x)==="number", but that can become a chore. (Although, of course, for some cases it's the only solution.) However, many errors can be detected before even running the code, as would happen here.

If you modify the function to include data type declarations, Flow will be able to detect the two wrong uses, and you will be able to solve the situation before even running the code:

function addTwoNumbers(x: number, y: number) {
return x + y;
}

Basically, that's all there is! Of course, there are many details about what data types are available, defining new ones, using interfaces, and much more, but we'll get to that in the next chapter. For the time being, let's just install it with the promise that we will learn more about its use very shortly.

How to do it...

Installing Flow depends on whether you are working with Babel (as would be the case for client-side browser code) or not (as you would do for server-side code). We will see how to deal with Node starting in Chapter 3, Developing with Node; here, we'll just consider Babel.

To start, execute the following command to get the needed Flow packages, including the Babel and ESLint ones:

npm install flow-bin babel-preset-flow eslint-plugin-flowtype --save-dev

Then, add the "flow" preset for Babel in package.json:

"babel": {
"presets": ["env", "flow"]
},

Add some lines to the ESLint configuration, also in package.json:

"eslintConfig": {
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"
},
"env": {
"browser": true,
"node": true
},
"parser": "babel-eslint",
"extends": ["eslint:recommended", "plugin:flowtype/recommended"],
"plugins": ["flowtype"],
"rules": {
.
.
.
}
},

Add a "flow" script in package.json:

"scripts": {
"build": "babel src -d out",
"flow": "flow",
.
.
.
},

Finally, perform npm run flow init to initialize Flow, only once, to create a .flowconfig file with information that will be used by the Flow process. (See https://flow.org/en/docs/config/ for more information on this file.)

The .flowconfig file doesn't really match the style of other configuration files, and should really be a JSON file instead, possibly part of package.json. However, this is a still pending item; you can check https://github.com/facebook/flow/issues/153 to monitor advances, but for the time being, you'll have to deal with .flowconfig as is.

How it works...

With the configuration you just wrote, you are set! Just do npm run flow whenever you start to work, to run a background process that will check your code incrementally and let you know about possible data type problems. However, you may even skip this step if you work with VSC; see the next section.

Configuring Flow's linting

Even though ESLint has us well covered for avoiding JS bad coding practices, it doesn't do much with regard to data types, but Flow can help us in this area.

There is a set of rules you can apply, and you will configure them through the .flowconfig file we mentioned in the previous section:

[lints]
all=warn
unsafe-getters-setters=off

The first line, all=warn, is a catch-all, which defines the standard setting for all rules; possible values are off, warn, and error. After that, you can specify settings for individual rules; for example, in the preceding code I decided to ignore warnings about unsafe getters or setters. Some rules are as follows:

  • sketchy-null, which applies whenever you test the value of a variable that could be false (for example, zero) but also null or undefined, in the context of something like if (x) { ... }. This warning is meant to remind you that the variable might have a value you weren't considering.
  • sketchy-null-bool, sketchy-null-number, sketchy-null-string, and sketchy-null-mixed are more granular versions of sketchy-null, and apply only to the specified data types.
  • unclear-type warns about using any, Object, or Function as data type annotations.
  • untyped-import and untyped-type-import warn you against importing from untyped files.
  • unsafe-getters-setters advises against using getters or setters, because of their side effects.
Read the complete current set of Flow linting rules at https://flow.org/en/docs/linting/rule-reference/, where you will also find examples of each rule.

You should also set include_warnings to true, in order to be able to get warnings in VSC:

[options]
include_warnings=true

Whatever settings you include in .fontconfig will apply globally to your entire project, but you can also change them on a file-by-file basis, or even for a single line of code, along the same lines as with ESLint. You can disable warnings for a line by using a flowlint-next-line comment and listing the rules you want to change:

// flowlint-next-line sketchy-null-bool:off
if (x) {
// ...
}

There is another comment, flowlint, that applies to the complete file. Checkout https://flow.org/en/docs/linting/flowlint-comments/ for more possibilities.

Using Flow within VSC

As we have been doing previously, we'll want to see Flow problems right in VSC. There's a simple solution: just go to Extensions, search for Flow Language Support, and install the package; that's it!

You'll also have to change two settings for VSC:

  • Add "flow.useNPMPackagedFlow": true and this will remove the need to do npm run flow at the beginning; the extension will do that on its own
  • Add "javascript.validate.enable": false to avoid clashes between Flow's syntax and JS

After that, you will be able to see Flow errors onscreen; see following screenshot for an example:

The VSC Flow extension lets you catch data type errors in real time; however, error messages are not always very clear