NodeJs
Setup
Running start up scripts in node
"scripts": {
"start": "run-p start:dev start:api",
"start:dev: "webpack-dev-server --config webpack.config.dev.js --port 3000",
"prestart:api": "node tools/createMockDb.js",
"start:api": "node tools/apiServer.js"
};
The run-p runs multiple jobs, pre<value> runs the command before the value without pre
Adding consts in webpack
To pass dev/production consts we can do this using webpack. Include webpack in you webpack.config.dev.js and webpack.DefinePlugin e.g.
const webpack = require("webpack")
...
plugins: [
new webpack.DefinePlugin({
"process.env.API_URL": JSON.stringify("http:://localhost:3001")
})
],
...
Introduction
Why nodejs
Node is popular because
- Node supports JavaScript
- Non Blocking
- Virtual Machine Single-Thread
Resources
There is a site https://medium.com/edge-coders/how-well-do-you-know-node-js-36b1473c01c8 where u can test your knowledge.
Resource for the course were at https://github.com/jscomplete/advanced-nodejs
Closures
I am really bad at remembering names for things for here is my understanding of Closures
Lexical Scoping
Basically this is driving at the fact there is such a time called scope, maybe new to people in JS at one time. ha ha. I.E. the var is available in init() but not outside of init()
This is an example of lexical scoping, which describes how a parser resolves variable names when functions are nested. The word lexical refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Nested functions have access to variables declared in their outer scope.
function init() {
var name = 'Mozilla'; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert(name); // use variable declared in the parent function
}
displayName();
}
init();
Closure Example
And repeat this almost, is that we return the function to be executed later. The values at the time of calling makeFunc are retained. i.e. name is 'Mozilla' if we execute myFunc().
A closure is the combination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created. In this case, myFunc is a reference to the instance of the function displayName that is created when makeFunc is run. The instance of displayName maintains a reference to its lexical environment, within which the variable name exists.
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
Node Architecture
V8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among others. It implements ECMAScript and WebAssembly, and runs on Windows 7 or later, macOS 10.12+, and Linux systems that use x64, IA-32, ARM, or MIPS processors. V8 can run standalone, or can be embedded into any C++ application.
libuv is a multi-platform C library that provides support for asynchronous I/O based on event loops. It supports epoll, kqueue, Windows IOCP, and Solaris event ports. It is primarily designed for use in Node.js but it is also used by other software projects.[3] It was originally an abstraction around libev or Microsoft IOCP, as libev supports only select and doesn't support poll and IOCP on Windows.
Chackra
This is an alternative to V8. I could find much on this cos I had other stuff to do but here is a diagram to make the page look nice. Note the picture is deliberately smaller.
V8 Node Options
The v8 engine has three feature groups, Shipping, Staged and In Progress. These are like channels and you can see which feature are supported with
node --v8-options | grep "staged"
Node CLI and REPL
REPL
- autocomplete
- up down history
- _ provides last command value
- .blah, .break will get you out of autocomplete, .save will write to history
Global Object
Introduction
The global object supports many functions. This is the core of Node.
For instance you can create a value in global which can be accessed from anywhere
global.myvar = 10000
An example of usage can be global.process which holds the information for a process started in node. So global.process.env will provide the environment variables.
Taking Process As an Example
In this example we can see that process.on has registered a uncaughtException. If we did not call process.exit(1) this would result in an infinite loop.
// process is an event emitter
process.on('exit', (code) => {
// do one final synchronous operation
// before the node process terminates
console.log(`About to exit with code: ${code}`);
});
process.on('uncaughtException', (err) => {
// something went unhandled.
// Do any cleanup and exit anyway!
console.error(err); // don't do just that.
// FORCE exit the process too.
process.exit(1);
});
// keep the event loop busy
process.stdin.resume();
// trigger a TypeError exception
console.dog();
And the rest
The other functions are like a bash api or c api. They are functions which can be called using javascript.
Require
When we envoke require the following happens
- Resolving
- Evaluating
- Loading
- Wrapping
- Caching
By using the repl we can see how it finds the module.
console.log(module)
Module {
id: '<repl>',
path: '.',
exports: {},
parent: undefined,
filename: null,
loaded: false,
children: [],
paths: [
'/home/iwiseman/dev/scratch/android_frag/repl/node_modules',
'/home/iwiseman/dev/scratch/android_frag/node_modules',
'/home/iwiseman/dev/scratch/node_modules',
'/home/iwiseman/dev/node_modules',
'/home/iwiseman/node_modules',
'/home/node_modules',
'/node_modules',
'/home/iwiseman/.node_modules',
'/home/iwiseman/.node_libraries',
'/usr/local/lib/node'
]
}
With require it will try
- something.js
- something.json
- something.node (compiled add-on file)
// hello.cc
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "world").ToLocalChecked());
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
}