Thursday, 18 April 2019

Http Client in Node.js

Making HTTP(S) calls from the application is very common requirement. Node.JS world offers lots of options about how to implement it, or better to say - which package to use.

Native solution


Node.JS comes with native http and https packages.


Request package


It does not support Promises so if we need to wrap it into a Promise ourselves...something like:

/**
 * Function which fetches http response asynchronously.
 * It is implemented as a simple Promise wrapper around request API.
 * @param url Request URL.
 */
function fetchData(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
        if (!url) {
            reject(ErrorFactory.createInvalidArgumentError("url"));
        }

        request(url, (error: any, response: request.Response, body: any) => {
            if (error) {
                reject(error);
            } else {
                if (response) {
                    console.log("statusCode: ", response.statusCode);
                    if (body) {
                        resolve(body);
                    } else {
                        reject(ErrorFactory.createFalsyObjectError("body"));
                    }
                } else {
                    reject(ErrorFactory.createFalsyObjectError("response"));
                }
            }
        });
    });
}


Request package with native promises



node-fetch package


window.fetch API for Node.js 

Axios package


Promise based HTTP client for the browser and node.js

Some References



Conclusion


I've been looking solutions which support Promises. node-fetch seems to be traditional approach and Axios seems to be very popular among developers now.

Friday, 12 April 2019

Introduction to JavaScript

Here are some notes & links I used on my quest of learning JavaScript. You won't find anything spectacular here :)

JS in general


http://blog.thefirehoseproject.com/posts/exactly-makes-javascript-weird-programming-language/
https://www.crockford.com/javascript/javascript.html

Coding convention

http://www.crockford.com/javascript/code.html

When to use and when not semicolons?

https://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascript
https://hackernoon.com/an-open-letter-to-javascript-leaders-regarding-no-semicolons-82cec422d67d
https://stackoverflow.com/questions/8528557/why-doesnt-a-javascript-return-statement-work-when-the-return-value-is-on-a-new

What are the rules for JavaScript's automatic semicolon insertion (ASI)?

https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi

Memory Management


Memory management model

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

Causes of memory leaks

https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/
https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec

How to free up memory?

https://stackoverflow.com/questions/8467350/how-to-free-up-the-memory-in-javascript

JS in Front-End


What is DOM?

https://www.quora.com/What-is-meant-by-Document-Object-Model-and-how-does-it-works

Web page lifecycle

https://javascript.info/onload-ondomcontentloaded

How to check which events on the page/window have handlers attached?

https://github.com/deanoemcke/thegreatsuspender/issues/272
When does DOMContentLoaded fire? What does its handler usually do?

https://www.quora.com/What-does-it-mean-exactly-that-the-DOM-Document-Object-Model-is-ready
https://api.jquery.com/ready/
https://eager.io/blog/how-to-decide-when-your-code-should-run/

What is the vanilla JS equivalent of '$(document).ready()'?

https://stackoverflow.com/questions/2304941/what-is-the-non-jquery-equivalent-of-document-ready

When does window.onload fire? What does its handler usually do?

https://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery
https://api.jquery.com/ready/

How to prevent web page from closing?

https://www.maki-chan.de/preventclose.htm

window.onbeforeunload = function() { return "Would you really like to close your browser?"; }

Threading system


Is JS single or multi-threaded language and why?
How does event system work if it’s single-threaded?

Variables

Assigning and passing to functions by value and by reference
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Error

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error


How to rethrow the error?


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties


http://zduck.com/2013/non-enumerable-properties-in-javascript/


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Data types


JavaScript is a weakly typed language, not un-typed language. Primitive types are passed into functions by value, while non-primitives are passed by reference. The typeof operator in JavaScript explicitly informs you of what the type of a variable is (hint is in the name of the operator). There are 5 primitive types (string, number, boolean, undefined, symbol) and two non-primitives (object, function) that are available in user land. [source]
Which 2 types of data types are defined by the latest ECMAScript?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

List all primitives.


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

null vs unsigned


https://codeburst.io/javascript-null-vs-undefined-20f955215a2

List all 6 falsy values in JS


https://codeburst.io/javascript-null-vs-undefined-20f955215a2

Object


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object

What is an “object” in computer science?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

Object.keys()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


Object.values()

What is the difference between Object.values() and for..in?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

String


template string


https://stackoverflow.com/questions/19105009/how-to-insert-variables-in-javascript-strings

How to make template string substitution in runtime?

https://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused
split()
https://medium.com/@jeanpan/javascript-splice-slice-split-745b1c1c05d2
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

Array


How to find if array contains some element which matches some criteria?
https://www.w3schools.com/jsref/jsref_find.asp

jQuery - What happens if some operation is executed on the empty array?
e.g. what happens if find returns empty array in:
$footer_ip.find(".user--ip, .virtual--ip").addClass("animated fadeInUp");
https://stackoverflow.com/questions/5705067/what-happens-when-a-jquery-selector-wasnt-found

How to create an array?
https://stackoverflow.com/questions/1629539/use-of-square-brackets-around-javascript-variables

How to redefine Array.toString function?
https://stackoverflow.com/questions/1629539/use-of-square-brackets-around-javascript-variables

Hoisting


https://www.sitepoint.com/back-to-basics-javascript-hoisting/

Expressions and operators


Loose equality operator


What does it do?
https://codeburst.io/javascript-null-vs-undefined-20f955215a2

Double Equals vs. Triple Equals


https://codeburst.io/javascript-double-equals-vs-triple-equals-61d4ce5a121a
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

Destructuring assignment


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Spread syntax

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://zendev.com/2018/05/09/understanding-spread-operator-in-javascript.html
https://stackoverflow.com/questions/11704267/in-javascript-how-to-conditionally-add-a-member-to-an-object

Short-circuiting

https://codeburst.io/javascript-what-is-short-circuit-evaluation-ff22b2f5608c


Functions

Built-in (global) functions


parseInt - what is the purpose of radix argument?
https://www.w3schools.com/jsref/jsref_parseint.asp
https://davidwalsh.name/parseint-radix
https://stackoverflow.com/questions/6611824/why-do-we-need-to-use-radix
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
https://eloquentjavascript.net/03_functions.html

How to verify that parsing some string as integer was successful?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt

Function.prototype.bind()


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Arrow functions


http://2ality.com/2012/04/arrow-functions.html

Self-Executing Anonymous Functions

http://markdalgleish.com/2011/03/self-executing-anonymous-functions/

Events


Is addEventListener (using listeners) preferred over attaching a handler?

https://www.reddit.com/r/learnjavascript/comments/6erpv2/whats_the_difference_between_using_an_event/
https://teamtreehouse.com/community/addeventlistener-vs-things-like-onclick-onchange-etc-pure-javascript

What is the correct attaching a handler (if go down this route)?
How to avoid wrong double handler execution?
https://stackoverflow.com/questions/7794301/window-onunload-is-not-working-properly-in-chrome-browser-can-any-one-help-me
Describe event phases
(capturing, bubbling...)
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation

jQuery - Why returning false from (click) event handler?
https://stackoverflow.com/questions/11184276/return-false-from-jquery-click-event

Event.stopPropagation()
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

Promises


http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects
https://italonascimento.github.io/applying-a-timeout-to-your-promises/
https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#list-of-active-timers
https://stackoverflow.com/questions/31324110/why-does-the-promise-constructor-require-a-function-that-calls-resolve-when-co
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
https://javascript.info/promise-chaining
JavaScript: async/await with forEach()

Should a Promise.reject message be wrapped in Error?
https://stackoverflow.com/questions/26020578/should-a-promise-reject-message-be-wrapped-in-error
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject#Using_the_static_Promise.reject_method
https://stackoverflow.com/questions/26711243/promise-resolve-vs-new-promiseresolve

resolve & reject

`resolve` and `reject` functions inside a Promise's executor

async-await

https://javascript.info/async-await

http://2ality.com/2016/10/async-function-tips.html

(Especially pay attention to point #3 - Returned Promises are not wrapped - which explains when and why await can be omitted)

JavaScript loops - how to handle async/await
JavaScript: async/await with forEach()


Web APIs


WindowOrWorkerGlobalScope

setTimeout()

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

How to set text in a <span> element?

https://stackoverflow.com/questions/1358810/how-do-i-change-the-text-of-a-span-element-in-javascript#

querySelector vs querySelectorAll

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
https://stackoverflow.com/questions/14377590/queryselector-and-queryselectorall-vs-getelementsbyclassname-and-getelementbyid

When to use (set) innerHTML and when innerText?
tbd...

Misc How Tos


How to declare a constant data member in a class?
https://stackoverflow.com/questions/32647215/declaring-static-constants-in-es6-classes

Best Practices


https://www.w3schools.com/js/js_best_practices.asp

Check that there is no unnecessary console.log which goes into production.
Check that there are no unused variables.
Check return values of functions (is it null, undefined, empty array, error code etc...)

Make sure of the time order of events and functions...e.g.

document.addEventListener("DOMContentLoaded", function() {..xxx...});

If xxx is never executed but you can see that document has event handler for DOMContentLoaded event that means that the document.addEventListener("DOMContentLoaded" code was executed too late, after DOMContentLoaded event has already been fired!

var btn = document.querySelectorAll("a.btn")[0];

Use querySelector.

I prefer:

var btn = document.querySelector("a.btn");
btn.addEventListener('click', function(e) {
   const url = "secure://extensions/?id=dmfdacibleoapmpfdgonigdfinmekhgp";
   chrome.tabs.create({ url: url });
});

to:

var btn = document.querySelector("a.btn");
if (btn !== null) {
   btn.addEventListener('click', function(e) {
      const url = "secure://extensions/?id=dmfdacibleoapmpfdgonigdfinmekhgp";
      chrome.tabs.create({ url: url });
   });
} else {
   console.log(“WARNING: a.btn element not found.”);
}

as console.log message would probably be unnoticed in the log while exception thrown in case btn is null would be marked in red in console log.

use _xxx for private member variables

use no special naming for global variables because try to avoid globals outside of application constants

Consts write as MY_CONST.

This function has a lot of side effects on the DOM and global multimap. Not necessarily a problem, although the function name doesn't communicate this. A nicer way may be restructure the app to have a function that returns a state object and then hands this off to a function which generates/mutates the DOM. It's a more "functional" way of doing it anyway! Personal preference.

when you say "state object", do you mean data (e.g. optimalGateway and multimap) in this case?

I mean an object representing all data within the application. Granted, this is quite a Redux/React way of thinking and is harder to implement with a bunch of jquery, so it may not be appropriate. Still, if I'm calling a function called loadDataFromBackgroundPage at the top level with no return value, it is very unclear that is going to have side effects on the DOM. I would expect it to have a return value of that data, and no side effects. Then that data could be handed off to another function to handle the rendering.

$() equivalent to $(document).ready()

$(handler) is now preferred to $(document).ready(handler) (https://api.jquery.com/ready/)

I have two similar handlers for $(document).click in this code so I'm going to merge them.

Function name capitalisation consistency.

selectedGatewayId = vpnExtensionEngine.getGateways().find(g => g.city.name + ", " + g.country.name === selectedLocation).id;

If find returns undefined, we'll get an error here. Might be worth adding a check for this or catching the error.

All parseInt calls should specify the base. e.g. parseInt(unixTimestampString, 10)

(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt confirms this)

Another DOM ready handler. Can we condense these in to one?

var url = "https://extension.avastbrowser.com/vpn/about/";

Move to const?

replace var with let wherever applicable.

Instead of looping infinitely and throwing, can we adjust this condition?

That's certainly better approach as exception is used here to control the flow of execution (and not to signal exceptional behaviour).

use setTimeout vs setInterval and clearing it immediately in the callback
Callback has to be executed only once, after timeout so it makes more sense to use setTimeout

const serverApiVersionMajor = lightVpnControllerApiVersion.split(".")[0];
const serverApiVersionMinor = lightVpnControllerApiVersion.split(".")[1];

Array destructuring supported in Chrome 49+, so could rewrite these two lines as:

const [serverApiVersionMajor, serverApiVersionMinor] = lightVpnControllerApiVersion.split(".")

Arrow functions are used elsewhere, so could use one here as well for compactness. Personal preference. Also, you wouldn't need the .bind(this) as the arrow function doesn't create a closure.

Chrome 42+ supports the fetch API. More compact and returns a promise, so don't need to wrap it like this. https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

General tips:
https://news.ycombinator.com/item?id=17466391

Stack Overflow:
https://stackoverflow.com/questions/tagged/javascript


Packages


https://socket.io/
http://tesseract.projectnaptha.com/

Cool Tips and Tricks


How to print the name of the JS file currently loaded in html?

console.log('Loading script: ' + document.currentScript.src);

https://stackoverflow.com/questions/22095529/hiding-everything-until-the-page-has-finished-loading?noredirect=1&lq=1
https://en.wikipedia.org/wiki/Flash_of_unstyled_content
https://en.wikipedia.org/wiki/Screen_reader
https://stackoverflow.com/questions/2690865/visibility-attribute-question

How to add a line break to the string in messages.json?

https://phraseapp.com/docs/guides/formats/chrome-json/
https://github.com/angular-translate/angular-translate/issues/595
https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices
Where should I put <script> tags in HTML markup?
Remove Render-Blocking JavaScript
JavaScript Where To

String literals:

console.log(‘Hello, world!’)

or

console.log("Hello, world!")

What is lexical scope?
What is "this"?
What is Lexical Scope Anyway?
How do I write a named arrow function in ES2015?

Why is the content of some js files wrapped inside a function which is wrapped inside anonymous self-executed function?

(function () {...})();

What is the purpose of wrapping whole Javascript files in anonymous functions like “(function(){ … })()”?
Self-Executing Anonymous Functions
Immediately Invoked Function Expression (IIFE)
What does “use strict” do in JavaScript, and what is the reasoning behind it?
Should I 'use strict' for every single javascript function I write?
Not recommended to use “use strict” in ES6?
Strict Mode
What is this Javascript “require”?
What is require?
Requiring modules in Node.js: Everything you need to know
Commonly accepted best practices around code organization in JavaScript
ECMA-262, 9th edition, June 2018


What is the difference between String.slice and String.substring?

Create a JavaScript array containing 1…N
Tasks, microtasks, queues and schedules
https://codeburst.io/javascript-quickie-dot-notation-vs-bracket-notation-333641c0f781
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

Wednesday, 10 April 2019

Introduction to RegEx

RegEx is used often when working with strings, paths, configurations etc...so here is a little breakdown of commonly used RegEx expressions. I will be adding examples I come across in my daily work and down below I'll be adding explanations on how to interpret them.

RegEx examples:


'/.*?\\.(test|spec)\\.js$'


RegEx Expressions & Interpretation:


.
Dot matches any single character except the newline character, by default.
If s flag ("dotAll") is true, it also matches newline characters.

*
Asterisk matches the preceding expression 0 or more times.

.*
Matches any character greedily - as many characters as possible.

Example:
1.*1 in 101000001 will match 101000001

?
Matches the preceding expression 0 or 1 time.
If used immediately after any of the quantifiers *, +, ?, or {}, makes the quantifier non-greedy (matching the fewest possible characters), as opposed to the default, which is greedy (matching as many characters as possible).

.*?
Matches any character in non-greedy mode - as little as enough to match the pattern.

Example:
1.*1 in 101000001 will match 101

What is the difference between .*? and .* regular expressions?
(this answer also contains nice explanation of backtracking and how non-greedy expression can return multiple matches within a string)

\
A backslash that precedes a non-special character indicates that the next character is special and is not to be interpreted literally.
A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally (this is called escaping).

\\
The first backslash escapes the one after it, so the expression searches for a single literal backslash.

TBC...


References:


Regular Expressions (MDN)

Tuesday, 9 April 2019

Introduction to Node.js

First program: Hello, world!


Let's write our first Node.js program which outputs a string onto the terminal:

helloworld.js:

console.log(‘Hello, world!’)

Output:

>node helloworld.js
Hello, world!

Let's now see how Node handles erroneous code:

helloworld.js:

console.log(Hello, world!)

Output:

C:\wherever\HelloWorld\helloworld.js:1

(function (exports, require, module, __filename, __dirname) { console.log(Hello, world!)
                                                                                                                        ^^^^^
SyntaxError: missing ) after argument list
   at createScript (vm.js:56:10)
   at Object.runInThisContext (vm.js:97:10)
   at Module._compile (module.js:542:28)
   at Object.Module._extensions..js (module.js:579:10)
   at Module.load (module.js:487:32)
   at tryModuleLoad (module.js:446:12)
   at Function.Module._load (module.js:438:3)
   at Module.runMain (module.js:604:10)
   at run (bootstrap_node.js:383:7)
   at startup (bootstrap_node.js:149:9)

Introducing dependencies


There are many Node packages around and the chances are that your Node application will use (depend on) some of them. To manage these dependencies we'll use Node Package Manager (npm). All dependencies will be listed in a file called package.json which is located at project's root directory. This file will also contain some other information about the application and so it will be a kind of an application manifest. To create it (which is usually one of the first things to do when setting up a Node project), we call npm init. For example:

>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (rollup-js-demo)
version: (1.0.0)
description: Application which demoes Rollup.JS basic features.
entry point: (index.js) main.js
test command: echo \"Error: no test specified\" && exit 1
git repository: (https://github.com/BojanKomazec/rollup-js-demo.git)
keywords: rollup.js, demo
author: Bojan Komazec
license: (ISC)
About to write to C:\wherever\rollup-js-demo\package.json:

{
  "name": "rollup-js-demo",
  "version": "1.0.0",
  "description": "Application which demoes Rollup.JS basic features.",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/BojanKomazec/rollup-js-demo.git"
  },
  "keywords": [
    "rollup.js",
    "demo"
  ],
  "author": "Bojan Komazec",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/BojanKomazec/rollup-js-demo/issues"
  },
  "homepage": "https://github.com/BojanKomazec/rollup-js-demo#readme"
}

Is this OK? (yes)

Running test command indeed echoes message specified:

>npm test

> rollup-js-demo@1.0.0 test C:\wherever\rollup-js-demo
> echo "Error: no test specified" && exit 1

"Error: no test specified"
npm ERR! Test failed.  See above for more details.

What is the test command while creating package.json?
How to properly use “keywords” property in package.json?

If we want to execute npm init without prompting us to customize configutation, we can execute:

> npm init --yes

or shorter:

> npm init -y

Here is the full list of npm init options:

$ npm init --help

npm init [--force|-f|--yes|-y|--scope]
npm init <@scope> (same as `npx <@scope>/create`)
npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)

aliases: create, innit

Installing dependencies


Dependencies (Node packages) are installed with npm install command:

$ npm install --help

npm install (with no args, in package dir)
npm install [<@scope>/]<pkg>
npm install [<@scope>/]<pkg>@<tag>
npm install [<@scope>/]<pkg>@<version>
npm install [<@scope>/]<pkg>@<version range>
npm install <folder>
npm install <tarball file>
npm install <tarball url>
npm install <git:// url>
npm install <github username>/<github project>

aliases: i, isntall, add
common options: [--save-prod|--save-dev|--save-optional] [--save-exact] [--no-save]

To see detailed help use:

$ npm help install


npm install
- reads list of dependencies from packages.json, creates a local node_modules directory (if not created) and installs there all dependencies (and dependencies of dependencies).
- this command is usually used upon cloning the app's repository

npm install package_name
- Installs package_name locally
- new package appears within dependencies property in packages.json
- If not created, it creates a local node_modules directory and installs there specified package (and its dependencies)
- As node_modules directory contains binaries, it shall be added to local .gitignore file
- this command is usually used during development, when we want to add a new dependency

npm install -g 
- installs dependency globally.

"I have a personal philosophy of not installing npm modules as global unless absolutely needed." [link]

npm install --save-dev
- installs dependency locally and as a development dependency (within "devDependencies" property in packages.json; otherwise it would be in "dependencies"). If --production option is used then installing all development dependencies is omitted.

In the next example we want to install unit testing framework which should only be a development dependency of our application:

$ npm install --save-dev jest

dependencies or devDependencies?

If you install some package as dev dependency and then want to move it to become runtime dependency (to move a module from devDependencies to dependencies), use this:

$ npm install <module_name> --save-prod

Move a module from devDependencies to dependencies in npm package.json

To move a module from dependencies to devDependencies:

$ npm install <module_name> --save-dev

or shorter:

$ npm i <module_name> -D




Misc


Should I add node_modules under version control?
No
http://blog.gvm-it.eu/post/20404719601/getting-started-with-nodejs-on-windows
In Node.js, how do I “include” functions from my other files?
https://nodejs.org/api/esm.html

How to edit .npmrc on OSX?

$ cat ~/.npmrc
registry=http://some.domain.com:5678
$ vi ~/.npmrc <-- add ; at the beginning of the line to comment it
$ cat ~/.npmrc
;registry=http://some.domain.com:5678

How to update node on OSX?

$ sudo npm install -g n
Password:
/usr/local/bin/n -> /usr/local/lib/node_modules/n/bin/n
/usr/local/lib
└── n@2.1.12 
$ sudo n latest

     install : node-v10.11.0
       mkdir : /usr/local/n/versions/node/10.11.0
       fetch : https://nodejs.org/dist/v10.11.0/node-v10.11.0-darwin-x64.tar.gz
######################################################################################################################################################### 100.0%
   installed : v10.11.0


API

path.join [Node.js path module].
node how to create a directory if doesn't exist?

Asynchronous programming

Node.js Async Function Best Practices
How to keep a node.js script alive while promises are being resolved?
Node exits without error and doesn't await promise (Event callback)
Promise prevent node process from exiting
How does a node.js process know when to stop?
Promise keep node process from exit
How can I use async/await at the top level?


Node.js Project Structure

Entry point (main file) is usually named index.js.
Node Hero - Node.js Project Structure Tutorial

Modules


require


Requiring modules in Node.js: Everything you need to know

The module.exports object in every module is what the require function returns when we require that module. 

You Can Use require() To Load JSON (JavaScript Object Notation) Files In Node.js

var config = require("./config")

If we omit the file extension and Node.js will look for a .js file first and then, if not found, look for a .json file.

Normally, when referencing a file with require() a relative path is used. This path must reflect the position of the current file within your site's directory structure. 
[Absolute paths & require()]

Node require absolute path
How to make node.js require absolute? (instead of relative)
Conditional require in express?

require vs import


From difference between require and import ? 

The main difference between require and import is that import is always run at the very beginning of the file (if you look at Babel's output, they get hoisted to the top), and can't be run conditionally. This means that you can guarantee all the imports have completed before any of your code runs. Whereas require can be used inline, conditionally, etc.

imports get sorted to the top of the file, and requires stay where they were put. So the run-order only changes with import.

From: Webpack: Import vs Require, and why
In order to take advantage of tree shaking in your application, you need to keep a few things in mind.
First, make sure you use ES2015 import and export statements in your code wherever possible.

From: An Update on ES6 Modules in Node.js
It’s important to keep in mind that all import and export statements are resolved to their targets before any code is actually evaluated. It is also important to note that the ES6 specification allows this resolution step to occur asynchronously. In Node.js terms, this means loading the contents of the script, resolution of the module imports and exports, and evaluation of the module code would occur over multiple turns of the event loop.

Application Configuration

Configuration Files 

How to store Node.js deployment settings/configuration files?
Node.js Best Practices — Smarter Ways to Manage Config Files and Variables

Environment Variables

How to set Environment variables from within package.json [Node.js]
Working with Environment Variables in Node.js
Node, the difference between development and production

Deployment



Best practice for nodejs deployment - Directly moving node_modules to server or run npm install command

References & Further Reading


node how to create a directory if doesn't exist?
Check synchronously if file/directory exists in Node.js
Writing files in Node.js
How to append to a file in Node?
Writing JSON object to a JSON file with fs.writeFileSync
How to get file size in Node.js
Difference between a module and a package in Node?
Create an empty file in Node.js?
What is the purpose of Node.js module.exports and how do you use it?
In Node.js, how do I “include” functions from my other files?
How to exit in Node.js
Node.js Development Tips



Monday, 8 April 2019

Node + TypeScript + Rollup + Jest

To install Jest:

$ npm install jest --save-dev

To create a basic config file:

$ npx jest --init

This file can also be created via ts-jest:

$ npx ts-jest config:init

This creates jest.config.js file with the following content:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

If jest.config.js already exists, the previous command will fail with this error message:

ts-jest[cli] (FATAL) Configuration file jest.config.js already exists.


To see the list of all Jest options:

$ npx jest --help
Usage: jest [--config=<pathToConfigFile>] [TestPathPattern]

Options:
  --help, -h                    Show help                              [boolean]
  --version, -v                 Print the version and exit             [boolean]
  --all                         The opposite of `onlyChanged`. If `onlyChanged`
                                is set by default, running jest with `--all`
                                will force Jest to run all tests instead of
                                running only tests related to changed files.
  --automock                    Automock all files by default.         [boolean]
  --bail, -b                    Exit the test suite immediately after `n` number
                                of failing tests.
  --browser                     Respect the "browser" field in package.json when
                                resolving modules. Some packages export
                                different versions based on whether they are
                                operating in node.js or a browser.     [boolean]
  --cache                       Whether to use the transform cache. Disable the
                                cache using --no-cache.                [boolean]
  --cacheDirectory              The directory where Jest should store its cached
                                dependency information.                 [string]
  --changedFilesWithAncestor    Runs tests related to the current changes and
                                the changes made in the last commit. Behaves
                                similarly to `--onlyChanged`.          [boolean]
  --changedSince                Runs tests related to the changes since the
                                provided branch. If the current branch has
                                diverged from the given branch, then only
                                changes made locally will be tested. Behaves
                                similarly to `--onlyChanged`.           [string]
  --ci                          Whether to run Jest in continuous integration
                                (CI) mode. This option is on by default in most
                                popular CI environments. It will  prevent
                                snapshots from being written unless explicitly
                                requested.            [boolean] [default: false]
  --clearCache                  Clears the configured Jest cache directory and
                                then exits. Default directory can be found by
                                calling jest --showConfig              [boolean]
  --clearMocks                  Automatically clear mock calls and instances
                                between every test. Equivalent to calling
                                jest.clearAllMocks() between each test.[boolean]
  --collectCoverage             Alias for --coverage.                  [boolean]
  --collectCoverageFrom         A glob pattern relative to <rootDir> matching
                                the files that coverage info needs to be
                                collected from.                         [string]
  --collectCoverageOnlyFrom     Explicit list of paths coverage will be
                                restricted to.                           [array]
  --color                       Forces test results output color highlighting
                                (even if stdout is not a TTY). Set to false if
                                you would like to have no colors.      [boolean]
  --colors                      Alias for `--color`.                   [boolean]
  --config, -c                  The path to a jest config file specifying how to
                                find and execute tests. If no rootDir is set in
                                the config, the directory containing the config
                                file is assumed to be the rootDir for the
                                project.This can also be a JSON encoded value
                                which Jest will use as configuration.   [string]
  --coverage                    Indicates that test coverage information should
                                be collected and reported in the output.
                                                                       [boolean]
  --coverageDirectory           The directory where Jest should output its
                                coverage files.                         [string]
  --coveragePathIgnorePatterns  An array of regexp pattern strings that are
                                matched against all file paths before executing
                                the test. If the file pathmatches any of the
                                patterns, coverage information will be skipped.
                                                                         [array]
  --coverageReporters           A list of reporter names that Jest uses when
                                writing coverage reports. Any istanbul reporter
                                can be used.                             [array]
  --coverageThreshold           A JSON string with which will be used to
                                configure minimum threshold enforcement for
                                coverage results                        [string]
  --debug                       Print debugging info about your jest config.
                                                                       [boolean]
  --detectLeaks                 **EXPERIMENTAL**: Detect memory leaks in tests.
                                After executing a test, it will try to garbage
                                collect the global object used, and fail if it
                                was leaked            [boolean] [default: false]
  --detectOpenHandles           Print out remaining open handles preventing Jest
                                from exiting at the end of a test run.
                                                      [boolean] [default: false]
  --env                         The test environment used for all tests. This
                                can point to any file or node module. Examples:
                                `jsdom`, `node` or `path/to/my-environment.js`
                                                                        [string]
  --errorOnDeprecated           Make calling deprecated APIs throw helpful error
                                messages.             [boolean] [default: false]
  --expand, -e                  Use this flag to show full diffs instead of a
                                patch.                                 [boolean]
  --filter                      Path to a module exporting a filtering function.
                                This method receives a list of tests which can
                                be manipulated to exclude tests from running.
                                Especially useful when used in conjunction with
                                a testing infrastructure to filter known broken
                                tests.                                  [string]
  --findRelatedTests            Find related tests for a list of source files
                                that were passed in as arguments. Useful for
                                pre-commit hook integration to run the minimal
                                amount of tests necessary.             [boolean]
  --forceExit                   Force Jest to exit after all tests have
                                completed running. This is useful when resources
                                set up by test code cannot be adequately cleaned
                                up.                                    [boolean]
  --globalSetup                 The path to a module that runs before All Tests.
                                                                        [string]
  --globalTeardown              The path to a module that runs after All Tests.
                                                                        [string]
  --globals                     A JSON string with map of global variables that
                                need to be available in all test environments.
                                                                        [string]
  --haste                       A JSON string with map of variables for the
                                haste module system                     [string]
  --init                        Generate a basic configuration file    [boolean]
  --json                        Prints the test results in JSON. This mode will
                                send all other test output and user messages to
                                stderr.                                [boolean]
  --lastCommit                  Run all tests affected by file changes in the
                                last commit made. Behaves similarly to
                                `--onlyChanged`.                       [boolean]
  --listTests                   Lists all tests Jest will run given the
                                arguments and exits. Most useful in a CI system
                                together with `--findRelatedTests` to determine
                                the tests Jest will run based on specific files
                                                      [boolean] [default: false]
  --logHeapUsage                Logs the heap usage after every test. Useful to
                                debug memory leaks. Use together with
                                `--runInBand` and `--expose-gc` in node.
                                                                       [boolean]
  --mapCoverage                 Maps code coverage reports against original
                                source code when transformers supply source
                                maps.

                                DEPRECATED                             [boolean]
  --maxConcurrency              Specifies the maximum number of tests that are
                                allowed to runconcurrently. This only affects
                                tests using `test.concurrent`.
                                                           [number] [default: 5]
  --maxWorkers, -w              Specifies the maximum number of workers the
                                worker-pool will spawn for running tests. This
                                defaults to the number of the cores available on
                                your machine. (its usually best not to override
                                this default)                           [number]
  --moduleDirectories           An array of directory names to be searched
                                recursively up from the requiring module's
                                location.                                [array]
  --moduleFileExtensions        An array of file extensions your modules use.
                                If you require modules without specifying a
                                file extension, these are the extensions Jest
                                will look for.                           [array]
  --moduleNameMapper            A JSON string with a map from regular
                                expressions to module names that allow to stub
                                out resources, like images or styles with a
                                single module                           [string]
  --modulePathIgnorePatterns    An array of regexp pattern strings that are
                                matched against all module paths before those
                                paths are to be considered "visible" to the
                                module loader.                           [array]
  --modulePaths                 An alternative API to setting the NODE_PATH env
                                variable, modulePaths is an array of absolute
                                paths to additional locations to search when
                                resolving modules.                       [array]
  --noStackTrace                Disables stack trace in test results output
                                                                       [boolean]
  --notify                      Activates notifications for test results.
                                                                       [boolean]
  --notifyMode                  Specifies when notifications will appear for
                                test results.
                                            [string] [default: "failure-change"]
  --onlyChanged, -o             Attempts to identify which tests to run based on
                                which files have changed in the current
                                repository. Only works if you're running tests
                                in a git or hg repository at the moment.
                                                                       [boolean]
  --onlyFailures, -f            Run tests that failed in the previous execution.
                                                                       [boolean]
  --outputFile                  Write test results to a file when the --json
                                option is also specified.               [string]
  --passWithNoTests             Will not fail if no tests are found (for example
                                while using `--testPathPattern`.)
                                                      [boolean] [default: false]
  --preset                      A preset that is used as a base for Jest's
                                configuration.                          [string]
  --prettierPath                The path to the "prettier" module used for
                                inline snapshots.                       [string]
  --projects                    A list of projects that use Jest to run all
                                tests of all projects in a single instance of
                                Jest.                                    [array]
  --reporters                   A list of custom reporters for the test suite.
                                                                         [array]
  --resetMocks                  Automatically reset mock state between every
                                test. Equivalent to calling jest.resetAllMocks()
                                between each test.                     [boolean]
  --resetModules                If enabled, the module registry for every test
                                file will be reset before running each
                                individual test.                       [boolean]
  --resolver                    A JSON string which allows the use of a custom
                                resolver.                               [string]
  --restoreMocks                Automatically restore mock state and
                                implementation between every test. Equivalent to
                                calling jest.restoreAllMocks() between each
                                test.                                  [boolean]
  --rootDir                     The root directory that Jest should scan for
                                tests and modules within.               [string]
  --roots                       A list of paths to directories that Jest should
                                use to search for files in.              [array]
  --runInBand, -i               Run all tests serially in the current process
                                (rather than creating a worker pool of child
                                processes that run tests). This is sometimes
                                useful for debugging, but such use cases are
                                pretty rare.                           [boolean]
  --runTestsByPath              Used when provided patterns are exact file
                                paths. This avoids converting them into a
                                regular expression and matching it against every
                                single file.          [boolean] [default: false]
  --runner                      Allows to use a custom runner instead of Jest's
                                default test runner.                    [string]
  --setupFiles                  A list of paths to modules that run some code
                                to configure or set up the testing environment
                                before each test.                        [array]
  --setupFilesAfterEnv          A list of paths to modules that run some code
                                to configure or set up the testing framework
                                before each test                         [array]
  --showConfig                  Print your jest config and then exits. [boolean]
  --silent                      Prevent tests from printing messages through the
                                console.                               [boolean]
  --skipFilter                  Disables the filter provided by --filter. Useful
                                for CI jobs, or local enforcement when fixing
                                tests.                                 [boolean]
  --snapshotSerializers         A list of paths to snapshot serializer modules
                                Jest should use for snapshot testing.    [array]
  --testEnvironment             Alias for --env                         [string]
  --testEnvironmentOptions      Test environment options that will be passed to
                                the testEnvironment. The relevant options depend
                                on the environment.                     [string]
  --testFailureExitCode         Exit code of `jest` command if the test run
                                failed                                  [string]
  --testLocationInResults       Add `location` information to the test results
                                                      [boolean] [default: false]
  --testMatch                   The glob patterns Jest uses to detect test
                                files.                                   [array]
  --testNamePattern, -t         Run only tests with a name that matches the
                                regex pattern.                          [string]
  --testPathIgnorePatterns      An array of regexp pattern strings that are
                                matched against all test paths before executing
                                the test. If the test path matches any of the
                                patterns, it will be skipped.            [array]
  --testPathPattern             A regexp pattern string that is matched against
                                all tests paths before executing the test.
                                                                         [array]
  --testRegex                   A string or array of string regexp patterns that
                                Jest uses to detect test files.          [array]
  --testResultsProcessor        Allows the use of a custom results processor.
                                This processor must be a node module that
                                exports a function expecting as the first
                                argument the result object.             [string]
  --testRunner                  Allows to specify a custom test runner. The
                                default is  `jasmine2`. A path to a custom test
                                runner can be provided:
                                `<rootDir>/path/to/testRunner.js`.      [string]
  --testSequencer               Allows to specify a custom test sequencer. The
                                default is `@jest/test-sequencer`. A path to a
                                custom test sequencer can be provided:
                                `<rootDir>/path/to/testSequencer.js`    [string]
  --testURL                     This option sets the URL for the jsdom
                                environment.                            [string]
  --timers                      Setting this value to fake allows the use of
                                fake timers for functions such as setTimeout.
                                                                        [string]
  --transform                   A JSON string which maps from regular
                                expressions to paths to transformers.   [string]
  --transformIgnorePatterns     An array of regexp pattern strings that are
                                matched against all source file paths before
                                transformation.                          [array]
  --unmockedModulePathPatterns  An array of regexp pattern strings that are
                                matched against all modules before the module
                                loader will automatically return a mock for
                                them.                                    [array]
  --updateSnapshot, -u          Use this flag to re-record snapshots. Can be
                                used together with a test suite pattern or with
                                `--testNamePattern` to re-record snapshot for
                                test matching the pattern              [boolean]
  --useStderr                   Divert all output to stderr.           [boolean]
  --verbose                     Display individual test results with the test
                                suite hierarchy.                       [boolean]
  --watch                       Watch files for changes and rerun tests related
                                to changed files. If you want to re-run all
                                tests when a file has changed, use the
                                `--watchAll` option.                   [boolean]
  --watchAll                    Watch files for changes and rerun all tests. If
                                you want to re-run only the tests related to the
                                changed files, use the `--watch` option.
                                                                       [boolean]
  --watchPathIgnorePatterns     An array of regexp pattern strings that are
                                matched against all paths before trigger test
                                re-run in watch mode. If the test path matches
                                any of the patterns, it will be skipped. [array]
  --watchman                    Whether to use watchman for file crawling.
                                Disable using --no-watchman.           [boolean]

Documentation: https://jestjs.io/




const greeter = require('../src/modules/greeter');

test('greeter ', () => {
  expect(greeter("ABC")).toBe('Hello, ABC');
});


Intellisense will mark an error on test with following message:

Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`  and then add `jest` or `mocha` to the types field in your tsconfig.ts(2582)


Using Jest with TypeScript

My demo project on GitHub: https://github.com/BojanKomazec/jest-demo-node-ts