Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Cross-platform Desktop Application Development: Electron, Node, NW.js, and React

You're reading from   Cross-platform Desktop Application Development: Electron, Node, NW.js, and React Build desktop applications with web technologies

Arrow left icon
Product type Paperback
Published in Jul 2017
Publisher Packt
ISBN-13 9781788295697
Length 300 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Dmitry Sheiko Dmitry Sheiko
Author Profile Icon Dmitry Sheiko
Dmitry Sheiko
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Creating a File Explorer with NW.js-Planning, Designing, and Development FREE CHAPTER 2. Creating a File Explorer with NW.js – Enhancement and Delivery 3. Creating a Chat System with Electron and React – Planning, Designing, and Development 4. Creating a Chat System with Electron and React – Enhancement, Testing, and Delivery 5. Creating a Screen Capturer with NW.js, React, and Redux – Planning, Design, and Development 6. Creating a Screen Capturer with NW.js: Enhancement, Tooling, and Testing 7. Creating RSS Aggregator with Electron, TypeScript , React, and Redux: Planning, Design, and Development 8. Creating RSS Aggregator with Electron, TypeScript, React, and Redux: Development

Fulfilling the functional requirements

We've described the semantic structure of our application with HTML. We have defined with CSS how our UI elements shall look. Now, we will teach our application to retrieve and update the content as well as to respond to user events. Actually, we will allocate the following tasks to several modules:

  • DirService: This provides control on directory navigation
  • FileService: This handles file operations
  • FileListView: This updates the file list with the data received from DirService, handles user events (open file, delete file, and so on) using FileService
  • DirListView: This updates the directory list with the data received from DirService and handles navigation events using DirService
  • TitleBarPath: This updates the current location with the path received from DirService
  • TitleBarActions: This handles user iteration with title bar buttons
  • LangSelector: This handles user iteration with language selector

However, before we start coding, let's see what we have in our arsenal.

NW.js gets distributed together with the latest stable version of Node.js, which has a great support for ES2015/ES2016 (http://node.green). It means that we can use any of the inherent new JavaScript features, but modules (http://bit.ly/2moblwB). Node.js has its own CommonJS-compliant module loading system. When we request a module by path, for example, require( "./foo" ), the runtime searches for a corresponding file (foo.js, foo.json, or foo.node) or a directory (./foo/index.js). Then, Node.js evaluates the module code and returns the exported type.

For example, we can create a module that exports a string:

./foo.js

console.log( "foo runs" ); 
exports.message = "foo's export";

and another one, which imports from the first module:

./bar.js

const foo = require( "./foo" ); 
console.log( foo.message );

If we run it, we get the following:

$node bar.js
foo runs
foo's export

One should note here that regardless of how many times we require a module, it gets executed just once, and every time, its exports are taken from the cache.

Starting with ES2015

As I have already mentioned, NW.js provides a complete support of JavaScript of ES2015 and ES2016 editions. To understand what it really means, we need a brief excursion into the history of the language. The standardized specification for JavaScript was first released in 1997 (ECMA-262 1st Edition).

Since then, the language has not really changed for 10 years. The 4th edition proposed in 2007 called for drastic changes. However, the working group (TC39) failed to agree on the feature set. Some proposals have been deemed unsound for the Web, but some were adopted in a new project code named Harmony. The project turned into the 6th edition of the language specification and was released in 2015 under the official name ES2015. Now, the committee is releasing a new specification every year.

New JavaScript is backward compatible with an earlier version. So, you can still write code with the syntax of the ECMAScript 5th edition or even 3rd one, but why should we lose the opportunity to work with the new advanced syntax and feature set? I think it would be helpful if we now go through some new language aspects that will be used in the application.

Scoping

In the old days, we used to always go with the var statement for variable declarations. ES2015 introduces two new declaration variables--let and const. The var statement declares a variable in a function scope:

(function(){ 
var foo = 1;
if ( true ) {
var foo = 2;
console.log( foo );
}
console.log( foo );
}()); $ node es6.js
2
2

A variable declared with var (foo) spans the entire function scope, meaning that every time we reference it by name, we target the same variable. Both let and const operate on block scopes (if statement, for/while loops, and so on) as shown:

 (function(){ 
let foo = 1;
if ( true ) {
let foo = 2;
console.log( foo );
}
console.log( foo );
}()); $ node es6.js
2
1

As you can see from the preceding example, we can declare a new variable in a block and it will exist only within that block. The statement const works the same, except it defines a constant that cannot be reassigned after it was declared.

Classes

JavaScript implies a prototype-based, object-oriented programming style. It differs from class-based OOP that is used in other popular programming languages, such as C++, C#, Objective-C, Java, and PHP. This used to confuse newcomer developers. ES2015 offers a syntactic sugar over the prototype, which looks pretty much like canonical classes:

 
class Machine {
constructor( name ){
this.name = name;
}
}
class Robot extends Machine {
constructor( name ){
super( name );
}
move( direction = "left" ){
console.log( this.name + " moving ", Robot.normalizeDirection( direction ) );
}
static normalizeDirection( direction ) {
return direction.toLowerCase();
}
}

const robot = new Robot( "R2D2" );
robot.move();
robot.move( "RIGHT" ); $ node es6.js
R2D2 moving left
R2D2 moving right

Here, we declare a Machine class that during instantiation assigns a value to a prototype property, name. A Robot class extends Machine and, therefore, inherits the prototype. In subtype, we can invoke the parent constructor with the super keyword.

We also define a prototype method--move--and a static method--normalizeDirection. The move method has a so-called default function parameter. So, if we omit the direction argument while calling move method, the parameter automatically sets to "left".

In ES2015, we can use a short syntax for the methods and do not need to repeat function keywords with every declaration. It's also available for object literals:

 
const R2D2 = {
name: "R2D2",
move(){
console.log( "moving" );
},
fly(){
console.log( "flying" );
}
};

The template literal

Another great addition to JavaScript is template literals. These are string literals that can be multiline and can include interpolated expressions (`${expression}`). For example, we can refactor our move method body, as follows:

  
console.log( `
${this.name} moving ${Robot.normalizeDirection( direction )}
` );

Getters and setters

Getters and setters were added back in ES5.1. In ES2015, it was extended for computed property names and goes hand in hand with a short method notation:

 
class Robot {
get nickname(){
return "But you have to prove first that you belong to the Rebel
Alliance!";
}
set nickname( nickname ){
throw new Error( "Seriously?!" );
}
};

const robot = new Robot();
console.log( robot.nickname );
robot.nickname = "trashcan"; $ node es6.js
But you have to prove first that you belong to the Rebel Alliance!
Error: Seriously?!

Arrow functions

A function declaration also obtained syntactic sugar. We write it now with a shorter syntax. It's remarkable that a function defined this way (fat arrow function) automatically picks up the surrounding context:

class Robot extends Machine { 
//...
isRebel(){
const ALLOWED_NAMES = [ "R2D2", "C3PO" ];
return ALLOWED_NAMES.find(( name ) => {
return name === this.name;
});
}
}

When using old function syntax, the callback function passed to an array's method, find, would lose the context of the Robot instance. Arrow functions, though, do not create their own context and, therefore, outer context (this) gets in the closure.

In this particular example, as it often goes with array extras, the callback body is extremely short. So, we can use an even shorter syntax:

return ALLOWED_NAMES.find( name => name === this.name ); 

Destructuring

In new JavaScript, we can extract specific data from arrays and objects. Let's say, we have an array that could be built by an external function, and we want its first and second elements. We can extract them as simple as this:

const robots =  [ "R2D2", "C3PO", "BB8" ]; 
const [ r2d2, c3po ] = robots;
console.log( r2d2, c3po );

So here, we declare two new constants--r2d2 and c3po--and assign the first and the second array elements to them, respectively.

We can do the same with objects:

const meta = { 
occupation: "Astromech droid",
homeworld: "Naboo"
};

const { occupation, homeworld } = meta;
console.log( occupation, homeworld );

What did we do? We declared two constants--occupation and homeworld--that receive values from correspondingly named object members.

What is more, we can even alias an object member while extracting:

const { occupation: affair, homeworld: home } = meta; 
console.log( affair, home );

In the last example, we delegated the values of object members--occupation and homeworld--to newly created constants--affair and home.

You have been reading a chapter from
Cross-platform Desktop Application Development: Electron, Node, NW.js, and React
Published in: Jul 2017
Publisher: Packt
ISBN-13: 9781788295697
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime