iOS browser cannot get keyboard key for keypress/keydown

1
2
3
4
5
ele.addEventListener('keypress', function(event) {
if (event.key === "Backspace") {
// Do something here
}
});

For this javascript, if you test on PC, or android, it works fine. But if you run on iOS, including webview of iOS. You will find that the webview cannot get the key of the keyboard, e.g. “Backspace”. Quite strange.

But there is a workaround for it - Use “keyCode” instead of “key”; And the above code can write in this way:

1
2
3
4
5
ele.addEventListener('keypress', function(event) {
if (event.key === "Backspace" || event.event.key === 8) {
// Do something here
}
});

OK, it works as expected!

CloudWatch, Azure Monitor, and Stackdriver

Overview

  • Amazon CloudWatch is the platform that monitors Amazon Web Services (AWS).
  • Azure Monitor is Microsoft’s built-in monitoring service for the performance and health of Azure resources. At its most basic level, the model is similar to Cloudwatch: Azure Monitor consumes the telemetry data (performance and log data) that all Azure services generate and allows the user to visualize, query, route, archive, and take actions on the data.
  • Stackdriver, Google’s offering for delivering cloud monitoring capabilities, differs from both Cloudwatch and Azure monitor in a number of ways. Firstly, Stackdriver embraces not only Google Cloud Platform (GCP) but also AWS, providing unified monitoring of the two cloud platforms. Google touts Stackdriver’s multi-cloud strategy and, given Amazon’s prominent standing, it certainly broadens Stackdriver’s appeal.

Stackdriver

Stackdriver also includes a development (DevOPs) component in addition to IT monitoring. However, while the IT Operations functionality spans both AWS and GCP, the DevOPs functionality is Google-centric. Stackdriver is able to troubleshoot deployments on the Google platform with tracing and debugging functionality, and offers capabilities such as:

  • Stackdriver Monitoring measures the health of cloud resources and applications by providing visibility into metrics such as CPU usage, disk I/O, memory, network traffic and uptime. It is based on collectd, an open source daemon that collects system and application performance metrics. Users can receive customizable alerts when Stackdriver Monitoring discovers performance issues. It is used to monitor Google Compute Engine and Amazon EC2 VMs.
  • Stackdriver Error Reporting identifies and analyzes cloud application errors. A centralized error management interface provides IT teams with real-time visibility into production errors with cloud applications, as well as the ability to sort and filter content based on the number of error occurrences, when the error was first and last seen, and where the error is located.
  • Stackdriver Debugger inspects the state of an application, deployed in Google App Engine or Google Compute Engine, using production data and source code. During production, snapshots can be taken of an application’s state and linked back to a specific line location in the source code, without having to add logging statements. This inspection can occur without affecting the performance of the production application.
  • Stackdriver Trace collects network latency data from applications deployed in Google App Engine. Trace data is gathered, analyzed and used to create performance reports to identify network bottlenecks. Trace API and Trace SDK can be used to trace, analyze and optimize custom workloads, as well.
  • Stackdriver Logging provides real-time log management and analysis for cloud applications. Log data can be kept for longer periods of time by archiving it with Google Cloud Storage. The service works with both Google and AWS, and can gather logs from Google Compute Engine, Google App Engine and Amazon EC2.

Stackdriver Monitor

Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver ingests that data and generates insights via dashboards, charts, and alerts.

Monitoring Agent

The Monitoring agent is a collectd-based daemon that gathers system and application metrics from virtual machine instances and sends them to Stackdriver Monitoring. By default, the Monitoring agent collects disk, CPU, network, and process metrics. You can configure the Monitoring agent to monitor third-party applications to get the full list of agent metrics.

Using the Monitoring agent is optional but recommended. Stackdriver Monitoring can access some metrics without the Monitoring agent, including CPU utilization, some disk traffic metrics, network traffic, and uptime information. Stackdriver Monitoring uses the Monitoring agent to access additional system resources and application services in virtual machine (VM) instances. If you want these additional capabilities, you should install the Monitoring agent.

Uptime Checks

Stackdriver can verify the availability of your service by accessing it from locations around the world. You can use the results from these uptime checks in your alerting policies, or you can directly monitor the results in the Stackdriver Monitoring uptime-check dashboards.

Alerting

Alerting gives timely awareness to problems in your cloud applications so you can resolve the problems quickly.

You use the Stackdriver Monitoring Console to set up alerting policies. Each policy specifies the following:

  • Conditions that identify an unhealthy state for a resource or a group of resources.
  • Optional notifications sent through email, SMS, or other channels to let your support team know a resource is unhealthy.
  • Optional documentation that can be included in some types of notifications to help your support team resolve the issue.

When events trigger conditions in one of your alerting policies, Stackdriver Monitoring creates and displays an incident in the Stackdriver Monitoring Console. If you set up notifications, Stackdriver Monitoring also sends notifications to people or third-party notification services. Responders can acknowledge receipt of the notification, but the incident remains open until resources are no longer in an unhealthy state.

Assignment Destructuring in ES6

  • var {foo} = pony is equivalent to var foo = pony.foo
  • var {foo: baz} = pony is equivalent to var baz = pony.foo
  • You can provide default values, var {foo='bar'} = baz yields foo: 'bar' if baz.foo is undefined
  • You can pull as many properties as you like, aliased or not
    • var {foo, bar: baz} = {foo: 0, bar: 1} gets you foo: 0 and baz: 1
  • You can go deeper. var {foo: {bar}} = { foo: { bar: 'baz' } } gets you bar: 'baz'
  • You can alias that too. var {foo: {bar: deep}} = { foo: { bar: 'baz' } } gets you deep: 'baz'
  • Properties that aren’t found yield undefined as usual, e.g: var {foo} = {}
  • Deeply nested properties that aren’t found yield an error, e.g: var {foo: {bar}} = {}
  • It also works for arrays, var [a, b] = [0, 1] yields a: 0 and b: 1
  • You can skip items in an array, var [a, , b] = [0, 1, 2], getting a: 0 and b: 2
  • You can swap without an “aux” variable, [a, b] = [b, a]
  • You can also use destructuring in function parameters
    • Assign default values like function foo (bar=2) {}
    • Those defaults can be objects, too function foo (bar={ a: 1, b: 2 }) {}
    • Destructure bar completely, like function foo ({ a=1, b=2 }) {}
    • Default to an empty object if nothing is provided, like function foo ({ a=1, b=2 } = {}) {}

Node.js Project Best Practice

Overview

Having been using node.js for several years, I have something to share with you. Hope it will save your time.

Lock dependencies

Your code must be identical across all environments but amazingly NPM lets dependencies drift across environments be default – when you install packages at various environments it tries to fetch packages’ latest patch version. Overcome this by using NPM config files , .npmrc, that tell each environment to save the exact (not the latest) version of each package. Alternatively, for finer grain control use NPM” shrinkwrap”. *Update: as of NPM5 , dependencies are locked by default. The new package manager in town, Yarn, also got us covered by default

For team work, I suggest to check-in node modules into your source code (git/snv/etc). To make sure everyone and the production site using the same version of node modules. And another reason is that, some modules are downloaded from github. And it may be not exist anymore after servery month or years.

Keep Your Promises

Node 8 supports the long-awaited async and await keywords without opting in to experimental features. This feature builds on top of Promises allowing you to write asynchronous code that looks like synchronous code and has the same error handling semantics, making it easier to write, easier to understand, and safer.

You can write your callback in this way

1
2
3
4
5
async function getAlbums(() {
const books = await getBooks();
const albums = await getAlbums(books);
return getPhotosForAlbums(albums);
}

Automate Your Code Formatting

We’ve all collectively spent too much time formatting code, adding a space here, aligning a comment there, and we all do it slightly different than our teammate two desks down. This leads to endless debates about where the semicolon goes or whether we should use semicolons at all.

You can use VSCode, which has the ability to format the code.

HTTPS all the things

As web engineers, there is no reason we shouldn’t default all traffic in our applications to using HTTPS. In an express application, there are several things you need to do to make sure you’re serving your site over https.

Be stateless

Store any type of data (e.g. users session, cache, uploaded files) within external data stores. Consider ‘killing’ your servers periodically or use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior.

Otherwise, failure at a given server will result in application downtime instead of a just killing a faulty machine. Moreover, scaling-out elasticity will get more challenging due to the reliance on a specific server.

Set NODE_ENV production

Set the environment variable NODE_ENV to ‘production’ or ‘development’ to flag whether production optimizations should get activated – many NPM packages determining the current environment and optimize their code for production.

For example, Setting NODE_ENV to “production” makes Express:

  • Cache view templates.
  • Cache CSS files generated from CSS extensions.
  • Generate less verbose error messages.

Useful Tools

IDE - VSCode

Visual Studio Code is a lightweight but powerful source code editor which runs on your desktop and is available for Windows, macOS and Linux. It comes with built-in support for JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other languages (such as C++, C#, Java, Python, PHP, Go) and runtimes (such as .NET and Unity).

VSCode

yarn

Yarn is a package manager for your code. It allows you to use and share code with other developers from around the world. Yarn does this quickly, securely, and reliably so you don’t ever have to worry.

Yarn allows you to use other developers’ solutions to different problems, making it easier for you to develop your software. If you have problems, you can report issues or contribute back, and when the problem is fixed, you can use Yarn to keep it all up to date.

e.g. Auto Clean

yarn autoclean
Cleans and removes unnecessary files from package dependencies.

An alternative tool is node-prune, a small tool to prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on.

This tool is written in go language. And there is also a npm package

npm install -g node-prune

e.g. running this tool

1
2
3
4
$ node-prune
files total 27,330
files removed 3,990
size removed 13 MB

webpack/ gulp/ grunt

These are all build tools. Suggest to use gulp for simple scenarios, and webpack for whole site management.

  • webpack - Packs modules and assets for the browser.
  • gulp - Streaming and fast build system that favors code over config.
  • grunt - Task runner that can perform repetitive tasks like minification, compilation, unit testing, linting, etc.

Web

Web Frameworks

Express

Needless to say, Express is the best Web application framework, providing a robust set of features for building single and multi-page, and hybrid web applications. Your first choice for web development.

Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love.

Restify

A Node.js web service framework optimized for building semantically correct RESTful web services ready for production use at scale. restify optimizes for introspection and performance, and is used in some of the largest Node.js deployments on Earth.

If you only want to write a API website, this is better than Express. And more focus on API.

Common Node.js Modules

underscore/lodash

These are two very useful javascript modules to help extend basic javascript usages. They are very similar, and you can choose one freely.
Underscore and Lo-Dash provide similar functionality. Lo-Dash’s API is a superset of Underscore’s. It provides everything that Underscore does, along with a few additional helper functions. Lo-Dash can generally serve as a drop-in replacement for Underscore with no changes; it works just fine with Backbone.

Lo-Dash answers that with a pretty extensive list on its site, but the claims really boils down to a few things:

  • Usability Improvements
  • Extra Functionality
  • Performance Gains

winston

Multi-transport async logging library. Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs.

Use try-catch in javascript

try/catch/throw/finally

Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below.

  • The try statement lets you test a block of code for errors.
  • The catch statement lets you handle the error.
  • The throw statement lets you create custom errors.
  • The finally statement lets you execute code, after try and catch, regardless of the result.

Use a tool such as JSHint or JSLint to help you find implicit exceptions like reference errors on undefined variables.

Here is an example of using try-catch to handle a potential process-crashing exception. This code try to parse a string into json object.

1
2
3
4
5
6
7
8
var jsonStr = 'your json object in string';
try {
var jsonObj = JSON.parse(jsonStr);
} catch (e) {
// handle exception
console.error(e);
}

However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won’t catch a lot of exceptions.

The Error Object

JavaScript has a built in error object that provides error information when an error occurs.

The error object provides two useful properties: name and message.

  • name: Sets or returns an error name
  • message: Sets or returns an error message (a string)

Six different values can be returned by the error name property

  • EvalError: An error has occurred in the eval() function
  • RangeError: A number “out of range” has occurred
  • ReferenceError: An illegal reference has occurred
  • SyntaxError: A syntax error has occurred
  • TypeError: A type error has occurred
  • URIError: An error in encodeURI() has occurred

What is functional programming in javascript

Functional programming produces programs by composing mathematical functions and avoids shared state & mutable data. Lisp (specified in 1958) was among the first languages to support functional programming, and was heavily inspired by lambda calculus. Lisp and many Lisp family languages are still in common use today.

Functional programming is an essential concept in JavaScript (one of the two pillars of JavaScript). Several common functional utilities were added to JavaScript in ES5.

  • Pure functions / function purity.
  • Avoid side-effects.
  • Simple function composition.
  • Examples of functional languages: Lisp, ML, Haskell, Erlang, Clojure, Elm, F Sharp, OCaml, etc…
  • Mention of features that support FP: first-class functions, higher order functions, functions as arguments/values.