JS - Tools - CL1 Flashcards

1
Q

NPM

  • installing node package manager
  • instaling required npm
  • global vs local instalation
A

npm consists of three distinct components:
- the website
- the Command Line Interface (CLI)
- the registry
Use the website to discover packages, set up profiles, and manage other aspects of your npm experience. For example, you can set up Orgs (organizations) to manage access to public or private packages.
The CLI runs from a terminal, and is how most developers interact with npm.
The registry is a large public database of JavaScript software and the meta-information surrounding it.

Use npm to . . .

  • Adapt packages of code for your apps, or incorporate packages as they are.
  • Download standalone tools you can use right away.
  • Run packages without downloading using npx.
  • Share code with any npm user, anywhere.
  • Restrict code to specific developers.
  • Create Orgs (organizations) to coordinate package maintenance, coding, and developers.
  • Form virtual teams by using Orgs.
  • Manage multiple versions of code and code dependencies.
  • Update applications easily when underlying code is updated.
  • Discover multiple ways to solve the same puzzle.
  • Find other developers who are working on similar problems and projects.

Installing node package manager
To publish and install packages to and from the public npm registry or your company’s npm Enterprise registry, you must install Node.js and the npm command line interface using either a Node version manager or a Node installer. We strongly recommend using a Node version manager to install Node.js and npm. We do not recommend using a Node installer, since the Node installation process installs npm in a directory with local permissions and can cause permissions errors when you run npm packages globally.
To see if you already have Node.js and npm installed and check the installed version, run the following commands:
node -v
npm -v

Using the Global versus the Local Mode
NPM has two main modes of operation: global and local. These two modes change target directories for storing packages and have deep implications for how Node loads modules.
The local mode is the default mode of operation in NPM. In this mode, NPM works on the local directory level, never making system-wide changes. This mode is ideal for installing the modules your application depends on without affecting other applications you might also have installed locally.
The global mode is more suited for installing modules that should always be available globally, like the ones that provide command-line utilities and that are not directly used by applications.
Always use the default local mode if you are in doubt. If module authors intend for one specific module to be installed globally, generally they will tell you so in the installation instructions.

The Global Mode
If you installed Node using the default directory, while in the global mode, NPM installs packages into /usr/local/lib/node_modules. If you type the following in the shell, NPM will search for, download, and install the latest version of the package named sax inside the directory /usr/local/lib/node_modules/sax :
npm install -g sax
If you then have the requirement for this package in any Node script:
var sax = require(‘sax’);
Node will pick up this module in this directory (unless you have it installed locally, in which case Node prefers the local version).
The local mode is the default mode, and you have to explicitly activate the global mode in NPM by using the –g flag.

The Local Mode
The local mode is the default mode of operation in NPM and the recommended dependency resolution mechanism. In this mode NPM installs everything inside the current directory — which can be your application root directory — and never touches any global settings. This way you can choose, application by application, which modules and which versions to include without polluting global module space. This means that you can have two applications that depend on different versions of the same module without them conflicting.
In this mode, NPM works with the node_modules directory under the current working directory. If you are inside /home/user/apps/my_app , NPM will use /home/user/apps/my_app/node_modules as file storage for the modules.
If you run a Node application installed in the directory /home/user/apps/my_app, Node will search this /home/user/apps/my_app/node_modules directory first (before trying the parent directories and finally searching for it inside the global one). This means that, when Node is resolving a module dependency, a module installed using the local mode will always take precedence over a module installed globally.

Installing a Module
Using the following command, you can download and install the latest version of a package:
$ npm install
For example, to download and install the latest version of the sax package, you should first change your current directory to your application root directory and then type:
$ npm install sax
This will create the node_modules directory if it doesn’t already exist and install the sax module under it.
You can also choose which version of a specific module to install by specifying it like this:
$ npm install @
You can use a specific version number in the placeholder. For instance, if you want to install version 0.2.5 of the sax module, you need to type:
$ npm install sax@0.2.5
Under you can also specify a version range. For instance, if you want to install the latest release of the 0.2 branch, you can type:
$ npm install sax@0.2.x
If you want to install the latest version before 0.3 you should type:
$ npm install sax@”<0.3”
You can get more sophisticated and combine version specifications like this:
$ npm install sax@”>=0.1.0 <0.3.1”

Uninstalling a Module
When you use the following command, NPM will try to find and uninstall the package with the specified name.
$ npm uninstall
If you want to remove a globally installed package, you should use:
$ npm uninstall -g

Updating a Module
You can also update an installed module by using the following command:
$ npm update
This command will fetch the latest version of the package and update it. If the package does not exist, it will install it.
You can also use the global switch ( -g ) to update a globally installed module like this:
$ npm update –g

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

grunt/gulp

  • advantages and disadavantages
  • run grunt or gulp
A

Grunt

Grunt is a JavaScript task runner, a tool used to automatically perform frequent tasks such as minification, compilation, unit testing, and linting. It uses a command-line interface to run custom tasks defined in a file (known as a Gruntfile). Grunt was created by Ben Alman and is written in Node.js. It is distributed via npm. As of September 2016, there were more than 5,000 plugins available in the Grunt ecosystem.
Companies that use Grunt include Adobe Systems, jQuery, Twitter, Mozilla, Bootstrap, Cloudant, Opera, WordPress, Walmart, and Microsoft.
Grunt was originally created by Ben Alman in 2012 as an efficient alternative to simplify writing and maintaining a suite of JavaScript build process tasks in one huge file. It was designed as a task-based command line build tool for JavaScript projects.
Grunt is primarily used to automate tasks that need to be performed routinely. There are thousands of plugins that can be installed and used directly to perform some commonly used tasks. One of Grunt’s most desirable features is that it is highly customizable—i.e., it allows developers to add, extend, and modify custom tasks to fit their personal needs; each task has a set of configuration options that can be set by the user. Moreover, Grunt offers the ability to define custom tasks, which can combine multiple existing tasks into a single task or add entirely new functionality.

Command-line interface
Grunt’s command-line interface (CLI) can be installed globally through npm. Executing the grunt command will load and run the version of Grunt locally installed in the current directory. Hence, we can maintain different versions of Grunt in different folders and execute each one as we wish.

Files
To use Grunt in a project, two specific files need to be created in the root directory, namely package.json and a Gruntfile.
- package.json - contains the metadata for the project including name, version, description, authors, licenses and its dependencies (Grunt plugins required by the project). All the dependencies are listed either in the dependencies or the devDependencies section.
- Gruntfile - a valid JavaScript or CoffeeScript file named “Gruntfile.js” or “Gruntfile.coffee” that contains code to configure tasks, load existing plugins and/or create custom tasks.

Tasks
Tasks are the modules that perform a specified job. They are defined in the Gruntfile.
Developers can load predefined tasks from existing Grunt plugins and/or write custom code to define their own tasks depending on their requirements. Once defined, these tasks can be run from the command line by simply executing grunt . If the defined in the Gruntfile is ‘default’ then simply executing grunt will suffice.

Plugins
Plugins are reusable code that defines a set of tasks. Each plugin internally contains a tasks directory with JavaScript files that have the same syntax as a Gruntfile. Most of the Grunt plugins are published with the keyword gruntplugin in npm and prefixed with grunt. This helps Grunt in showing all the plugins in Grunt’s plugin listing. The plugins officially supported by Grunt are prefixed with grunt-contrib and are also marked with a star symbol in the plugins listing. Some popular plugins include grunt-contrib-watch, grunt-contrib-clean, grunt-contrib-uglify, etc.
Developers can even create their own Grunt plugins by using the grunt-init plugin and publish them to npm using the npm publish command.

Advantages
The following are some of the advantages of using Grunt:
- All task runners have the following properties: consistency, effectiveness, efficiency, repeatability, etc.
- Access to many predefined plugins that can be used to work with JavaScript tasks and on static content.
- Allows users to customize tasks using predefined plugins.
- Prefers the configuration approach to coding.
- Allows users to add their own plugins and publish them to npm.

Comparison
Ant
Ant or Apache Ant is a Java-based build tool. Ant has a little over hundred built-in tasks that are better suited to projects with a Java build structure. Writing custom code in Ant requires users to write a JAR file and reference it from XML. This would add unnecessary complexities to projects that do not require Java themselves. Ant build configurations are listed in XML rather than in JSON format.
Rake
Rake allows developers to define tasks in Ruby. Rake doesn’t have the concept of plugins or predefined tasks which means all the required actions must be written and then executed. This makes the developments costly when compared to Grunt which has a large set of reusable plugins.
Gulp
Gulp.js is a relatively new JavaScript based task runner tool. It is similar to Grunt since both follow a modular-based architecture and are based on npm. Gulp tasks are defined by code rather than configuration. Gulp is faster than Grunt. Grunt uses temporary files to transfer output from one task to another whereas in Gulp files are piped between the tasks.

Getting started
Grunt and Grunt plugins are installed and managed via npm, the Node.js package manager.
npm install -g grunt-cli
The easiest way to add Grunt and gruntplugins to an existing package.json is with the command npm install –save-dev. Not only will this install locally, but it will automatically be added to the devDependencies section, using a tilde version range.
For example, this will install the latest version of Grunt in your project folder, adding it to your devDependencies:
npm install grunt –save-dev
The same can be done for gruntplugins and other node modules. As seen in the following example installing the JSHint task module:
npm install grunt-contrib-jshint –save-dev

The Gruntfile
The Gruntfile.js or Gruntfile.coffee file is a valid JavaScript or CoffeeScript file that belongs in the root directory of your project, next to the package.json file, and should be committed with your project source.
A Gruntfile is comprised of the following parts:
- The “wrapper” function
- Project and task configuration
- Loading Grunt plugins and tasks
- Custom tasks

Gulp
gulp is an open-source JavaScript toolkit created by Eric Schoffstall[3] used as a streaming build system in front-end web development.
It is a task runner built on Node.js and npm, used for automation of time-consuming and repetitive tasks involved in web development like minification, concatenation, cache busting, unit testing, linting, optimization, etc.
gulp uses a code-over-configuration approach to define its tasks and relies on its small, single-purpose plugins to carry them out. The gulp ecosystem includes more than 3500 such plugins.
gulp is a build tool in JavaScript built on node streams. These streams facilitate the connection of file operations through pipelines. gulp reads the file system and pipes the data at hand from one single-purposed plugin to another through the .pipe() operator, doing one task at a time. The original files are not affected until all the plugins are processed. It can be configured either to modify the original files or to create new ones. This grants the ability to perform complex tasks through linking its numerous plugins. The users can also write their own plugins to define their own tasks. Unlike other task runners that run tasks by configuration, gulp requires knowledge of JavaScript and coding to define its tasks. gulp is a build system which means apart from running tasks, it is also capable of copying files from one location to another, compiling, deploying, creating notifications, unit testing, linting, etc.

Need for a task runner
Task-runners like gulp and Grunt are built on Node.js rather than npm, because the basic npm scripts are inefficient when executing multiple tasks. Even though some developers prefer npm scripts because they can be simple and easy to implement, there are numerous ways where gulp and Grunt seem to have an advantage over each other and the default provided scripts. Grunt runs tasks by transforming files and saves as new ones in temporary folders and the output of one task is taken as input for another and so on until the output reaches the destination folder. This involves a lot of I/O calls and creation of many temporary files. Whereas gulp streams through the file system and does not require any of these temporary locations decreasing the number of I/O calls thus, improving performance. Grunt uses configuration files to perform tasks whereas gulp requires its build file to be coded. In Grunt, each plugin needs to be configured to match its input location to the previous plugin’s output. In gulp, the plugins are automatically pipe-lined.

Operation
The gulp tasks are run from a command-line interface (CLI) shell and require package.json and gulpfile.js (or simply gulpfile) in the project root directory. The gulpfile is where plugins are loaded and tasks are defined. First, all the necessary modules are loaded and then tasks are defined in the gulpfile. All the necessary plugins specified in the gulpfile are installed into the devDependencies. The default task runs by $gulp. Individual tasks can be defined by gulp.task and are run by gulp . Complex tasks are defined by chaining the plugins with the help of .pipe() operator.

Installing gulp
Before we delve into configuring tasks, we need to install gulp:
$ npm install gulp -g
This installs gulp globally, giving access to gulp’s CLI. We then need to install it locally to the project. cd into your project and run the following (make sure you have an existing package.json file):
$ npm install gulp –save-dev
This installs gulp locally to the project and saves it to the devDependencies in the package.json file.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

bower/jspm

  • advantages and disadavantages
  • instalation of bower
  • get needed dependencies
A
Bower
Bower is just a package manager, and nothing else. It doesn’t offer the ability to concatenate or minify code, it doesn’t support a module system like AMD: it’s sole purpose is to manage packages.

jspm
jspm is a JavaScript package manager designed to
work seamlessly with native modules in universal workflows,
while providing full compatibility with the npm ecosystem.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Karma

  • how it works
  • structure of config file
A

Karma is essentially a tool which spawns a web server that executes source code against test code for each of the browsers connected. The results of each test against each browser are examined and displayed via the command line to the developer such that they can see which browsers and tests passed or failed.
A browser can be captured either manually, by visiting the URL where the Karma server is listening (typically http://localhost:9876/), or automatically by letting Karma know which browsers to start when Karma is run (see browsers).
Karma also watches all the files, specified within the configuration file, and whenever any file changes, it triggers the test run by sending a signal to the testing server to inform all of the captured browsers to run the test code again. Each browser then loads the source files inside an IFrame, executes the tests and reports the results back to the server.
The server collects the results from all of the captured browsers and presents them to the developer.
This is only a very brief overview, as the internals of how Karma works aren’t entirely necessary when using Karma.

Outline of workflow.
Here is roughly how Karma works:
After starting up, Karma loads plugins and the configuration file, then starts its local web server which listens for connections. Any browser already waiting on websockets from the server will reconnect immediately. As part of loading the plugins, test reporters register for ‘browser’ events so they are ready for test results.
Then karma launches zero, one, or more browsers, setting their start page the Karma server URL.
When the browsers connect, Karma serves a ‘client.html’ page; when this page runs in the browser it connects back to the server via websockets.
Once the server sees the websocket connection, it instructs the client – over the websocket – to execute tests. The client page opens an iframe with a ‘context.html’ page from the server. The server generates this context.html page using the configuration. This page includes the test framework adapter, the code to be tested, and the test code.
When the browser loads this context page, the onload event handler connects the context page to the client page via postMessage. The framework adapter is in charge at this point: it runs the test, reporting errors or success by messaging through the client page.
Messages sent to the client page are forwarded through the websocket to the Karma server. The server re-dispatches these messages as ‘browser’ events. The reporters listening to ‘browser’ events get the data; they may print it, save it to files, or forward the data to another service. Since the data is sent by the test framework adapter to the reporter, adapters and reporters almost always come in pairs, like karma-jasmine and karma-jasmine-reporter. The detailed content of test-result data is of no concern to other parts of karma: only the reporter needs to know it format.
Karma has many variations and options that may cause different workflow with different configurations.

Configuration File
In order to serve you well, Karma needs to know about your project in order to test it and this is done via a configuration file. The easiest way to generate an initial configuration file is by using the karma init command.
The Karma configuration file can be written in JavaScript or CoffeeScript and is loaded as a regular Node.js module. Within the configuration file, the configuration code is put together by setting module.exports to point to a function which accepts one argument: the configuration object.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Casper.js/Nightwatch.js

  • what is
  • creating of simple tests
A

Casper.js
CasperJS is a navigation scripting & testing utility for the PhantomJS (WebKit) and SlimerJS (Gecko) headless browsers, written in Javascript.

Nightwatch.js
Nightwatch.js is an integrated, easy to use End-to-End testing solution for web applications and websites, written in Node.js. It uses the W3C WebDriver API to drive browsers in order to perform commands and assertions on DOM elements.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Chrome developers tools

  • catch all exeptions and unhandled exeptions
  • debugging of JS
  • live editing of styles
A

Chrome DevTools
Chrome DevTools is a set of web developer tools built directly into the Google Chrome browser. DevTools can help you edit pages on-the-fly and diagnose problems quickly, which ultimately helps you build better websites, faster.
- Inspect and edit on the fly any element in the DOM tree in the Elements panel.
- View and change the CSS rules applied to any selected element in the Styles pane.
- View and edit a selected element’s box model in the Computed pane.
- View any changes made to your page locally in the Sources panel.

To live-edit a DOM node, simply double-click a selected element and make changes

The DOM tree view shows the current state of the tree; it may not match the HTML that was originally loaded for different reasons. For example, you can modify the DOM tree using JavaScript; the browser engine can try to correct invalid author markup and produce an unexpected DOM.

Live-edit a style
Live-edit style property names and values in the Styles pane. All styles are editable, except the ones that are greyed out (as is the case with user agent stylesheets).
To edit a name or value, click on it, make your changes, and press Tab or Enter to save the change.
By default, your CSS modifications are not permanent, changes are lost when you reload the page. Set up persistent authoring if you want to persist your changes between page loads.

Examine and edit box model parameters
Examine and edit the current element’s box model parameters using the Computed pane. All values in the box model are editable, just click on them.
The concentric rectangles contain the top, bottom, left, right values for the current element’s padding, border, and margin properties.
For non-statically positioned elements, a position rectangle is also displayed, containing the values of the top, right, bottom, and left properties.
For position: fixed and position: absolute elements, the central field contains the actual offsetWidth × offsetHeight pixel dimensions of the selected element. All values can be modified by double-clicking them, like property values in the Styles pane. The changes are not, however, guaranteed to take effect, as this is subject to the concrete element positioning specifics.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

jslint/jshint

A

jslint
JSLint is a static code analysis tool used in software development for checking if JavaScript source code complies with coding rules. It is provided primarily as a browser-based web application accessible through the domain jslint.com, but there are also command-line adaptations. It was created in 2002 by Douglas Crockford.

jshint
JSHint is a static code analysis tool used in software development for checking if JavaScript source code complies with coding rules. JSHint was created in 2011 by Anton Kovalyov as a fork of the JSLint project (by Douglas Crockford). Anton and others felt JSLint was getting “too opinionated”, and did not allow enough customization options. The JSHint maintainers[8] publish both an online version, and a command-line version.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Webpack

  • Entry
  • Output
  • Loaders
  • Plugins
A
Webpack
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles.
Since version 4.0.0, webpack does not require a configuration file to bundle your project. Nevertheless, it is incredibly configurable to better fit your needs.

Dependency Graph
Any time one file depends on another, webpack treats this as a dependency. This allows webpack to take non-code assets, such as images or web fonts, and also provide them as dependencies for your application.
When webpack processes your application, it starts from a list of modules defined on the command line or in its config file. Starting from these entry points, webpack recursively builds a dependency graph that includes every module your application needs, then bundles all of those modules into a small number of bundles - often, just one - to be loaded by the browser.

Entry
An entry point indicates which module webpack should use to begin building out its internal dependency graph. webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).
By default its value is ./src/index.js, but you can specify a different (or multiple entry points) by setting an entry property in the webpack configuration. For example:
webpack.config.js
module.exports = {
  entry: './path/to/my/entry/file.js'
};

Output
The output property tells webpack where to emit the bundles it creates and how to name these files. It defaults to ./dist/main.js for the main output file and to the ./dist folder for any other generated file.
You can configure this part of the process by specifying an output field in your configuration:
webpack.config.js
const path = require(‘path’);
module.exports = {
entry: ‘./path/to/my/entry/file.js’,
output: {
path: path.resolve(__dirname, ‘dist’),
filename: ‘my-first-webpack.bundle.js’
}
};
In the example above, we use the output.filename and the output.path properties to tell webpack the name of our bundle and where we want it to be emitted to. In case you’re wondering about the path module being imported at the top, it is a core Node.js module that gets used to manipulate file paths.

Loaders
Out of the box, webpack only understands JavaScript and JSON files. Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.
Note that the ability to import any type of module, e.g. .css files, is a feature specific to webpack and may not be supported by other bundlers or task runners. We feel this extension of the language is warranted as it allows developers to build a more accurate dependency graph.
At a high level, loaders have two properties in your webpack configuration:
1. The test property identifies which file or files should be transformed.
2. The use property indicates which loader should be used to do the transforming.
webpack.config.js
const path = require(‘path’);
module.exports = {
output: {
filename: ‘my-first-webpack.bundle.js’
},
module: {
rules: [
{ test: /.txt$/, use: ‘raw-loader’ }
]
}
};
The configuration above has defined a rules property for a single module with two required properties: test and use. This tells webpack’s compiler the following:
“Hey webpack compiler, when you come across a path that resolves to a ‘.txt’ file inside of a require()/import statement, use the raw-loader to transform it before you add it to the bundle.”

Plugins
While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.
In order to use a plugin, you need to require() it and add it to the plugins array. Most plugins are customizable through options. Since you can use a plugin multiple times in a config for different purposes, you need to create an instance of it by calling it with the new operator.
webpack.config.js
const HtmlWebpackPlugin = require(‘html-webpack-plugin’); //installed via npm
const webpack = require(‘webpack’); //to access built-in plugins
module.exports = {
module: {
rules: [
{ test: /.txt$/, use: ‘raw-loader’ }
]
},
plugins: [
new HtmlWebpackPlugin({template: ‘./src/index.html’})
]
};

Mode
By setting the mode parameter to either development, production or none, you can enable webpack's built-in optimizations that correspond to each environment. The default value is production.
module.exports = {
  mode: 'production'
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Typescript

  • Basic Types
  • Interfaces
  • Generics
  • strictNullChecks
A

Typescript
TypeScript is an open-source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript, and adds optional static typing to the language.
TypeScript is designed for development of large applications and transcompiles to JavaScript. As TypeScript is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs. TypeScript may be used to develop JavaScript applications for both client-side and server-side (Node.js) execution.
There are multiple options available for transcompilation. Either the default TypeScript Checker can be used,[6] or the Babel compiler can be invoked to convert TypeScript to JavaScript.

Basic Types
For programs to be useful, we need to be able to work with some of the simplest units of data: numbers, strings, structures, boolean values, and the like. In TypeScript, we support much the same types as you would expect in JavaScript, with a convenient enumeration type thrown in to help things along.
1. Boolean
The most basic datatype is the simple true/false value, which JavaScript and TypeScript call a boolean value.
let isDone: boolean = false;
2. Number
As in JavaScript, all numbers in TypeScript are floating point values. These floating point numbers get the type number. In addition to hexadecimal and decimal literals, TypeScript also supports binary and octal literals introduced in ECMAScript 2015.
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
3. String
Another fundamental part of creating programs in JavaScript for webpages and servers alike is working with textual data. As in other languages, we use the type string to refer to these textual datatypes. Just like JavaScript, TypeScript also uses double quotes (“) or single quotes (‘) to surround string data.
let color: string = “blue”;
color = ‘red’;
You can also use template strings, which can span multiple lines and have embedded expressions. These strings are surrounded by the backtick/backquote () character, and embedded expressions are of the form ${ expr }. 4. Array TypeScript, like JavaScript, allows you to work with arrays of values. Array types can be written in one of two ways. In the first, you use the type of the elements followed by [] to denote an array of that element type: let list: number[] = [1, 2, 3]; The second way uses a generic array type, Array: let list: Array = [1, 2, 3]; 5. Tuple Tuple types allow you to express an array with a fixed number of elements whose types are known, but need not be the same. For example, you may want to represent a value as a pair of a string and a number: // Declare a tuple type let x: [string, number]; // Initialize it x = ["hello", 10]; // OK // Initialize it incorrectly x = [10, "hello"]; // Error 6. Enum A helpful addition to the standard set of datatypes from JavaScript is the enum. As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values. enum Color {Red, Green, Blue} let c: Color = Color.Green; By default, enums begin numbering their members starting at 0. You can change this by manually setting the value of one of its members. For example, we can start the previous example at 1 instead of 0: enum Color {Red = 1, Green, Blue} let c: Color = Color.Green; Or, even manually set all the values in the enum enum Color {Red = 1, Green = 2, Blue = 4} let c: Color = Color.Green; A handy feature of enums is that you can also go from a numeric value to the name of that value in the enum. For example, if we had the value 2 but weren’t sure what that mapped to in the Color enum above, we could look up the corresponding name: enum Color {Red = 1, Green, Blue} let colorName: string = Color[2]; console.log(colorName); // Displays 'Green' as its value is 2 above 7. Any We may need to describe the type of variables that we do not know when we are writing an application. These values may come from dynamic content, e.g. from the user or a 3rd party library. In these cases, we want to opt-out of type checking and let the values pass through compile-time checks. To do so, we label these with the any type: let notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // okay, definitely a boolean The any type is a powerful way to work with existing JavaScript, allowing you to gradually opt-in and opt-out of type checking during compilation. You might expect Object to play a similar role, as it does in other languages. However, variables of type Object only allow you to assign any value to them. You can’t call arbitrary methods on them, even ones that actually exist: let notSure: any = 4; notSure.ifItExists(); // okay, ifItExists might exist at runtime notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check) let prettySure: Object = 4; prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'. The any type is also handy if you know some part of the type, but perhaps not all of it. For example, you may have an array but the array has a mix of different types: let list: any[] = [1, true, "free"]; list[1] = 100; 8. Void void is a little like the opposite of any: the absence of having any type at all. You may commonly see this as the return type of functions that do not return a value: function warnUser(): void { console.log("This is my warning message"); } Declaring variables of type void is not useful because you can only assign null (only if --strictNullChecks is not specified, see next section) or undefined to them: let unusable: void = undefined; unusable = null; // OK if –strictNullChecks` is not given
9. Null and Undefined
In TypeScript, both undefined and null actually have their own types named undefined and null respectively. Much like void, they’re not extremely useful on their own:
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;
By default null and undefined are subtypes of all other types. That means you can assign null and undefined to something like number.
However, when using the –strictNullChecks flag, null and undefined are only assignable to any and their respective types (the one exception being that undefined is also assignable to void). This helps avoid many common errors. In cases where you want to pass in either a string or null or undefined, you can use the union type string | null | undefined.
Union types are an advanced topic that we’ll cover in a later chapter.
As a note: we encourage the use of –strictNullChecks when possible, but for the purposes of this handbook, we will assume it is turned off.
10. Never
The never type represents the type of values that never occur. For instance, never is the return type for a function expression or an arrow function expression that always throws an exception or one that never returns; Variables also acquire the type never when narrowed by any type guards that can never be true.
The never type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to, never (except never itself). Even any isn’t assignable to never.
11. Object
object is a type that represents the non-primitive type, i.e. anything that is not number, string, boolean, symbol, null, or undefined.
With object type, APIs like Object.create can be better represented. For example:
declare function create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK
create(42); // Error
create(“string”); // Error
create(false); // Error
create(undefined); // Error

Type assertions
Sometimes you’ll end up in a situation where you’ll know more about a value than TypeScript does. Usually this will happen when you know the type of some entity could be more specific than its current type.
Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler. TypeScript assumes that you, the programmer, have performed any special checks that you need.
Type assertions have two forms. One is the “angle-bracket” syntax:
let someValue: any = “this is a string”;
let strLength: number = (someValue).length;
And the other is the as-syntax:
let someValue: any = “this is a string”;
let strLength: number = (someValue as string).length;
The two samples are equivalent. Using one over the other is mostly a choice of preference; however, when using TypeScript with JSX, only as-style assertions are allowed.

Interfaces
One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.
Not all properties of an interface may be required. Some exist under certain conditions or may not be there at all. These optional properties are popular when creating patterns like “option bags” where you pass an object to a function that only has a couple of properties filled in.
Here’s an example of this pattern:
interface SquareConfig {
    color?: string;
    width?: number;
}
Some properties should only be modifiable when an object is first created. You can specify this by putting readonly before the name of the property:
interface Point {
    readonly x: number;
    readonly y: number;
}
Interfaces are capable of describing the wide range of shapes that JavaScript objects can take. In addition to describing an object with properties, interfaces are also capable of describing function types.
To describe a function type with an interface, we give the interface a call signature. This is like a function declaration with only the parameter list and return type given. Each parameter in the parameter list requires both name and type.
interface SearchFunc {
    (source: string, subString: string): boolean;
}
Similarly to how we can use interfaces to describe function types, we can also describe types that we can “index into” like a[10], or ageMap["daniel"]. Indexable types have an index signature that describes the types we can use to index into the object, along with the corresponding return types when indexing. Let’s take an example:
interface StringArray {
    [index: number]: string;
}
Like classes, interfaces can extend each other. This allows you to copy the members of one interface into another, which gives you more flexibility in how you separate your interfaces into reusable components.
interface Shape {
    color: string;
}
interface Square extends Shape {
    sideLength: number;
}
An interface can extend multiple interfaces, creating a combination of all of the interfaces.
interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}
When an interface type extends a class type it inherits the members of the class but not their implementations. It is as if the interface had declared all of the members of the class without providing an implementation. Interfaces inherit even the private and protected members of a base class. This means that when you create an interface that extends a class with private or protected members, that interface type can only be implemented by that class or a subclass of it.
This is useful when you have a large inheritance hierarchy, but want to specify that your code works with only subclasses that have certain properties. The subclasses don’t have to be related besides inheriting from the base class. For example:
class Control {
    private state: any;
}
interface SelectableControl extends Control {
    select(): void;
}
class Button extends Control implements SelectableControl {
    select() { }
}
class TextBox extends Control {
    select() { }
}
// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    private state: any;
    select() { }
}
class Location {}
Generics
A major part of software engineering is building components that not only have well-defined and consistent APIs, but are also reusable. Components that are capable of working on the data of today as well as the data of tomorrow will give you the most flexible capabilities for building up large software systems.
In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.
To start off, let’s do the “hello world” of generics: the identity function. The identity function is a function that will return back whatever is passed in. You can think of this in a similar way to the echo command.
Without generics, we would either have to give the identity function a specific type:
function identity(arg: number): number {
    return arg;
}
Or, we could describe the identity function using the any type:
function identity(arg: any): any {
    return arg;
}
While using any is certainly generic in that it will cause the function to accept any and all types for the type of arg, we actually are losing the information about what that type was when the function returns. If we passed in a number, the only information we have is that any type could be returned.
Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned. Here, we will use a type variable, a special kind of variable that works on types rather than values.
function identity(arg: T): T {
    return arg;
}
We’ve now added a type variable T to the identity function. This T allows us to capture the type the user provides (e.g. number), so that we can use that information later. Here, we use T again as the return type. On inspection, we can now see the same type is used for the argument and the return type. This allows us to traffic that type information in one side of the function and out the other.
We say that this version of the identity function is generic, as it works over a range of types. Unlike using any, it’s also just as precise (ie, it doesn’t lose any information) as the first identity function that used numbers for the argument and return type.
Once we’ve written the generic identity function, we can call it in one of two ways. The first way is to pass all of the arguments, including the type argument, to the function:
let output = identity("myString");  // type of output will be 'string'
Here we explicitly set T to be string as one of the arguments to the function call, denoted using the <> around the arguments rather than ().
The second way is also perhaps the most common. Here we use type argument inference – that is, we want the compiler to set the value of T for us automatically based on the type of the argument we pass in:
let output = identity("myString");  // type of output will be 'string'
Notice that we didn’t have to explicitly pass the type in the angle brackets (<>); the compiler just looked at the value "myString", and set T to its type. While type argument inference can be a helpful tool to keep code shorter and more readable, you may need to explicitly pass in the type arguments as we did in the previous example when the compiler fails to infer the type, as may happen in more complex examples.

Strict null checks
TypeScript has two special types, Null and Undefined, that have the values null and undefined respectively. Previously it was not possible to explicitly name these types, but null and undefined may now be used as type names regardless of type checking mode.
The type checker previously considered null and undefined assignable to anything. Effectively, null and undefined were valid values of every type and it wasn’t possible to specifically exclude them (and therefore not possible to detect erroneous use of them).
–strictNullChecks switches to a new strict null checking mode.
In strict null checking mode, the null and undefined values are not in the domain of every type and are only assignable to themselves and any (the one exception being that undefined is also assignable to void). So, whereas T and T | undefined are considered synonymous in regular type checking mode (because undefined is considered a subtype of any T), they are different types in strict type checking mode, and only T | undefined permits undefined values. The same is true for the relationship of T to T | null.
In strict null checking mode the compiler requires every reference to a local variable of a type that doesn’t include undefined to be preceded by an assignment to that variable in every possible preceding code path.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Babel

  • Main purpose
  • .babelrc and its options
  • CLI
  • presets and plugins
A

Babel
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments. Here are the main things Babel can do for you:
- Transform syntax
- Polyfill features that are missing in your target environment (through @babel/polyfill)
- Source code transformations (codemods)

.babelrc
Babel loads .babelrc (and .babelrc.js / package.json#babel) files by searching up the directory structure starting from the “filename” being compiled (limited by the caveats below). This can be powerful because it allows you to create independent configurations for subsections of a package. File-relative configurations are also merged over top of project-wide config values, making them potentially useful for specific overrides, though that can also be accomplished through “overrides”.
There are a few edge cases to consider when using a file-relative config:
Searching will stop once a directory containing a package.json is found, so a relative config only applies within a single package.
The “filename” being compiled must be inside of “babelrcRoots” packages, or else searching will be skipped entirely.
These caveats mean that:
.babelrc files only apply to files within their own package
.babelrc files in packages that aren’t Babel’s ‘root’ are ignored unless you opt in with “babelrcRoots”.
See the monorepo documentation for more discussion on how to configure monorepos that have many packages.
File-relative configs can also be disabled by setting “babelrc” to false.

CLI
Babel comes with a built-in CLI which can be used to compile files from the command line.
In addition, various entry point scripts live in the top-level package at @babel/cli/bin. There is a shell-executable utility script, babel-external-helpers.js, and the main Babel cli script, babel.js.
Install
While you can install Babel CLI globally on your machine, it’s much better to install it locally project by project.
There are two primary reasons for this.
1. Different projects on the same machine can depend on different versions of Babel allowing you to update them individually.
2. Not having an implicit dependency on the environment you are working in makes your project far more portable and easier to setup.
We can install Babel CLI locally by running:
npm install –save-dev @babel/core @babel/cli

Plugins
Babel is a compiler (source code => output code). Like many other compilers it runs in 3 stages: parsing, transforming, and printing.
Now, out of the box Babel doesn’t do anything. It basically acts like const babel = code => code; by parsing the code and then generating the same code back out again. You will need to add plugins for Babel to do anything.
Instead of individual plugins, you can also enable a set of plugins in a preset.

Presets
Don’t want to assemble your own set of plugins? No problem! Presets can act as an array of Babel plugins or even a sharable options config.
Official Presets
We’ve assembled some for common environments:
@babel/preset-env
@babel/preset-flow
@babel/preset-react
@babel/preset-typescript
Many other community maintained presets are available on npm!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly