Topics on the language itself

ES5 works with most browsers, though there are various execution environments of JavaScript. If you do your best on ES5 in the first place, you can be freed from confusing compiler (transpiler), that is, Babel.

As JavaScript has a lot to learn, so first you should think about the option not to tackle with Babel.

It was impossible for me to choose that option, not facing Babel. The reason is simple; I do not want to write a lot of function . How about everyone?

I think I should repeat that I came from Java and it is true that I do not have any negative feelings on the process of compiling.

Babel is everyone’s sandbox

Designing a programming language is somewhat lonely work. Until now, a few language designers have released the language carefully until they get a shape to some extent.

However, at least in the case of JavaScript, we had learned from ECMAScript 4’s failure that it will not work in such a way.

So here comes Babel, where you can casually implement experimental language features in the form of the plugins of it. Discuss the features of New language Proposals as using them agressively and decide the features to import into the next version of JavaScript.

Users can just try using cool new features by just writing .babelrc . If the feature is not better than expected or is unstable, you can just stop using it.

It is fun to add and subtract language features depending upon your demands.

Babel modules

There are many modules for Babel, but there are surprisingly few good ones that you should dig into.

The first two are modules for setting up the environment, and the other two are modules for working with other tools.

babel-preset-env is a handy module that automatically selects the Babel plugin to use, in conjunction with the environment where the JavaScript source code runs that is converted by Babel.

In JavaScript ecosystem, the execution environment of browsers and Node.js and so on get improved hand over hand, the plug-in of Babel required at compile time changes accordingly. Though even if unnecessary plugins are activated, what happens is only that ompilation time get slightly increased.

However, it is not very healthy that you can’t keep up with the latest state unless you are conscious.

Using babel-preset-env will free you from such bold work. Just updating the module on a regular basis will bring you the latest environment, which is just awesome.

babel-register is a hacking module that hooks Node's require and inserts Babel's process.

It is not used on loading modules with production code but mainly on running test code.

When executing unit test code in JavaScript, it is common to run a test by detecting a change of file.

If slight modification of the test code kicks compilation of all the project code, you cannot focus on writing code at all.

To avoid that situation, you can fully automate the process of compiling only files that have changed and that are related to those changes by hooking require or import .

Please note that the test code which does not refer directly to the code under test, such as a test like an E2E test, sometimes does not work very well.

babel-eslint is a parser to handle JavaScript code extended by Babel with ESLint.

ESLint has evolved properly, so if you write code on ES and JSX as usual, you do not need babel-eslint .

The reason why this is necessary is because you use a tool to declare and validate the type in JavaScript called Flow.

As for Flow and ESLint, I will explain properly later.

babel-plugin-transform-flow-strip-types is, as its name says, a module that automatically removes information about types declared for Flow.

After deleting the information for typing, it converts the written code to JavaScript executable at the target runtime.

On condition with a fixed language specification without using Flow, Babel requires almost no configuration. So, I think we don’t need to repel Babel so much.

Typing system

I’m not going to talk about such a difficult story. It is a story of adding a bit of JavaScript’s missing taste.

Since JavaScript has almost no type declaration in the first place, as a simple logic, it is absolutely impossible to know what kind of objects are passed as function’s arguments if you just look at the code of the callee side.

If you write both the caller and the callee all by yourself in a short period, you know exactly what to pass as arguments. Then, you think it’s unnecessary to declare them.

But I want you to think calmly. Are you exactly same as yourself a week ago? I can say that it is different. Even though I know roughly what I thought about on writing the code last week, the truth is that I am not sure in details.

It is not a bad idea to provide information to others including yourself in the future by writing comments in the code, but comments are not executed on runtime, and you can not validate automatically. On the other hand, if you write the type as a little memo, you can automatically verify the code and be happy.

Faction of type declaration in JavaScript

Let’s check out how to declare types in JavaScript here a bit.

What I worked on a type declaration for the first time on using JavaScript is Google Closure Compiler’s Type System.

If you write a type declaration briefly in the document comment, it validates the types in the code.

What makes this approach wonderful is that the type declaration is in the comment, so the programmer can provide the necessary information by the compiler without affecting the behavior of the source code at all.

On the other hand, there is a problem that the declaration in the comment is easy to be ignored. There is also a problem that expression flexibility is extremely low instead of being easy to understand.

ADVANCED_OPTIMIZATIONS of Google Closure Compiler has a risk that the code will not run at all, but I was really surprised because the code size gets seriously smaller.

TypeScript emerged as one of a lot of efforts to develop a new language as an advanced JavaScript.

For me, I think that TypeScript is a kind of grace from God, with the recognition that it is the latest work by Anders Hejlsberg who designed Delphi and C#.

Let’s look at the code of TypeScript a bit.

TypeScript is more similar to the my own Java I mentioned earlier than the originial Java.

TypeScript provides 2 ways to daclare types; one is to mix type annotations in the code to work and the other is to create a dedicated file for type declaration. For example, if you create a dedicated file, declare it like this.

If you have a file with the extension d.ts for type declaration, you can write the code as if there is a type in a library, even if that has no actual type declaration.

It is a crucial feature to be able to have types in post-installation of the libraries with out tyep declaration as needed in order to utilize existing assets.

The DefinitelyTyped project that was working to collect type declaration files for OSS modules into a single repository was busted due to the enormous number of declaration files.

Now the organization called types is managing them in a straightforward way where allocating one repository for one module. Nonetheless, it is not to say DefinitelyTyped is not referenced at all.

By the way, to retrieve the type declaration files from the npm repository, you can do npm install -D @types/lodash etc. It's great that you can get them by npm, not by the decicated tools.

Flow is a static analysis tool written in OCaml, and it checks the type declaration mixed in JavaScript, and it performs various validations.

Let’s see a bit of JavaScript code typed in Flow.

It looks like it is similar to TypeScript’s type annotation. But Flow has a distinctly different point from TypeScript. Flow does static analysis such as evaluating type annotation given to JavaScript, but does not create a new programming language.

It is a closer approach to Google Closure Compiler. However, unlike the time when Google Closure Compiler was created, now there is Babel, so once you have extended the syntax of the language primarily and you finish using it, it is possible to safely remove only the description specifically for Flow implementation.

Type declarations done in comments is limited in terms of expressive power. Flow got over the challenge. Nevertheless, compared with Haskell and OCaml, it does not have much rich expressiveness, even compared to Java.

It is not so difficult to understand the extent where Flow infer the type. In other words, Flow does only very simple type inference.

For Flow, there is a repository called flow-typed for sharing type declarations like TypeScript. I do not know why it’s going to do the same mistake as [Definitely Typed], but it’s managing them in a single repository.

However, this seems to reviews the PRs serverly, and the contents of the stored type definition file are strict and the absolute amount of those are small.

On retrieving a type declaration file, the command flow-typed will automatically download the type declaration files of dependent module in package.json from the flow-typed repository. For those without a type declaration, it makes a type declaration file where all types are declared as any .

Why does not it let you pull type declaration files with the npm command? I wonder it should have another command that make a miscellaneous type declaration file.

Which type system to use

There is no reason to choose Google Closure Compiler anymore.

Since TypeScript and Flow are different objectives, they are not something that can simply be evaluated in the score sheet. If you compare it in the Star table, TypeScript is a victory.

Well then, which one to use?

It’d be good to consider the support for the libraries and the frameworks you want to use.

At least if you use Angular, TypeScript is the choice and if you use React, definitely you use Flow.

There is an official TypeScript type definition file for Vue.js. However, this does not recommend the use of TypeScript, it seems that the contribution by some users was merged.

If you use normal JavaScript, it is good to use Flow, and TypeScript is a pretty good choice if you have the type definition files of the library you’d like to use. Especially VS Code apparently improves the precision of input completion if you have the type definition files.

Supplementally, Flow Language Support also has a function to enhance input completion.

Unresolved issues in the type system

Supplement the indications received from experts after the first release of this entry.

Dart

A language that makes stronger type inference than TypeScript

Dart2js can convert the code to JavaScript

Two large use case Angular2 within Google’s already exists

Large use case is achieved with Angular2Dart

Let’s share best practices with static analysis

JavaScript has many traps. The trap here is the language specification that many programmers tend to misunderstand, and the behavior of certain libraries. Because JavaScript is a truly flexible language, most of the new language specifications can be converted directly into the old language. That is why there are many traps.

Code written as results of mistakes by programmers, code not written unless misunderstanding about specifications, code that can be considered a bug in most situations, and code which satisfies the language specification but can not obtain the expected results on runtime in an application… Lint is a tool for automatically finding those codes.

If you use Lint a bit more aggressively, you can inspect anything that has nothing to do with the behavior of the code but with code readability, such as how to indent and how to name variables.

History of Lint in JavaScript

If you take a glance at Javascript ecosystem, you will find lots of Lint tools. The oldest one that I have used is JSLint. This guy isthe Lint made by legendary Douglas Crockford and is very strict. It’s an hardcore style lint tool that does not allow any indulgence. It is painful for unskilled guys because it makes us feel the author’s strong will that codes that can do strange behavior should be a strange look and he would never misled by a strange behavior of JavaScript.

By the way, reading the code of JSLint is a great resource to learn JavaScript. It’s compact and easy to read.

Lint that became evangelical for unskilled guys like me is JSHint. This is not too strict. It is incredibly easy to use because it can cut out the setting file. However, JSHint is easy to enable and disable the built-in functions, but adding a new rule is a little troublesome.

Also, to incorporate someone’s recommended rules into your project, you have to copy and paste the settings. Most people want to use someone’s recommendation, and only a part of maniacs like me like to make Lint’s rules. If that recommended set is maintained, you want to use only that final result without doing troublesome things.

That’s why ESLint is now recommended that is easy to extend and easy to create configuration files.

ESLint has the excellent plug-in system, so there are plenty of plug-ins, and you can publish the suggested rule set as an npm module.

Airbnb’s published eslint-config-airbnb is one such kind of recommended rule set.

Airbnb’s one contains a lot of things that do not fit my idea, so I did not adopt it, tho.

ESlint related modules

ESLint related modules are almost all about plug-ins.

I listed here those at least that I used and found especially useful though I think there are many other modules.

If you are an ESLint mania and know a useful plugin I do not know, please let me know.

In my project I use a testing framework called AVA. AVA will be explained later.

AVA is relatively straightforward and easy to use, but it is too simple to understand how to write the test code until you get used to it.

So, using this plugin makes it possible to get warned when you use AVA obviously incorrectly.

eslint-plugin-import finds errors on import statements.

In concrete, if you try to import a module that does not exist in the project, you will get a warning. Everyone can typo the module name.

In another example, if you pass strings other than literals to require , you get errors.

Only this one has a different role from other modules.

eslint-import-resolver-node can work with eslint-plugin-import to customize how to find import modules.

What I mean is, in my project, I store application code and test code in separate directories, src and test respectively.

In this case, in the test code side, when you do import application code, I have to write import world from '../../src/hello/world"; , and it is painful. To avoid that, by setting NODE_PATH=src when executing the test code, we do not need to write that ../../src/ part.

I use eslint-import-resolver-node to inform the omission to eslint-plugin-import about this.

The JavaScript Promise is a type of library you need to get used to. Moreover, it is hard to understand the correct usage. Speaking of Promise , JavaScript Promise's book is a very wonderful document so I recoomend to read it many times.

It is highly likely that you are using Promise wrongly until you get used to Promise . If there are JavaScript experts around you and can receive code reviews from them, it is very wonderful. But I am writing a bit of JavaScript as a hobby, I can not ask such an expert casually.

So by using this plug-in, you will get errors in the obviously wrong Promise code. You can understand how to use Promise by simply reading the rule details of this plugin, so please try setting the rules carefully.

By the way, if async/await are introduced into ES, will not you use Promise directly?

I think that async/await and Promise can coexist according to my experience of using C#'s async/await , but I don't exactly know how they are in JavsScript. At least, in my impression using async/await in AVA has effect to make test code easy to understand.

Do you care about security while writing code? I am doing security reviews using static analysis tools as a job, so I’m paying attention on it to some extent. However, I am not whenever there is a consideration on security in the head.

The amount of vulnerability that can be checked with this plug-in is not much, but it finds vulnerability that easily get mixed in.

As long as you write the code normally, you may not see any errors due to this plugin, but when you get warned by this plug-in, I want you to be cautious a little.

Although it is good to type declaration using Flow, sometimes you may make a huge mistake.

Also, since the type declaration by Flow is not ordinary JavaScript, the standard rules in ESLint are not applied at all. In other words, you need to reimplement rules for Flow, such as indentation, sticking a semicolon at the end of the line, killing trailing comma, etc.

Flow itself has its traps, and if you declare a consistent type declaration, it would be better to keep them linted.

I told the same story at Promise , but it is good to use eslint-plugin-flowtype as a training plaster jacket since Flow is a new technology. If you get used to it properly, no error will come out at all.

In my project React is used as a framework for building UI.

Since React is very commonly used, along with many best practices, undesirable coding styles have been found.

Everything defined as a rule is not always desirable for our project, but it is much easier to argue about what is being ruleized than to create that knowledge.

In fact, to get knowledge about the rules as defined in this plug-in by yourself, it will not be enough to simply use it with a small project.

The merit of using a de-facto standard framework lies in this place.

How carefully are you using the Accessibility of the system that we are making?

I feel that it is Accessibility that has a lower priority than Security which tends to be negligible.

Because it is to provide a rich UI for a better user experience, it may be good to give consideration to users with disabilities on the extension line.

However reading through WAI-ARIA 1.1 and MDN’s ARIA page from end to end is extremely hard if you are to do it.

I hope to provide the maximum value as much as I can with the minimum effort, such as referencing to HTML5 Accessibility.