diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 845b20c2bd..986c151097 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -48,36 +48,40 @@ equivalent of the following JavaScript code: First, create the file `hello.cc`: - // hello.cc - #include +```cpp +// hello.cc +#include - namespace demo { +namespace demo { - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Object; - using v8::String; - using v8::Value; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; - void Method(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world")); - } +void Method(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world")); +} - void init(Local exports) { - NODE_SET_METHOD(exports, "hello", Method); - } +void init(Local exports) { + NODE_SET_METHOD(exports, "hello", Method); +} - NODE_MODULE(addon, init) +NODE_MODULE(addon, init) - } // namespace demo +} // namespace demo +``` Note that all Node.js Addons must export an initialization function following the pattern: - void Initialize(Local exports); - NODE_MODULE(module_name, Initialize) +```cpp +void Initialize(Local exports); +NODE_MODULE(module_name, Initialize) +``` There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`). @@ -96,14 +100,16 @@ top-level of the project describing the build configuration of your module using a JSON-like format. This file is used by [node-gyp][] -- a tool written specifically to compile Node.js Addons. +``` +{ + "targets": [ { - "targets": [ - { - "target_name": "addon", - "sources": [ "hello.cc" ] - } - ] + "target_name": "addon", + "sources": [ "hello.cc" ] } + ] +} +``` *Note: A version of the `node-gyp` utility is bundled and distributed with Node.js as part of `npm`. This version is not made directly available for @@ -128,10 +134,12 @@ compiled version of the Addon for the user's platform on demand. Once built, the binary Addon can be used from within Node.js by pointing `require()` to the built `addon.node` module: - // hello.js - const addon = require('./build/Release/addon'); +```js +// hello.js +const addon = require('./build/Release/addon'); - console.log(addon.hello()); // 'world' +console.log(addon.hello()); // 'world' +``` Please see the examples below for further information or for an example in production. @@ -144,11 +152,13 @@ Note that while the `bindings` package implementation is more sophisticated in how it locates Addon modules, it is essentially using a try-catch pattern similar to: - try { - return require('./build/Release/addon.node'); - } catch (err) { - return require('./build/Debug/addon.node'); - } +```js +try { + return require('./build/Release/addon.node'); +} catch (err) { + return require('./build/Debug/addon.node'); +} +``` ### Linking to Node.js' own dependencies @@ -209,24 +219,30 @@ several concepts used such as handles, scopes, function templates, etc. Each of these examples using the following `binding.gyp` file: +``` +{ + "targets": [ { - "targets": [ - { - "target_name": "addon", - "sources": [ "addon.cc" ] - } - ] + "target_name": "addon", + "sources": [ "addon.cc" ] } + ] +} +``` In cases where there is more than one `.cc` file, simply add the additional filename to the `sources` array. For example: - "sources": ["addon.cc", "myexample.cc"] +``` +"sources": ["addon.cc", "myexample.cc"] +``` Once the `binding.gyp` file is ready, the example Addons can be configured and built using `node-gyp`: - $ node-gyp configure build +``` +$ node-gyp configure build +``` ### Function arguments @@ -239,64 +255,68 @@ code. The following example illustrates how to read function arguments passed from JavaScript and how to return a result: - // addon.cc - #include - - namespace demo { - - using v8::Exception; - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Number; - using v8::Object; - using v8::String; - using v8::Value; - - // This is the implementation of the "add" method - // Input arguments are passed using the - // const FunctionCallbackInfo& args struct - void Add(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - // Check the number of arguments passed. - if (args.Length() < 2) { - // Throw an Error that is passed back to JavaScript - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong number of arguments"))); - return; - } - - // Check the argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong arguments"))); - return; - } - - // Perform the operation - double value = args[0]->NumberValue() + args[1]->NumberValue(); - Local num = Number::New(isolate, value); - - // Set the return value (using the passed in - // FunctionCallbackInfo&) - args.GetReturnValue().Set(num); - } - - void Init(Local exports) { - NODE_SET_METHOD(exports, "add", Add); - } - - NODE_MODULE(addon, Init) - - } // namespace demo +```cpp +// addon.cc +#include + +namespace demo { + +using v8::Exception; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; + +// This is the implementation of the "add" method +// Input arguments are passed using the +// const FunctionCallbackInfo& args struct +void Add(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + // Check the number of arguments passed. + if (args.Length() < 2) { + // Throw an Error that is passed back to JavaScript + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Wrong number of arguments"))); + return; + } + + // Check the argument types + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Wrong arguments"))); + return; + } + + // Perform the operation + double value = args[0]->NumberValue() + args[1]->NumberValue(); + Local num = Number::New(isolate, value); + + // Set the return value (using the passed in + // FunctionCallbackInfo&) + args.GetReturnValue().Set(num); +} + +void Init(Local exports) { + NODE_SET_METHOD(exports, "add", Add); +} + +NODE_MODULE(addon, Init) + +} // namespace demo +``` Once compiled, the example Addon can be required and used from within Node.js: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); - console.log( 'This should be eight:', addon.add(3,5) ); +console.log('This should be eight:', addon.add(3,5)); +``` ### Callbacks @@ -305,35 +325,37 @@ It is common practice within Addons to pass JavaScript functions to a C++ function and execute them from there. The following example illustrates how to invoke such callbacks: - // addon.cc - #include - - namespace demo { - - using v8::Function; - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Null; - using v8::Object; - using v8::String; - using v8::Value; - - void RunCallback(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - Local cb = Local::Cast(args[0]); - const unsigned argc = 1; - Local argv[argc] = { String::NewFromUtf8(isolate, "hello world") }; - cb->Call(Null(isolate), argc, argv); - } +```cpp +// addon.cc +#include - void Init(Local exports, Local module) { - NODE_SET_METHOD(module, "exports", RunCallback); - } +namespace demo { - NODE_MODULE(addon, Init) +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Null; +using v8::Object; +using v8::String; +using v8::Value; - } // namespace demo +void RunCallback(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + Local cb = Local::Cast(args[0]); + const unsigned argc = 1; + Local argv[argc] = { String::NewFromUtf8(isolate, "hello world") }; + cb->Call(Null(isolate), argc, argv); +} + +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", RunCallback); +} + +NODE_MODULE(addon, Init) + +} // namespace demo +``` Note that this example uses a two-argument form of `Init()` that receives the full `module` object as the second argument. This allows the Addon @@ -342,12 +364,14 @@ adding the function as a property of `exports`. To test it, run the following JavaScript: - // test.js - const addon = require('./build/Release/addon'); +```cpp +// test.js +const addon = require('./build/Release/addon'); - addon(function(msg){ - console.log(msg); // 'hello world' - }); +addon(function(msg){ + console.log(msg); // 'hello world' +}); +``` Note that, in this example, the callback function is invoked synchronously. @@ -357,43 +381,47 @@ Addons can create and return new objects from within a C++ function as illustrated in the following example. An object is created and returned with a property `msg` that echoes the string passed to `createObject()`: - // addon.cc - #include +```cpp +// addon.cc +#include - namespace demo { +namespace demo { - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Object; - using v8::String; - using v8::Value; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; - void CreateObject(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); +void CreateObject(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); - Local obj = Object::New(isolate); - obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString()); + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString()); - args.GetReturnValue().Set(obj); - } + args.GetReturnValue().Set(obj); +} - void Init(Local exports, Local module) { - NODE_SET_METHOD(module, "exports", CreateObject); - } +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", CreateObject); +} - NODE_MODULE(addon, Init) +NODE_MODULE(addon, Init) - } // namespace demo +} // namespace demo +``` To test it in JavaScript: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); - var obj1 = addon('hello'); - var obj2 = addon('world'); - console.log(obj1.msg+' '+obj2.msg); // 'hello world' +var obj1 = addon('hello'); +var obj2 = addon('world'); +console.log(obj1.msg+' '+obj2.msg); // 'hello world' +``` ### Function factory @@ -401,52 +429,56 @@ To test it in JavaScript: Another common scenario is creating JavaScript functions that wrap C++ functions and returning those back to JavaScript: - // addon.cc - #include +```cpp +// addon.cc +#include - namespace demo { +namespace demo { - using v8::Function; - using v8::FunctionCallbackInfo; - using v8::FunctionTemplate; - using v8::Isolate; - using v8::Local; - using v8::Object; - using v8::String; - using v8::Value; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; - void MyFunction(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world")); - } +void MyFunction(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world")); +} - void CreateFunction(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); +void CreateFunction(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); - Local tpl = FunctionTemplate::New(isolate, MyFunction); - Local fn = tpl->GetFunction(); + Local tpl = FunctionTemplate::New(isolate, MyFunction); + Local fn = tpl->GetFunction(); - // omit this to make it anonymous - fn->SetName(String::NewFromUtf8(isolate, "theFunction")); + // omit this to make it anonymous + fn->SetName(String::NewFromUtf8(isolate, "theFunction")); - args.GetReturnValue().Set(fn); - } + args.GetReturnValue().Set(fn); +} - void Init(Local exports, Local module) { - NODE_SET_METHOD(module, "exports", CreateFunction); - } +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", CreateFunction); +} - NODE_MODULE(addon, Init) +NODE_MODULE(addon, Init) - } // namespace demo +} // namespace demo +``` To test: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); - var fn = addon(); - console.log(fn()); // 'hello world' +var fn = addon(); +console.log(fn()); // 'hello world' +``` ### Wrapping C++ objects @@ -454,328 +486,350 @@ To test: It is also possible to wrap C++ objects/classes in a way that allows new instances to be created using the JavaScript `new` operator: - // addon.cc - #include - #include "myobject.h" +```cpp +// addon.cc +#include +#include "myobject.h" - namespace demo { +namespace demo { - using v8::Local; - using v8::Object; +using v8::Local; +using v8::Object; - void InitAll(Local exports) { - MyObject::Init(exports); - } +void InitAll(Local exports) { + MyObject::Init(exports); +} - NODE_MODULE(addon, InitAll) +NODE_MODULE(addon, InitAll) - } // namespace demo +} // namespace demo +``` Then, in `myobject.h`, the wrapper class inherits from `node::ObjectWrap`: - // myobject.h - #ifndef MYOBJECT_H - #define MYOBJECT_H +```cpp +// myobject.h +#ifndef MYOBJECT_H +#define MYOBJECT_H - #include - #include +#include +#include - namespace demo { +namespace demo { - class MyObject : public node::ObjectWrap { - public: - static void Init(v8::Local exports); +class MyObject : public node::ObjectWrap { + public: + static void Init(v8::Local exports); - private: - explicit MyObject(double value = 0); - ~MyObject(); + private: + explicit MyObject(double value = 0); + ~MyObject(); - static void New(const v8::FunctionCallbackInfo& args); - static void PlusOne(const v8::FunctionCallbackInfo& args); - static v8::Persistent constructor; - double value_; - }; + static void New(const v8::FunctionCallbackInfo& args); + static void PlusOne(const v8::FunctionCallbackInfo& args); + static v8::Persistent constructor; + double value_; +}; - } // namespace demo +} // namespace demo - #endif +#endif +``` In `myobject.cc`, implement the various methods that are to be exposed. Below, the method `plusOne()` is exposed by adding it to the constructor's prototype: - // myobject.cc - #include "myobject.h" - - namespace demo { - - using v8::Function; - using v8::FunctionCallbackInfo; - using v8::FunctionTemplate; - using v8::Isolate; - using v8::Local; - using v8::Number; - using v8::Object; - using v8::Persistent; - using v8::String; - using v8::Value; - - Persistent MyObject::constructor; - - MyObject::MyObject(double value) : value_(value) { - } - - MyObject::~MyObject() { - } - - void MyObject::Init(Local exports) { - Isolate* isolate = exports->GetIsolate(); - - // Prepare constructor template - Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - - // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - - constructor.Reset(isolate, tpl->GetFunction()); - exports->Set(String::NewFromUtf8(isolate, "MyObject"), - tpl->GetFunction()); - } - - void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - if (args.IsConstructCall()) { - // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); - } else { - // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); - } - } - - void MyObject::PlusOne(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - MyObject* obj = ObjectWrap::Unwrap(args.Holder()); - obj->value_ += 1; - - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); - } - - } // namespace demo +```cpp +// myobject.cc +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Local exports) { + Isolate* isolate = exports->GetIsolate(); + + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + + constructor.Reset(isolate, tpl->GetFunction()); + exports->Set(String::NewFromUtf8(isolate, "MyObject"), + tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::PlusOne(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + obj->value_ += 1; + + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); +} + +} // namespace demo +``` To build this example, the `myobject.cc` file must be added to the `binding.gyp`: +``` +{ + "targets": [ { - "targets": [ - { - "target_name": "addon", - "sources": [ - "addon.cc", - "myobject.cc" - ] - } + "target_name": "addon", + "sources": [ + "addon.cc", + "myobject.cc" ] } + ] +} +``` Test it with: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); - var obj = new addon.MyObject(10); - console.log( obj.plusOne() ); // 11 - console.log( obj.plusOne() ); // 12 - console.log( obj.plusOne() ); // 13 +var obj = new addon.MyObject(10); +console.log( obj.plusOne() ); // 11 +console.log( obj.plusOne() ); // 12 +console.log( obj.plusOne() ); // 13 +``` ### Factory of wrapped objects Alternatively, it is possible to use a factory pattern to avoid explicitly creating object instances using the JavaScript `new` operator: - var obj = addon.createObject(); - // instead of: - // var obj = new addon.Object(); +```js +var obj = addon.createObject(); +// instead of: +// var obj = new addon.Object(); +``` First, the `createObject()` method is implemented in `addon.cc`: - // addon.cc - #include - #include "myobject.h" +```cpp +// addon.cc +#include +#include "myobject.h" - namespace demo { +namespace demo { - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Object; - using v8::String; - using v8::Value; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; - void CreateObject(const FunctionCallbackInfo& args) { - MyObject::NewInstance(args); - } +void CreateObject(const FunctionCallbackInfo& args) { + MyObject::NewInstance(args); +} - void InitAll(Local exports, Local module) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local exports, Local module) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(module, "exports", CreateObject); - } + NODE_SET_METHOD(module, "exports", CreateObject); +} - NODE_MODULE(addon, InitAll) +NODE_MODULE(addon, InitAll) - } // namespace demo +} // namespace demo +``` In `myobject.h`, the static method `NewInstance()` is added to handle instantiating the object. This method takes the place of using `new` in JavaScript: - // myobject.h - #ifndef MYOBJECT_H - #define MYOBJECT_H +```cpp +// myobject.h +#ifndef MYOBJECT_H +#define MYOBJECT_H - #include - #include +#include +#include - namespace demo { +namespace demo { - class MyObject : public node::ObjectWrap { - public: - static void Init(v8::Isolate* isolate); - static void NewInstance(const v8::FunctionCallbackInfo& args); +class MyObject : public node::ObjectWrap { + public: + static void Init(v8::Isolate* isolate); + static void NewInstance(const v8::FunctionCallbackInfo& args); - private: - explicit MyObject(double value = 0); - ~MyObject(); + private: + explicit MyObject(double value = 0); + ~MyObject(); - static void New(const v8::FunctionCallbackInfo& args); - static void PlusOne(const v8::FunctionCallbackInfo& args); - static v8::Persistent constructor; - double value_; - }; + static void New(const v8::FunctionCallbackInfo& args); + static void PlusOne(const v8::FunctionCallbackInfo& args); + static v8::Persistent constructor; + double value_; +}; - } // namespace demo +} // namespace demo - #endif +#endif +``` The implementation in `myobject.cc` is similar to the previous example: - // myobject.cc - #include - #include "myobject.h" - - namespace demo { - - using v8::Function; - using v8::FunctionCallbackInfo; - using v8::FunctionTemplate; - using v8::Isolate; - using v8::Local; - using v8::Number; - using v8::Object; - using v8::Persistent; - using v8::String; - using v8::Value; - - Persistent MyObject::constructor; - - MyObject::MyObject(double value) : value_(value) { - } - - MyObject::~MyObject() { - } - - void MyObject::Init(Isolate* isolate) { - // Prepare constructor template - Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - - // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - - constructor.Reset(isolate, tpl->GetFunction()); - } - - void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - if (args.IsConstructCall()) { - // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); - } else { - // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); - } - } - - void MyObject::NewInstance(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - const unsigned argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - Local instance = cons->NewInstance(argc, argv); - - args.GetReturnValue().Set(instance); - } - - void MyObject::PlusOne(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - MyObject* obj = ObjectWrap::Unwrap(args.Holder()); - obj->value_ += 1; - - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); - } - - } // namespace demo +```cpp +// myobject.cc +#include +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Isolate* isolate) { + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + + constructor.Reset(isolate, tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::NewInstance(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + const unsigned argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + Local instance = cons->NewInstance(argc, argv); + + args.GetReturnValue().Set(instance); +} + +void MyObject::PlusOne(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + obj->value_ += 1; + + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); +} + +} // namespace demo +``` Once again, to build this example, the `myobject.cc` file must be added to the `binding.gyp`: +``` +{ + "targets": [ { - "targets": [ - { - "target_name": "addon", - "sources": [ - "addon.cc", - "myobject.cc" - ] - } + "target_name": "addon", + "sources": [ + "addon.cc", + "myobject.cc" ] } + ] +} +``` Test it with: - // test.js - const createObject = require('./build/Release/addon'); +```js +// test.js +const createObject = require('./build/Release/addon'); - var obj = createObject(10); - console.log( obj.plusOne() ); // 11 - console.log( obj.plusOne() ); // 12 - console.log( obj.plusOne() ); // 13 +var obj = createObject(10); +console.log( obj.plusOne() ); // 11 +console.log( obj.plusOne() ); // 12 +console.log( obj.plusOne() ); // 13 - var obj2 = createObject(20); - console.log( obj2.plusOne() ); // 21 - console.log( obj2.plusOne() ); // 22 - console.log( obj2.plusOne() ); // 23 +var obj2 = createObject(20); +console.log( obj2.plusOne() ); // 21 +console.log( obj2.plusOne() ); // 22 +console.log( obj2.plusOne() ); // 23 +``` ### Passing wrapped objects around @@ -785,155 +839,163 @@ wrapped objects around by unwrapping them with the Node.js helper function `node::ObjectWrap::Unwrap`. The following examples shows a function `add()` that can take two `MyObject` objects as input arguments: - // addon.cc - #include - #include - #include "myobject.h" +```cpp +// addon.cc +#include +#include +#include "myobject.h" - namespace demo { +namespace demo { - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::Number; - using v8::Object; - using v8::String; - using v8::Value; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; - void CreateObject(const FunctionCallbackInfo& args) { - MyObject::NewInstance(args); - } +void CreateObject(const FunctionCallbackInfo& args) { + MyObject::NewInstance(args); +} - void Add(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); +void Add(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); - MyObject* obj1 = node::ObjectWrap::Unwrap( - args[0]->ToObject()); - MyObject* obj2 = node::ObjectWrap::Unwrap( - args[1]->ToObject()); + MyObject* obj1 = node::ObjectWrap::Unwrap( + args[0]->ToObject()); + MyObject* obj2 = node::ObjectWrap::Unwrap( + args[1]->ToObject()); - double sum = obj1->value() + obj2->value(); - args.GetReturnValue().Set(Number::New(isolate, sum)); - } + double sum = obj1->value() + obj2->value(); + args.GetReturnValue().Set(Number::New(isolate, sum)); +} - void InitAll(Local exports) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local exports) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(exports, "createObject", CreateObject); - NODE_SET_METHOD(exports, "add", Add); - } + NODE_SET_METHOD(exports, "createObject", CreateObject); + NODE_SET_METHOD(exports, "add", Add); +} - NODE_MODULE(addon, InitAll) +NODE_MODULE(addon, InitAll) - } // namespace demo +} // namespace demo +``` In `myobject.h`, a new public method is added to allow access to private values after unwrapping the object. - // myobject.h - #ifndef MYOBJECT_H - #define MYOBJECT_H +```cpp +// myobject.h +#ifndef MYOBJECT_H +#define MYOBJECT_H - #include - #include +#include +#include - namespace demo { +namespace demo { - class MyObject : public node::ObjectWrap { - public: - static void Init(v8::Isolate* isolate); - static void NewInstance(const v8::FunctionCallbackInfo& args); - inline double value() const { return value_; } +class MyObject : public node::ObjectWrap { + public: + static void Init(v8::Isolate* isolate); + static void NewInstance(const v8::FunctionCallbackInfo& args); + inline double value() const { return value_; } - private: - explicit MyObject(double value = 0); - ~MyObject(); + private: + explicit MyObject(double value = 0); + ~MyObject(); - static void New(const v8::FunctionCallbackInfo& args); - static v8::Persistent constructor; - double value_; - }; + static void New(const v8::FunctionCallbackInfo& args); + static v8::Persistent constructor; + double value_; +}; - } // namespace demo +} // namespace demo - #endif +#endif +``` The implementation of `myobject.cc` is similar to before: - // myobject.cc - #include - #include "myobject.h" - - namespace demo { - - using v8::Function; - using v8::FunctionCallbackInfo; - using v8::FunctionTemplate; - using v8::Isolate; - using v8::Local; - using v8::Object; - using v8::Persistent; - using v8::String; - using v8::Value; - - Persistent MyObject::constructor; - - MyObject::MyObject(double value) : value_(value) { - } - - MyObject::~MyObject() { - } - - void MyObject::Init(Isolate* isolate) { - // Prepare constructor template - Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - - constructor.Reset(isolate, tpl->GetFunction()); - } - - void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - if (args.IsConstructCall()) { - // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); - } else { - // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); - } - } - - void MyObject::NewInstance(const FunctionCallbackInfo& args) { - Isolate* isolate = args.GetIsolate(); - - const unsigned argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - Local instance = cons->NewInstance(argc, argv); - - args.GetReturnValue().Set(instance); - } - - } // namespace demo +```cpp +// myobject.cc +#include +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Isolate* isolate) { + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + constructor.Reset(isolate, tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::NewInstance(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + const unsigned argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + Local instance = cons->NewInstance(argc, argv); + + args.GetReturnValue().Set(instance); +} + +} // namespace demo +``` Test it with: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); - var obj1 = addon.createObject(10); - var obj2 = addon.createObject(20); - var result = addon.add(obj1, obj2); +var obj1 = addon.createObject(10); +var obj2 = addon.createObject(20); +var result = addon.add(obj1, obj2); - console.log(result); // 30 +console.log(result); // 30 +``` ### AtExit hooks @@ -956,58 +1018,62 @@ Callbacks are run in last-in first-out order. The following `addon.cc` implements AtExit: - // addon.cc - #undef NDEBUG - #include - #include - #include - - namespace demo { - - using node::AtExit; - using v8::HandleScope; - using v8::Isolate; - using v8::Local; - using v8::Object; - - static char cookie[] = "yum yum"; - static int at_exit_cb1_called = 0; - static int at_exit_cb2_called = 0; - - static void at_exit_cb1(void* arg) { - Isolate* isolate = static_cast(arg); - HandleScope scope(isolate); - Local obj = Object::New(isolate); - assert(!obj.IsEmpty()); // assert VM is still alive - assert(obj->IsObject()); - at_exit_cb1_called++; - } - - static void at_exit_cb2(void* arg) { - assert(arg == static_cast(cookie)); - at_exit_cb2_called++; - } - - static void sanity_check(void*) { - assert(at_exit_cb1_called == 1); - assert(at_exit_cb2_called == 2); - } - - void init(Local exports) { - AtExit(sanity_check); - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb1, exports->GetIsolate()); - } - - NODE_MODULE(addon, init); - - } // namespace demo +```cpp +// addon.cc +#undef NDEBUG +#include +#include +#include + +namespace demo { + +using node::AtExit; +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::Object; + +static char cookie[] = "yum yum"; +static int at_exit_cb1_called = 0; +static int at_exit_cb2_called = 0; + +static void at_exit_cb1(void* arg) { + Isolate* isolate = static_cast(arg); + HandleScope scope(isolate); + Local obj = Object::New(isolate); + assert(!obj.IsEmpty()); // assert VM is still alive + assert(obj->IsObject()); + at_exit_cb1_called++; +} + +static void at_exit_cb2(void* arg) { + assert(arg == static_cast(cookie)); + at_exit_cb2_called++; +} + +static void sanity_check(void*) { + assert(at_exit_cb1_called == 1); + assert(at_exit_cb2_called == 2); +} + +void init(Local exports) { + AtExit(sanity_check); + AtExit(at_exit_cb2, cookie); + AtExit(at_exit_cb2, cookie); + AtExit(at_exit_cb1, exports->GetIsolate()); +} + +NODE_MODULE(addon, init); + +} // namespace demo +``` Test in JavaScript by running: - // test.js - const addon = require('./build/Release/addon'); +```js +// test.js +const addon = require('./build/Release/addon'); +``` [online]: https://v8docs.nodesource.com/ [libuv]: https://github.com/libuv/libuv diff --git a/doc/api/assert.markdown b/doc/api/assert.markdown index ff387972c8..0a9fa36d06 100644 --- a/doc/api/assert.markdown +++ b/doc/api/assert.markdown @@ -2,10 +2,10 @@ Stability: 3 - Locked -The `assert` module provides a simple set of assertion tests that can be used to -test invariants. The module is intended for internal use by Node.js, but can be -used in application code via `require('assert')`. However, `assert` is not a -testing framework, and is not intended to be used as a general purpose assertion +The `assert` module provides a simple set of assertion tests that can be used to +test invariants. The module is intended for internal use by Node.js, but can be +used in application code via `require('assert')`. However, `assert` is not a +testing framework, and is not intended to be used as a general purpose assertion library. The API for the `assert` module is [Locked][]. This means that there will be no @@ -21,25 +21,27 @@ If `value` is not truthy, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is `undefined`, a default error message is assigned. - const assert = require('assert'); - - assert(true); // OK - assert(1); // OK - assert(false); - // throws "AssertionError: false == true" - assert(0); - // throws "AssertionError: 0 == true" - assert(false, 'it\'s false'); - // throws "AssertionError: it's false" - - assert.ok(true); // OK - assert.ok(1); // OK - assert.ok(false); - // throws "AssertionError: false == true" - assert.ok(0); - // throws "AssertionError: 0 == true" - assert.ok(false, 'it\'s false'); - // throws "AssertionError: it's false" +```js +const assert = require('assert'); + +assert(true); // OK +assert(1); // OK +assert(false); + // throws "AssertionError: false == true" +assert(0); + // throws "AssertionError: 0 == true" +assert(false, 'it\'s false'); + // throws "AssertionError: it's false" + +assert.ok(true); // OK +assert.ok(1); // OK +assert.ok(false); + // throws "AssertionError: false == true" +assert.ok(0); + // throws "AssertionError: 0 == true" +assert.ok(false, 'it\'s false'); + // throws "AssertionError: it's false" +``` ## assert.deepEqual(actual, expected[, message]) @@ -52,44 +54,48 @@ non-enumerable properties. This can lead to some potentially surprising results. For example, the following example does not throw an `AssertionError` because the properties on the [`Error`][] object are non-enumerable: - // WARNING: This does not throw an AssertionError! - assert.deepEqual(Error('a'), Error('b')); +```js +// WARNING: This does not throw an AssertionError! +assert.deepEqual(Error('a'), Error('b')); +``` "Deep" equality means that the enumerable "own" properties of child objects are evaluated also: - const assert = require('assert'); - - const obj1 = { - a : { - b : 1 - } - }; - const obj2 = { - a : { - b : 2 - } - }; - const obj3 = { - a : { - b : 1 - } - } - const obj4 = Object.create(obj1); - - assert.deepEqual(obj1, obj1); - // OK, object is equal to itself - - assert.deepEqual(obj1, obj2); - // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } } - // values of b are different - - assert.deepEqual(obj1, obj3); - // OK, objects are equal - - assert.deepEqual(obj1, obj4); - // AssertionError: { a: { b: 1 } } deepEqual {} - // Prototypes are ignored +```js +const assert = require('assert'); + +const obj1 = { + a : { + b : 1 + } +}; +const obj2 = { + a : { + b : 2 + } +}; +const obj3 = { + a : { + b : 1 + } +} +const obj4 = Object.create(obj1); + +assert.deepEqual(obj1, obj1); + // OK, object is equal to itself + +assert.deepEqual(obj1, obj2); + // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } } + // values of b are different + +assert.deepEqual(obj1, obj3); + // OK, objects are equal + +assert.deepEqual(obj1, obj4); + // AssertionError: { a: { b: 1 } } deepEqual {} + // Prototypes are ignored +``` If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` @@ -100,14 +106,16 @@ parameter is undefined, a default error message is assigned. Generally identical to `assert.deepEqual` with the exception that primitive values are compared using the strict equality operator ( `===` ). - const assert = require('assert'); +```js +const assert = require('assert'); - assert.deepEqual({a:1}, {a:'1'}); - // OK, because 1 == '1' +assert.deepEqual({a:1}, {a:'1'}); + // OK, because 1 == '1' - assert.deepStrictEqual({a:1}, {a:'1'}); - // AssertionError: { a: 1 } deepStrictEqual { a: '1' } - // because 1 !== '1' using strict equality +assert.deepStrictEqual({a:1}, {a:'1'}); + // AssertionError: { a: 1 } deepStrictEqual { a: '1' } + // because 1 !== '1' using strict equality +``` If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` @@ -129,52 +137,60 @@ to the caller. The following, for instance, will throw the [`TypeError`][] because there is no matching error type in the assertion: - assert.doesNotThrow( - function() { - throw new TypeError('Wrong value'); - }, - SyntaxError - ); +```js +assert.doesNotThrow( + function() { + throw new TypeError('Wrong value'); + }, + SyntaxError +); +``` However, the following will result in an `AssertionError` with the message 'Got unwanted exception (TypeError)..': - assert.doesNotThrow( - function() { - throw new TypeError('Wrong value'); - }, - TypeError - ); +```js +assert.doesNotThrow( + function() { + throw new TypeError('Wrong value'); + }, + TypeError +); +``` If an `AssertionError` is thrown and a value is provided for the `message` parameter, the value of `message` will be appended to the `AssertionError` message: - assert.doesNotThrow( - function() { - throw new TypeError('Wrong value'); - }, - TypeError, - 'Whoops' - ); - // Throws: AssertionError: Got unwanted exception (TypeError). Whoops +```js +assert.doesNotThrow( + function() { + throw new TypeError('Wrong value'); + }, + TypeError, + 'Whoops' +); +// Throws: AssertionError: Got unwanted exception (TypeError). Whoops +``` ## assert.equal(actual, expected[, message]) Tests shallow, coercive equality between the `actual` and `expected` parameters using the equal comparison operator ( `==` ). - const assert = require('assert'); +```js +const assert = require('assert'); - assert.equal(1, 1); - // OK, 1 == 1 - assert.equal(1, '1'); - // OK, 1 == '1' +assert.equal(1, 1); + // OK, 1 == 1 +assert.equal(1, '1'); + // OK, 1 == '1' - assert.equal(1, 2); - // AssertionError: 1 == 2 - assert.equal({a: {b: 1}}, {a: {b: 1}}); - //AssertionError: { a: { b: 1 } } == { a: { b: 1 } } +assert.equal(1, 2); + // AssertionError: 1 == 2 +assert.equal({a: {b: 1}}, {a: {b: 1}}); + //AssertionError: { a: { b: 1 } } == { a: { b: 1 } } +``` If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` @@ -186,60 +202,66 @@ Throws an `AssertionError`. If `message` is falsy, the error message is set as the values of `actual` and `expected` separated by the provided `operator`. Otherwise, the error message is the value of `message`. - const assert = require('assert'); +```js +const assert = require('assert'); - assert.fail(1, 2, undefined, '>'); - // AssertionError: 1 > 2 +assert.fail(1, 2, undefined, '>'); + // AssertionError: 1 > 2 - assert.fail(1, 2, 'whoops', '>'); - // AssertionError: whoops +assert.fail(1, 2, 'whoops', '>'); + // AssertionError: whoops +``` ## assert.ifError(value) Throws `value` if `value` is truthy. This is useful when testing the `error` argument in callbacks. - const assert = require('assert'); +```js +const assert = require('assert'); - assert.ifError(0); // OK - assert.ifError(1); // Throws 1 - assert.ifError('error') // Throws 'error' - assert.ifError(new Error()); // Throws Error +assert.ifError(0); // OK +assert.ifError(1); // Throws 1 +assert.ifError('error') // Throws 'error' +assert.ifError(new Error()); // Throws Error +``` ## assert.notDeepEqual(actual, expected[, message]) Tests for any deep inequality. Opposite of [`assert.deepEqual`][]. - const assert = require('assert'); - - const obj1 = { - a : { - b : 1 - } - }; - const obj2 = { - a : { - b : 2 - } - }; - const obj3 = { - a : { - b : 1 - } - } - const obj4 = Object.create(obj1); - - assert.deepEqual(obj1, obj1); - AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } - - assert.deepEqual(obj1, obj2); - // OK, obj1 and obj2 are not deeply equal - - assert.deepEqual(obj1, obj3); - // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } - - assert.deepEqual(obj1, obj4); - // OK, obj1 and obj2 are not deeply equal +```js +const assert = require('assert'); + +const obj1 = { + a : { + b : 1 + } +}; +const obj2 = { + a : { + b : 2 + } +}; +const obj3 = { + a : { + b : 1 + } +} +const obj4 = Object.create(obj1); + +assert.deepEqual(obj1, obj1); + AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } + +assert.deepEqual(obj1, obj2); + // OK, obj1 and obj2 are not deeply equal + +assert.deepEqual(obj1, obj3); + // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } + +assert.deepEqual(obj1, obj4); + // OK, obj1 and obj2 are not deeply equal +``` If the values are deeply equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` @@ -249,13 +271,15 @@ parameter is undefined, a default error message is assigned. Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual`][]. - const assert = require('assert'); +```js +const assert = require('assert'); - assert.notDeepEqual({a:1}, {a:'1'}); - // AssertionError: { a: 1 } notDeepEqual { a: '1' } +assert.notDeepEqual({a:1}, {a:'1'}); + // AssertionError: { a: 1 } notDeepEqual { a: '1' } - assert.notDeepStrictEqual({a:1}, {a:'1'}); - // OK +assert.notDeepStrictEqual({a:1}, {a:'1'}); + // OK +``` If the values are deeply and strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If @@ -266,16 +290,18 @@ the `message` parameter is undefined, a default error message is assigned. Tests shallow, coercive inequality with the not equal comparison operator ( `!=` ). - const assert = require('assert'); +```js +const assert = require('assert'); - assert.notEqual(1, 2); - // OK +assert.notEqual(1, 2); + // OK - assert.notEqual(1, 1); - // AssertionError: 1 != 1 +assert.notEqual(1, 1); + // AssertionError: 1 != 1 - assert.notEqual(1, '1'); - // AssertionError: 1 != '1' +assert.notEqual(1, '1'); + // AssertionError: 1 != '1' +``` If the values are equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` @@ -286,16 +312,18 @@ parameter is undefined, a default error message is assigned. Tests strict inequality as determined by the strict not equal operator ( `!==` ). - const assert = require('assert'); +```js +const assert = require('assert'); - assert.notStrictEqual(1, 2); - // OK +assert.notStrictEqual(1, 2); + // OK - assert.notStrictEqual(1, 1); - // AssertionError: 1 != 1 +assert.notStrictEqual(1, 1); + // AssertionError: 1 != 1 - assert.notStrictEqual(1, '1'); - // OK +assert.notStrictEqual(1, '1'); + // OK +``` If the values are strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the @@ -305,16 +333,18 @@ If the values are strictly equal, an `AssertionError` is thrown with a Tests strict equality as determined by the strict equality operator ( `===` ). - const assert = require('assert'); +```js +const assert = require('assert'); - assert.strictEqual(1, 2); - // AssertionError: 1 === 2 +assert.strictEqual(1, 2); + // AssertionError: 1 === 2 - assert.strictEqual(1, 1); - // OK +assert.strictEqual(1, 1); + // OK - assert.strictEqual(1, '1'); - // AssertionError: 1 === '1' +assert.strictEqual(1, '1'); + // AssertionError: 1 === '1' +``` If the values are not strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the @@ -327,35 +357,41 @@ constructor, [`RegExp`][], or validation function. Validate instanceof using constructor: - assert.throws( - function() { - throw new Error('Wrong value'); - }, - Error - ); +```js +assert.throws( + function() { + throw new Error('Wrong value'); + }, + Error +); +``` Validate error message using [`RegExp`][]: - assert.throws( - function() { - throw new Error('Wrong value'); - }, - /value/ - ); +```js +assert.throws( + function() { + throw new Error('Wrong value'); + }, + /value/ +); +``` Custom error validation: - assert.throws( - function() { - throw new Error('Wrong value'); - }, - function(err) { - if ( (err instanceof Error) && /value/.test(err) ) { - return true; - } - }, - 'unexpected error' - ); +```js +assert.throws( + function() { + throw new Error('Wrong value'); + }, + function(err) { + if ( (err instanceof Error) && /value/.test(err) ) { + return true; + } + }, + 'unexpected error' +); +``` [Locked]: documentation.html#documentation_stability_index [`assert.deepEqual`]: #assert_assert_deepequal_actual_expected_message diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown index 090a3eef51..9c202044da 100644 --- a/doc/api/buffer.markdown +++ b/doc/api/buffer.markdown @@ -20,17 +20,19 @@ resized. The `Buffer` class is a global within Node.js, making it unlikely that one would need to ever use `require('buffer')`. - const buf1 = new Buffer(10); - // creates a buffer of length 10 +```js +const buf1 = new Buffer(10); + // creates a buffer of length 10 - const buf2 = new Buffer([1,2,3]); - // creates a buffer containing [01, 02, 03] +const buf2 = new Buffer([1,2,3]); + // creates a buffer containing [01, 02, 03] - const buf3 = new Buffer('test'); - // creates a buffer containing ASCII bytes [74, 65, 73, 74] +const buf3 = new Buffer('test'); + // creates a buffer containing ASCII bytes [74, 65, 73, 74] - const buf4 = new Buffer('tést', 'utf8'); - // creates a buffer containing UTF8 bytes [74, c3, a9, 73, 74] +const buf4 = new Buffer('tést', 'utf8'); + // creates a buffer containing UTF8 bytes [74, c3, a9, 73, 74] +``` ## Buffers and Character Encodings @@ -39,11 +41,13 @@ such as UTF8, UCS2, Base64 or even Hex-encoded data. It is possible to convert back and forth between Buffers and ordinary JavaScript string objects by using an explicit encoding method. - const buf = new Buffer('hello world', 'ascii'); - console.log(buf.toString('hex')); - // prints: 68656c6c6f20776f726c64 - console.log(buf.toString('base64')); - // prints: aGVsbG8gd29ybGQ= +```js +const buf = new Buffer('hello world', 'ascii'); +console.log(buf.toString('hex')); + // prints: 68656c6c6f20776f726c64 +console.log(buf.toString('base64')); + // prints: aGVsbG8gd29ybGQ= +``` The character encodings currently supported by Node.js include: @@ -88,47 +92,53 @@ as a byte array of the target type. That is, It is possible to create a new Buffer that shares the same allocated memory as a TypedArray instance by using the TypeArray objects `.buffer` property: - const arr = new Uint16Array(2); - arr[0] = 5000; - arr[1] = 4000; +```js +const arr = new Uint16Array(2); +arr[0] = 5000; +arr[1] = 4000; - const buf1 = new Buffer(arr); // copies the buffer - const buf2 = new Buffer(arr.buffer); // shares the memory with arr; +const buf1 = new Buffer(arr); // copies the buffer +const buf2 = new Buffer(arr.buffer); // shares the memory with arr; - console.log(buf1); - // Prints: , copied buffer has only two elements - console.log(buf2); - // Prints: +console.log(buf1); + // Prints: , copied buffer has only two elements +console.log(buf2); + // Prints: - arr[1] = 6000; - console.log(buf1); - // Prints: - console.log(buf2); - // Prints: +arr[1] = 6000; +console.log(buf1); + // Prints: +console.log(buf2); + // Prints: +``` Note that when creating a Buffer using the TypeArray's `.buffer`, it is not currently possible to use only a portion of the underlying `ArrayBuffer`. To create a Buffer that uses only a part of the `ArrayBuffer`, use the `buf.slice()` function after the Buffer is created: - const arr = new Uint16Array(20); - const buf = new Buffer(arr.buffer).slice(0, 16); - console.log(buf.length); - // Prints: 16 +```js +const arr = new Uint16Array(20); +const buf = new Buffer(arr.buffer).slice(0, 16); +console.log(buf.length); + // Prints: 16 +``` ## Buffers and ES6 iteration Buffers can be iterated over using the ECMAScript 2015 (ES6) `for..of` syntax: - const buf = new Buffer([1, 2, 3]); +```js +const buf = new Buffer([1, 2, 3]); - for (var b of buf) - console.log(b) +for (var b of buf) + console.log(b) - // Prints: - // 1 - // 2 - // 3 +// Prints: +// 1 +// 2 +// 3 +``` Additionally, the `buffer.values()`, `buffer.keys()`, and `buffer.entries()` methods can be used to create iterators. @@ -144,9 +154,11 @@ It can be constructed in a variety of ways. Allocates a new Buffer using an `array` of octets. - const buf = new Buffer([0x62,0x75,0x66,0x66,0x65,0x72]); - // creates a new Buffer containing ASCII bytes - // ['b','u','f','f','e','r'] +```js +const buf = new Buffer([0x62,0x75,0x66,0x66,0x65,0x72]); + // creates a new Buffer containing ASCII bytes + // ['b','u','f','f','e','r'] +``` ### new Buffer(buffer) @@ -154,14 +166,16 @@ Allocates a new Buffer using an `array` of octets. Copies the passed `buffer` data onto a new `Buffer` instance. - const buf1 = new Buffer('buffer'); - const buf2 = new Buffer(buf1); +```js +const buf1 = new Buffer('buffer'); +const buf2 = new Buffer(buf1); - buf1[0] = 0x61; - console.log(buf1.toString()); - // 'auffer' - console.log(buf2.toString()); - // 'buffer' (copy is not changed) +buf1[0] = 0x61; +console.log(buf1.toString()); + // 'auffer' +console.log(buf2.toString()); + // 'buffer' (copy is not changed) +``` ### new Buffer(arrayBuffer) @@ -172,20 +186,22 @@ When passed a reference to the `.buffer` property of a `TypedArray` instance, the newly created Buffer will share the same allocated memory as the TypedArray. - const arr = new Uint16Array(2); - arr[0] = 5000; - arr[1] = 4000; +```js +const arr = new Uint16Array(2); +arr[0] = 5000; +arr[1] = 4000; - const buf = new Buffer(arr.buffer); // shares the memory with arr; +const buf = new Buffer(arr.buffer); // shares the memory with arr; - console.log(buf); - // Prints: +console.log(buf); + // Prints: - // changing the TypdArray changes the Buffer also - arr[1] = 6000; +// changing the TypdArray changes the Buffer also +arr[1] = 6000; - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### new Buffer(size) @@ -202,13 +218,15 @@ this way is not initialized. The contents of a newly created `Buffer` are unknown and could contain sensitive data. Use [`buf.fill(0)`][] to initialize a Buffer to zeroes. - const buf = new Buffer(5); - console.log(buf); - // - // (octets will be different, every time) - buf.fill(0); - console.log(buf); - // +```js +const buf = new Buffer(5); +console.log(buf); + // + // (octets will be different, every time) +buf.fill(0); +console.log(buf); + // +``` ### new Buffer(str[, encoding]) @@ -219,15 +237,17 @@ Creates a new Buffer containing the given JavaScript string `str`. If provided, the `encoding` parameter identifies the strings character encoding. If not provided, `encoding` defaults to `'utf8'`. - const buf1 = new Buffer('this is a tést'); - console.log(buf1.toString()); - // prints: this is a tést - console.log(buf1.toString('ascii')); - // prints: this is a tC)st +```js +const buf1 = new Buffer('this is a tést'); +console.log(buf1.toString()); + // prints: this is a tést +console.log(buf1.toString('ascii')); + // prints: this is a tC)st - const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex'); - console.log(buf2.toString()); - // prints: this is a tést +const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex'); +console.log(buf2.toString()); + // prints: this is a tést +``` ### Class Method: Buffer.byteLength(string[, encoding]) @@ -241,12 +261,14 @@ since that returns the number of *characters* in a string. Example: - const str = '\u00bd + \u00bc = \u00be'; +```js +const str = '\u00bd + \u00bc = \u00be'; - console.log(`${str}: ${str.length} characters, ` + - `${Buffer.byteLength(str, 'utf8')} bytes`); +console.log(`${str}: ${str.length} characters, ` + + `${Buffer.byteLength(str, 'utf8')} bytes`); - // ½ + ¼ = ¾: 9 characters, 12 bytes +// ½ + ¼ = ¾: 9 characters, 12 bytes +``` ### Class Method: Buffer.compare(buf1, buf2) @@ -256,8 +278,10 @@ Example: Compares `buf1` to `buf2` typically for the purpose of sorting arrays of Buffers. This is equivalent is calling `buf1.compare(buf2)`. - const arr = [Buffer('1234'), Buffer('0123')]; - arr.sort(Buffer.compare); +```js +const arr = [Buffer('1234'), Buffer('0123')]; +arr.sort(Buffer.compare); +``` ### Class Method: Buffer.concat(list[, totalLength]) @@ -276,19 +300,21 @@ to provide the length explicitly. Example: build a single Buffer from a list of three Buffers: - const buf1 = new Buffer(10).fill(0); - const buf2 = new Buffer(14).fill(0); - const buf3 = new Buffer(18).fill(0); - const totalLength = buf1.length + buf2.length + buf3.length; +```js +const buf1 = new Buffer(10).fill(0); +const buf2 = new Buffer(14).fill(0); +const buf3 = new Buffer(18).fill(0); +const totalLength = buf1.length + buf2.length + buf3.length; - console.log(totalLength); - const bufA = Buffer.concat([buf1, buf2, buf3], totalLength); - console.log(bufA); - console.log(bufA.length); +console.log(totalLength); +const bufA = Buffer.concat([buf1, buf2, buf3], totalLength); +console.log(bufA); +console.log(bufA.length); - // 42 - // - // 42 +// 42 +// +// 42 +``` ### Class Method: Buffer.isBuffer(obj) @@ -309,61 +335,67 @@ otherwise. Creates and returns an [iterator][] of `[index, byte]` pairs from the Buffer contents. - const buf = new Buffer('buffer'); - for (var pair of buf.entries()) { - console.log(pair); - } - // prints: - // [0, 98] - // [1, 117] - // [2, 102] - // [3, 102] - // [4, 101] - // [5, 114] +```js +const buf = new Buffer('buffer'); +for (var pair of buf.entries()) { + console.log(pair); +} +// prints: +// [0, 98] +// [1, 117] +// [2, 102] +// [3, 102] +// [4, 101] +// [5, 114] +``` ### buffer.keys() Creates and returns an [iterator][] of Buffer keys (indices). - const buf = new Buffer('buffer'); - for (var key of buf.keys()) { - console.log(key); - } - // prints: - // 0 - // 1 - // 2 - // 3 - // 4 - // 5 +```js +const buf = new Buffer('buffer'); +for (var key of buf.keys()) { + console.log(key); +} +// prints: +// 0 +// 1 +// 2 +// 3 +// 4 +// 5 +``` ### buffer.values() Creates and returns an [iterator][] for Buffer values (bytes). This function is called automatically when the Buffer is used in a `for..of` statement. - const buf = new Buffer('buffer'); - for (var value of buf.values()) { - console.log(value); - } - // prints: - // 98 - // 117 - // 102 - // 102 - // 101 - // 114 - - for (var value of buf) { - console.log(value); - } - // prints: - // 98 - // 117 - // 102 - // 102 - // 101 - // 114 +```js +const buf = new Buffer('buffer'); +for (var value of buf.values()) { + console.log(value); +} +// prints: +// 98 +// 117 +// 102 +// 102 +// 101 +// 114 + +for (var value of buf) { + console.log(value); +} +// prints: +// 98 +// 117 +// 102 +// 102 +// 101 +// 114 +``` ### buf[index] @@ -376,15 +408,17 @@ range is between `0x00` and `0xFF` (hex) or `0` and `255` (decimal). Example: copy an ASCII string into a Buffer, one byte at a time: - const str = "Node.js"; - const buf = new Buffer(str.length); +```js +const str = "Node.js"; +const buf = new Buffer(str.length); - for (var i = 0; i < str.length ; i++) { - buf[i] = str.charCodeAt(i); - } +for (var i = 0; i < str.length ; i++) { + buf[i] = str.charCodeAt(i); +} - console.log(buf); - // Prints: Node.js +console.log(buf); + // Prints: Node.js +``` ### buf.compare(otherBuffer) @@ -398,7 +432,7 @@ Comparison is based on the actual sequence of bytes in each Buffer. * `1` is returned if `otherBuffer` should come *before* `buf` when sorted. * `-1` is returned if `otherBuffer` should come *after* `buf` when sorted. -``` +```js const buf1 = new Buffer('ABC'); const buf2 = new Buffer('BCD'); const buf3 = new Buffer('ABCD'); @@ -435,30 +469,34 @@ Returns the number of bytes copied. Example: build two Buffers, then copy `buf1` from byte 16 through byte 19 into `buf2`, starting at the 8th byte in `buf2`. - const buf1 = new Buffer(26); - const buf2 = new Buffer(26).fill('!'); +```js +const buf1 = new Buffer(26); +const buf2 = new Buffer(26).fill('!'); - for (var i = 0 ; i < 26 ; i++) { - buf1[i] = i + 97; // 97 is ASCII a - } +for (var i = 0 ; i < 26 ; i++) { + buf1[i] = i + 97; // 97 is ASCII a +} - buf1.copy(buf2, 8, 16, 20); - console.log(buf2.toString('ascii', 0, 25)); - // Prints: !!!!!!!!qrst!!!!!!!!!!!!! +buf1.copy(buf2, 8, 16, 20); +console.log(buf2.toString('ascii', 0, 25)); + // Prints: !!!!!!!!qrst!!!!!!!!!!!!! +``` Example: Build a single Buffer, then copy data from one region to an overlapping region in the same Buffer - const buf = new Buffer(26); +```js +const buf = new Buffer(26); - for (var i = 0 ; i < 26 ; i++) { - buf[i] = i + 97; // 97 is ASCII a - } +for (var i = 0 ; i < 26 ; i++) { + buf[i] = i + 97; // 97 is ASCII a +} - buf.copy(buf, 0, 4, 10); - console.log(buf.toString()); +buf.copy(buf, 0, 4, 10); +console.log(buf.toString()); - // efghijghijklmnopqrstuvwxyz +// efghijghijklmnopqrstuvwxyz +``` ### buf.equals(otherBuffer) @@ -467,14 +505,16 @@ region in the same Buffer Returns a boolean indicating whether `this` and `otherBuffer` have exactly the same bytes. - const buf1 = new Buffer('ABC'); - const buf2 = new Buffer('414243', 'hex'); - const buf3 = new Buffer('ABCD'); +```js +const buf1 = new Buffer('ABC'); +const buf2 = new Buffer('414243', 'hex'); +const buf3 = new Buffer('ABCD'); - console.log(buf1.equals(buf2)); - // Prints: true - console.log(buf1.equals(buf3)); - // Prints: false +console.log(buf1.equals(buf2)); + // Prints: true +console.log(buf1.equals(buf3)); + // Prints: false +``` ### buf.fill(value[, offset][, end]) @@ -486,9 +526,11 @@ Fills the Buffer with the specified value. If the `offset` (defaults to `0`) and `end` (defaults to `buffer.length`) are not given it will fill the entire Buffer. The method returns a reference to the Buffer so calls can be chained. - const b = new Buffer(50).fill('h'); - console.log(b.toString()); - // Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +```js +const b = new Buffer(50).fill('h'); +console.log(b.toString()); + // Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +``` ### buf.indexOf(value[, byteOffset]) @@ -502,20 +544,22 @@ contain `value`. The `value` can be a String, Buffer or Number. Strings are interpreted as UTF8. Buffers will use the entire Buffer (to compare a partial Buffer use [`Buffer#slice()`][]). Numbers can range from 0 to 255. - const buf = new Buffer('this is a buffer'); - - buf.indexOf('this'); - // returns 0 - buf.indexOf('is'); - // returns 2 - buf.indexOf(new Buffer('a buffer')); - // returns 8 - buf.indexOf(97); // ascii for 'a' - // returns 8 - buf.indexOf(new Buffer('a buffer example')); - // returns -1 - buf.indexOf(new Buffer('a buffer example').slice(0,8)); - // returns 8 +```js +const buf = new Buffer('this is a buffer'); + +buf.indexOf('this'); + // returns 0 +buf.indexOf('is'); + // returns 2 +buf.indexOf(new Buffer('a buffer')); + // returns 8 +buf.indexOf(97); // ascii for 'a' + // returns 8 +buf.indexOf(new Buffer('a buffer example')); + // returns -1 +buf.indexOf(new Buffer('a buffer example').slice(0,8)); + // returns 8 +``` ### buf.includes(value[, byteOffset][, encoding]) @@ -529,22 +573,24 @@ or Number. Strings are interpreted as UTF8 unless overridden with the The `byteOffset` indicates the index in `buf` where searching begins. - const buf = new Buffer('this is a buffer'); - - buf.includes('this'); - // returns true - buf.includes('is'); - // returns true - buf.includes(new Buffer('a buffer')); - // returns true - buf.includes(97); // ascii for 'a' - // returns true - buf.includes(new Buffer('a buffer example')); - // returns false - buf.includes(new Buffer('a buffer example').slice(0,8)); - // returns true - buf.includes('this', 4); - // returns false +```js +const buf = new Buffer('this is a buffer'); + +buf.includes('this'); + // returns true +buf.includes('is'); + // returns true +buf.includes(new Buffer('a buffer')); + // returns true +buf.includes(97); // ascii for 'a' + // returns true +buf.includes(new Buffer('a buffer example')); + // returns false +buf.includes(new Buffer('a buffer example').slice(0,8)); + // returns true +buf.includes('this', 4); + // returns false +``` ### buf.length @@ -555,27 +601,31 @@ that this does not necessarily reflect the amount of usable data within the Buffer. For instance, in the example below, a Buffer with 1234 bytes is allocated, but only 11 ASCII bytes are written. - const buf = new Buffer(1234); +```js +const buf = new Buffer(1234); - console.log(buf.length); - // Prints: 1234 +console.log(buf.length); + // Prints: 1234 - buf.write('some string', 0, 'ascii'); - console.log(buf.length); - // Prints: 1234 +buf.write('some string', 0, 'ascii'); +console.log(buf.length); + // Prints: 1234 +``` While the `length` property is not immutable, changing the value of `length` can result in undefined and inconsistent behavior. Applications that wish to modify the length of a Buffer should therefore treat `length` as read-only and use [`buf.slice`][] to create a new Buffer. - const buf = new Buffer(10); - buf.write('abcdefghj', 0, 'ascii'); - console.log(buf.length); - // Prints: 10 - buf = buf.slice(0,5); - console.log(buf.length); - // Prints: 5 +```js +const buf = new Buffer(10); +buf.write('abcdefghj', 0, 'ascii'); +console.log(buf.length); + // Prints: 10 +buf = buf.slice(0,5); +console.log(buf.length); + // Prints: 5 +``` ### buf.readDoubleBE(offset[, noAssert]) ### buf.readDoubleLE(offset[, noAssert]) @@ -592,17 +642,19 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. When not specified, `noAssert` defaults to `false`. - const buf = new Buffer([1,2,3,4,5,6,7,8]); +```js +const buf = new Buffer([1,2,3,4,5,6,7,8]); - buf.readDoubleBE(); - // Returns: 8.20788039913184e-304 - buf.readDoubleLE(); - // Returns: 5.447603722011605e-270 - buf.readDoubleLE(1); - // throws RangeError: Index out of range +buf.readDoubleBE(); + // Returns: 8.20788039913184e-304 +buf.readDoubleLE(); + // Returns: 5.447603722011605e-270 +buf.readDoubleLE(1); + // throws RangeError: Index out of range - buf.readDoubleLE(1, true); // Warning: reads passed end of buffer! - // Segmentation fault! don't do this! +buf.readDoubleLE(1, true); // Warning: reads passed end of buffer! + // Segmentation fault! don't do this! +``` ### buf.readFloatBE(offset[, noAssert]) ### buf.readFloatLE(offset[, noAssert]) @@ -619,17 +671,19 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. When not specified, `noAssert` defaults to `false`. - const buf = new Buffer([1,2,3,4]); +```js +const buf = new Buffer([1,2,3,4]); - buf.readFloatBE(); - // Returns: 2.387939260590663e-38 - buf.readFloatLE(); - // Returns: 1.539989614439558e-36 - buf.readFloatLE(1); - // throws RangeError: Index out of range +buf.readFloatBE(); + // Returns: 2.387939260590663e-38 +buf.readFloatLE(); + // Returns: 1.539989614439558e-36 +buf.readFloatLE(1); + // throws RangeError: Index out of range - buf.readFloatLE(1, true); // Warning: reads passed end of buffer! - // Segmentation fault! don't do this! +buf.readFloatLE(1, true); // Warning: reads passed end of buffer! + // Segmentation fault! don't do this! +``` ### buf.readInt8(offset[, noAssert]) @@ -645,12 +699,14 @@ defaults to `false`. Integers read from the Buffer are interpreted as two's complement signed values. - const buf = new Buffer([1,-2,3,4]); +```js +const buf = new Buffer([1,-2,3,4]); - buf.readInt8(0); - // returns 1 - buf.readInt8(1); - // returns -2 +buf.readInt8(0); + // returns 1 +buf.readInt8(1); + // returns -2 +``` ### buf.readInt16BE(offset[, noAssert]) ### buf.readInt16LE(offset[, noAssert]) @@ -669,12 +725,14 @@ defaults to `false`. Integers read from the Buffer are interpreted as two's complement signed values. - const buf = new Buffer([1,-2,3,4]); +```js +const buf = new Buffer([1,-2,3,4]); - buf.readInt16BE(); - // returns 510 - buf.readInt16LE(1); - // returns -511 +buf.readInt16BE(); + // returns 510 +buf.readInt16LE(1); + // returns -511 +``` ### buf.readInt32BE(offset[, noAssert]) ### buf.readInt32LE(offset[, noAssert]) @@ -693,12 +751,14 @@ defaults to `false`. Integers read from the Buffer are interpreted as two's complement signed values. - const buf = new Buffer([1,-2,3,4]); +```js +const buf = new Buffer([1,-2,3,4]); - buf.readInt32BE(); - // returns 33424132 - buf.readInt32LE(1); - // returns 67370497 +buf.readInt32BE(); + // returns 33424132 +buf.readInt32LE(1); + // returns 67370497 +``` ### buf.readIntBE(offset, byteLength[, noAssert]) ### buf.readIntLE(offset, byteLength[, noAssert]) @@ -712,14 +772,16 @@ Reads `byteLength` number of bytes from the Buffer at the specified `offset` and interprets the result as a two's complement signed value. Supports up to 48 bits of accuracy. For example: - const buf = new Buffer(6); - buf.writeUInt16LE(0x90ab, 0); - buf.writeUInt32LE(0x12345678, 2); - buf.readIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) - // Returns: '1234567890ab' +```js +const buf = new Buffer(6); +buf.writeUInt16LE(0x90ab, 0); +buf.writeUInt32LE(0x12345678, 2); +buf.readIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) +// Returns: '1234567890ab' - buf.readIntBE(0, 6).toString(16); - // Returns: -546f87a9cbee +buf.readIntBE(0, 6).toString(16); +// Returns: -546f87a9cbee +``` Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. When not specified, `noAssert` @@ -737,12 +799,14 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. When not specified, `noAssert` defaults to `false`. - const buf = new Buffer([1,-2,3,4]); +```js +const buf = new Buffer([1,-2,3,4]); - buf.readUInt8(0); - // returns 1 - buf.readUInt8(1); - // returns 254 +buf.readUInt8(0); + // returns 1 +buf.readUInt8(1); + // returns 254 +``` ### buf.readUInt16BE(offset[, noAssert]) ### buf.readUInt16LE(offset[, noAssert]) @@ -761,20 +825,22 @@ defaults to `false`. Example: - const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); - - buf.readUInt16BE(0); - // Returns: 0x0304 - buf.readUInt16LE(0); - // Returns: 0x0403 - buf.readUInt16BE(1); - // Returns: 0x0423 - buf.readUInt16LE(1); - // Returns: 0x2304 - buf.readUInt16BE(2); - // Returns: 0x2342 - buf.readUInt16LE(2); - // Returns: 0x4223 +```js +const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); + +buf.readUInt16BE(0); + // Returns: 0x0304 +buf.readUInt16LE(0); + // Returns: 0x0403 +buf.readUInt16BE(1); + // Returns: 0x0423 +buf.readUInt16LE(1); + // Returns: 0x2304 +buf.readUInt16BE(2); + // Returns: 0x2342 +buf.readUInt16LE(2); + // Returns: 0x4223 +``` ### buf.readUInt32BE(offset[, noAssert]) ### buf.readUInt32LE(offset[, noAssert]) @@ -793,12 +859,14 @@ defaults to `false`. Example: - const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); +```js +const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); - buf.readUInt32BE(0); - // Returns: 0x03042342 - console.log(buf.readUInt32LE(0)); - // Returns: 0x42230403 +buf.readUInt32BE(0); + // Returns: 0x03042342 +console.log(buf.readUInt32LE(0)); + // Returns: 0x42230403 +``` ### buf.readUIntBE(offset, byteLength[, noAssert]) ### buf.readUIntLE(offset, byteLength[, noAssert]) @@ -812,14 +880,16 @@ Reads `byteLength` number of bytes from the Buffer at the specified `offset` and interprets the result as an unsigned integer. Supports up to 48 bits of accuracy. For example: - const buf = new Buffer(6); - buf.writeUInt16LE(0x90ab, 0); - buf.writeUInt32LE(0x12345678, 2); - buf.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) - // Returns: '1234567890ab' +```js +const buf = new Buffer(6); +buf.writeUInt16LE(0x90ab, 0); +buf.writeUInt32LE(0x12345678, 2); +buf.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) +// Returns: '1234567890ab' - buf.readUIntBE(0, 6).toString(16); - // Returns: ab9078563412 +buf.readUIntBE(0, 6).toString(16); +// Returns: ab9078563412 +``` Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. When not specified, `noAssert` @@ -839,30 +909,34 @@ and cropped by the `start` (defaults to `0`) and `end` (defaults to Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte from the original Buffer. - const buf1 = new Buffer(26); +```js +const buf1 = new Buffer(26); - for (var i = 0 ; i < 26 ; i++) { - buf1[i] = i + 97; // 97 is ASCII a - } +for (var i = 0 ; i < 26 ; i++) { + buf1[i] = i + 97; // 97 is ASCII a +} - const buf2 = buf1.slice(0, 3); - buf2.toString('ascii', 0, buf2.length); - // Returns: 'abc' - buf1[0] = 33; - buf2.toString('ascii', 0, buf2.length); - // Returns : '!bc' +const buf2 = buf1.slice(0, 3); +buf2.toString('ascii', 0, buf2.length); + // Returns: 'abc' +buf1[0] = 33; +buf2.toString('ascii', 0, buf2.length); + // Returns : '!bc' +``` Specifying negative indexes causes the slice to be generated relative to the end of the Buffer rather than the beginning. - const buf = new Buffer('buffer'); +```js +const buf = new Buffer('buffer'); - buf.slice(-6, -1).toString(); - // Returns 'buffe', equivalent to buf.slice(0, 5) - buf.slice(-6, -2).toString(); - // Returns 'buff', equivalent to buf.slice(0, 4) - buf.slice(-5, -2).toString(); - // Returns 'uff', equivalent to buf.slice(1, 4) +buf.slice(-6, -1).toString(); + // Returns 'buffe', equivalent to buf.slice(0, 5) +buf.slice(-6, -2).toString(); + // Returns 'buff', equivalent to buf.slice(0, 4) +buf.slice(-5, -2).toString(); + // Returns 'uff', equivalent to buf.slice(1, 4) +``` ### buf.toString([encoding][, start][, end]) @@ -875,18 +949,20 @@ character set `encoding`. If `encoding` is `undefined` or `null`, then `encoding` defaults to `'utf8'`. The `start` and `end` parameters default to `0` and `buffer.length` when `undefined`. - const buf = new Buffer(26); - for (var i = 0 ; i < 26 ; i++) { - buf[i] = i + 97; // 97 is ASCII a - } - buf.toString('ascii'); - // Returns: 'abcdefghijklmnopqrstuvwxyz' - buf.toString('ascii',0,5); - // Returns: 'abcde' - buf.toString('utf8',0,5); - // Returns: 'abcde' - buf.toString(undefined,0,5); - // Returns: 'abcde', encoding defaults to 'utf8' +```js +const buf = new Buffer(26); +for (var i = 0 ; i < 26 ; i++) { + buf[i] = i + 97; // 97 is ASCII a +} +buf.toString('ascii'); + // Returns: 'abcdefghijklmnopqrstuvwxyz' +buf.toString('ascii',0,5); + // Returns: 'abcde' +buf.toString('utf8',0,5); + // Returns: 'abcde' +buf.toString(undefined,0,5); + // Returns: 'abcde', encoding defaults to 'utf8' +``` ### buf.toJSON() @@ -895,20 +971,22 @@ implicitly calls this function when stringifying a Buffer instance. Example: - const buf = new Buffer('test'); - const json = JSON.stringify(buf); +```js +const buf = new Buffer('test'); +const json = JSON.stringify(buf); - console.log(json); - // Prints: '{"type":"Buffer","data":[116,101,115,116]}' +console.log(json); +// Prints: '{"type":"Buffer","data":[116,101,115,116]}' - const copy = JSON.parse(json, (key, value) => { - return value && value.type === 'Buffer' - ? new Buffer(value.data) - : value; - }); +const copy = JSON.parse(json, (key, value) => { + return value && value.type === 'Buffer' + ? new Buffer(value.data) + : value; + }); - console.log(copy.toString()); - // Prints: 'test' +console.log(copy.toString()); +// Prints: 'test' +``` ### buf.write(string[, offset][, length][, encoding]) @@ -925,10 +1003,12 @@ space to fit the entire string, only a partial amount of the string will be written however, the will not write only partially encoded characters. The return value indicates the number of octets written. - const buf = new Buffer(256); - const len = buf.write('\u00bd + \u00bc = \u00be', 0); - console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); - // Prints: 12 bytes: ½ + ¼ = ¾ +```js +const buf = new Buffer(256); +const len = buf.write('\u00bd + \u00bc = \u00be', 0); +console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); + // Prints: 12 bytes: ½ + ¼ = ¾ +``` ### buf.writeDoubleBE(value, offset[, noAssert]) ### buf.writeDoubleLE(value, offset[, noAssert]) @@ -948,16 +1028,18 @@ should not be used unless you are certain of correctness. Defaults to `false`. Example: - const buf = new Buffer(8); - buf.writeDoubleBE(0xdeadbeefcafebabe, 0); +```js +const buf = new Buffer(8); +buf.writeDoubleBE(0xdeadbeefcafebabe, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: - buf.writeDoubleLE(0xdeadbeefcafebabe, 0); +buf.writeDoubleLE(0xdeadbeefcafebabe, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### buf.writeFloatBE(value, offset[, noAssert]) ### buf.writeFloatLE(value, offset[, noAssert]) @@ -978,16 +1060,18 @@ should not be used unless you are certain of correctness. Defaults to `false`. Example: - const buf = new Buffer(4); - buf.writeFloatBE(0xcafebabe, 0); +```js +const buf = new Buffer(4); +buf.writeFloatBE(0xcafebabe, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: - buf.writeFloatLE(0xcafebabe, 0); +buf.writeFloatLE(0xcafebabe, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### buf.writeInt8(value, offset[, noAssert]) @@ -1005,11 +1089,13 @@ should not be used unless you are certain of correctness. Defaults to `false`. The `value` is interpreted and written as a two's complement signed integer. - const buf = new Buffer(2); - buf.writeInt8(2, 0); - buf.writeInt8(-2, 1); - console.log(buf); - // Prints: +```js +const buf = new Buffer(2); +buf.writeInt8(2, 0); +buf.writeInt8(-2, 1); +console.log(buf); + // Prints: +``` ### buf.writeInt16BE(value, offset[, noAssert]) ### buf.writeInt16LE(value, offset[, noAssert]) @@ -1029,11 +1115,13 @@ should not be used unless you are certain of correctness. Defaults to `false`. The `value` is interpreted and written as a two's complement signed integer. - const buf = new Buffer(4); - buf.writeInt16BE(0x0102,0); - buf.writeInt16LE(0x0304,2); - console.log(buf); - // Prints: +```js +const buf = new Buffer(4); +buf.writeInt16BE(0x0102,0); +buf.writeInt16LE(0x0304,2); +console.log(buf); + // Prints: +``` ### buf.writeInt32BE(value, offset[, noAssert]) ### buf.writeInt32LE(value, offset[, noAssert]) @@ -1053,11 +1141,13 @@ should not be used unless you are certain of correctness. Defaults to `false`. The `value` is interpreted and written as a two's complement signed integer. - const buf = new Buffer(8); - buf.writeInt32BE(0x01020304,0); - buf.writeInt32LE(0x05060708,4); - console.log(buf); - // Prints: +```js +const buf = new Buffer(8); +buf.writeInt32BE(0x01020304,0); +buf.writeInt32LE(0x05060708,4); +console.log(buf); + // Prints: +``` ### buf.writeIntBE(value, offset, byteLength[, noAssert]) ### buf.writeIntLE(value, offset, byteLength[, noAssert]) @@ -1071,15 +1161,17 @@ The `value` is interpreted and written as a two's complement signed integer. Writes `value` to the Buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: - const buf1 = new Buffer(6); - buf1.writeUIntBE(0x1234567890ab, 0, 6); - console.log(buf1); - // Prints: +```js +const buf1 = new Buffer(6); +buf1.writeUIntBE(0x1234567890ab, 0, 6); +console.log(buf1); + // Prints: - const buf2 = new Buffer(6); - buf2.writeUIntLE(0x1234567890ab, 0, 6); - console.log(buf2); - // Prints: +const buf2 = new Buffer(6); +buf2.writeUIntLE(0x1234567890ab, 0, 6); +console.log(buf2); + // Prints: +``` Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be @@ -1102,14 +1194,16 @@ should not be used unless you are certain of correctness. Defaults to `false`. Example: - const buf = new Buffer(4); - buf.writeUInt8(0x3, 0); - buf.writeUInt8(0x4, 1); - buf.writeUInt8(0x23, 2); - buf.writeUInt8(0x42, 3); +```js +const buf = new Buffer(4); +buf.writeUInt8(0x3, 0); +buf.writeUInt8(0x4, 1); +buf.writeUInt8(0x23, 2); +buf.writeUInt8(0x42, 3); - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### buf.writeUInt16BE(value, offset[, noAssert]) ### buf.writeUInt16LE(value, offset[, noAssert]) @@ -1129,18 +1223,20 @@ should not be used unless you are certain of correctness. Defaults to `false`. Example: - const buf = new Buffer(4); - buf.writeUInt16BE(0xdead, 0); - buf.writeUInt16BE(0xbeef, 2); +```js +const buf = new Buffer(4); +buf.writeUInt16BE(0xdead, 0); +buf.writeUInt16BE(0xbeef, 2); - console.log(buf); - // Prints: +console.log(buf); + // Prints: - buf.writeUInt16LE(0xdead, 0); - buf.writeUInt16LE(0xbeef, 2); +buf.writeUInt16LE(0xdead, 0); +buf.writeUInt16LE(0xbeef, 2); - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### buf.writeUInt32BE(value, offset[, noAssert]) ### buf.writeUInt32LE(value, offset[, noAssert]) @@ -1160,16 +1256,18 @@ should not be used unless you are certain of correctness. Defaults to `false`. Example: - const buf = new Buffer(4); - buf.writeUInt32BE(0xfeedface, 0); +```js +const buf = new Buffer(4); +buf.writeUInt32BE(0xfeedface, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: - buf.writeUInt32LE(0xfeedface, 0); +buf.writeUInt32LE(0xfeedface, 0); - console.log(buf); - // Prints: +console.log(buf); + // Prints: +``` ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) ### buf.writeUIntLE(value, offset, byteLength[, noAssert]) @@ -1183,10 +1281,12 @@ Example: Writes `value` to the Buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: - const buf = new Buffer(6); - buf.writeUIntBE(0x1234567890ab, 0, 6); - console.log(buf); - // Prints: +```js +const buf = new Buffer(6); +buf.writeUIntBE(0x1234567890ab, 0, 6); +console.log(buf); + // Prints: +``` Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be @@ -1217,17 +1317,19 @@ In the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using `SlowBuffer` then copy out the relevant bits. - // need to keep around a few small chunks of memory - const store = []; - - socket.on('readable', () => { - var data = socket.read(); - // allocate for retained data - var sb = new SlowBuffer(10); - // copy the data into the new allocation - data.copy(sb, 0, 0, 10); - store.push(sb); - }); +```js +// need to keep around a few small chunks of memory +const store = []; + +socket.on('readable', () => { + var data = socket.read(); + // allocate for retained data + var sb = new SlowBuffer(10); + // copy the data into the new allocation + data.copy(sb, 0, 0, 10); + store.push(sb); +}); +``` Use of `SlowBuffer` should be used only as a last resort *after* a developer has observed undue memory retention in their applications. diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown index 18f37502ac..a47d4d8349 100644 --- a/doc/api/child_process.markdown +++ b/doc/api/child_process.markdown @@ -6,20 +6,22 @@ The `child_process` module provides the ability to spawn child processes in a manner that is similar, but not identical, to [`popen(3)`][]. This capability is primarily provided by the `child_process.spawn()` function: - const spawn = require('child_process').spawn; - const ls = spawn('ls', ['-lh', '/usr']); +```js +const spawn = require('child_process').spawn; +const ls = spawn('ls', ['-lh', '/usr']); - ls.stdout.on('data', (data) => { - console.log(`stdout: ${data}`); - }); +ls.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); +}); - ls.stderr.on('data', (data) => { - console.log(`stderr: ${data}`); - }); +ls.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); +}); - ls.on('close', (code) => { - console.log(`child process exited with code ${code}`); - }); +ls.on('close', (code) => { + console.log(`child process exited with code ${code}`); +}); +``` By default, pipes for `stdin`, `stdout` and `stderr` are established between the parent Node.js process and the spawned child. It is possible to stream data @@ -81,31 +83,33 @@ When running on Windows, `.bat` and `.cmd` files can only be invoked using either `child_process.exec()` or by spawning `cmd.exe` and passing the `.bat` or `.cmd` file as an argument (which is what `child_process.exec()` does). - // On Windows Only ... - const spawn = require('child_process').spawn; - const bat = spawn('cmd.exe', ['/c', 'my.bat']); - - bat.stdout.on('data', (data) => { - console.log(data); - }); - - bat.stderr.on('data', (data) => { - console.log(data); - }); - - bat.on('exit', (code) => { - console.log(`Child exited with code ${code}`); - }); - - // OR... - const exec = require('child_process').exec; - exec('my.bat', (err, stdout, stderr) => { - if (err) { - console.error(err); - return; - } - console.log(stdout); - }); +```js +// On Windows Only ... +const spawn = require('child_process').spawn; +const bat = spawn('cmd.exe', ['/c', 'my.bat']); + +bat.stdout.on('data', (data) => { + console.log(data); +}); + +bat.stderr.on('data', (data) => { + console.log(data); +}); + +bat.on('exit', (code) => { + console.log(`Child exited with code ${code}`); +}); + +// OR... +const exec = require('child_process').exec; +exec('my.bat', (err, stdout, stderr) => { + if (err) { + console.error(err); + return; + } + console.log(stdout); +}); +``` ### child_process.exec(command[, options][, callback]) @@ -133,15 +137,17 @@ or `.cmd` file as an argument (which is what `child_process.exec()` does). Spawns a shell then executes the `command` within that shell, buffering any generated output. - const exec = require('child_process').exec; - const child = exec('cat *.js bad_file | wc -l', - (error, stdout, stderr) => { - console.log(`stdout: ${stdout}`); - console.log(`stderr: ${stderr}`); - if (error !== null) { - console.log(`exec error: ${error}`); - } - }); +```js +const exec = require('child_process').exec; +const child = exec('cat *.js bad_file | wc -l', + (error, stdout, stderr) => { + console.log(`stdout: ${stdout}`); + console.log(`stderr: ${stderr}`); + if (error !== null) { + console.log(`exec error: ${error}`); + } +}); +``` If a `callback` function is provided, it is called with the arguments `(error, stdout, stderr)`. On success, `error` will be `null`. On error, @@ -153,14 +159,16 @@ to be an error. The `options` argument may be passed as the second argument to customize how the process is spawned. The default options are: - { - encoding: 'utf8', - timeout: 0, - maxBuffer: 200*1024, - killSignal: 'SIGTERM', - cwd: null, - env: null - } +```js +{ + encoding: 'utf8', + timeout: 0, + maxBuffer: 200*1024, + killSignal: 'SIGTERM', + cwd: null, + env: null +} +``` If `timeout` is greater than `0`, the parent will send the the signal identified by the `killSignal` property (the default is `'SIGTERM'`) if the @@ -201,13 +209,15 @@ is spawned directly as a new process making it slightly more efficient than The same options as `child_process.exec()` are supported. Since a shell is not spawned, behaviors such as I/O redirection and file globbing are not supported. - const execFile = require('child_process').execFile; - const child = execFile('node', ['--version'], (error, stdout, stderr) => { - if (error) { - throw error; - } - console.log(stdout); - }); +```js +const execFile = require('child_process').execFile; +const child = execFile('node', ['--version'], (error, stdout, stderr) => { + if (error) { + throw error; + } + console.log(stdout); +}); +``` ### child_process.fork(modulePath[, args][, options]) @@ -275,10 +285,12 @@ to an empty array. A third argument may be used to specify additional options, with these defaults: - { - cwd: undefined, - env: process.env - } +```js +{ + cwd: undefined, + env: process.env +} +``` Use `cwd` to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory. @@ -289,66 +301,72 @@ process, the default is `process.env`. Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code: - const spawn = require('child_process').spawn; - const ls = spawn('ls', ['-lh', '/usr']); +```js +const spawn = require('child_process').spawn; +const ls = spawn('ls', ['-lh', '/usr']); - ls.stdout.on('data', (data) => { - console.log(`stdout: ${data}`); - }); +ls.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); +}); - ls.stderr.on('data', (data) => { - console.log(`stderr: ${data}`); - }); +ls.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); +}); - ls.on('close', (code) => { - console.log(`child process exited with code ${code}`); - }); +ls.on('close', (code) => { + console.log(`child process exited with code ${code}`); +}); +``` Example: A very elaborate way to run 'ps ax | grep ssh' - const spawn = require('child_process').spawn; - const ps = spawn('ps', ['ax']); - const grep = spawn('grep', ['ssh']); +```js +const spawn = require('child_process').spawn; +const ps = spawn('ps', ['ax']); +const grep = spawn('grep', ['ssh']); - ps.stdout.on('data', (data) => { - grep.stdin.write(data); - }); +ps.stdout.on('data', (data) => { + grep.stdin.write(data); +}); - ps.stderr.on('data', (data) => { - console.log(`ps stderr: ${data}`); - }); +ps.stderr.on('data', (data) => { + console.log(`ps stderr: ${data}`); +}); - ps.on('close', (code) => { - if (code !== 0) { - console.log(`ps process exited with code ${code}`); - } - grep.stdin.end(); - }); +ps.on('close', (code) => { + if (code !== 0) { + console.log(`ps process exited with code ${code}`); + } + grep.stdin.end(); +}); - grep.stdout.on('data', (data) => { - console.log(`${data}`); - }); +grep.stdout.on('data', (data) => { + console.log(`${data}`); +}); - grep.stderr.on('data', (data) => { - console.log(`grep stderr: ${data}`); - }); +grep.stderr.on('data', (data) => { + console.log(`grep stderr: ${data}`); +}); - grep.on('close', (code) => { - if (code !== 0) { - console.log(`grep process exited with code ${code}`); - } - }); +grep.on('close', (code) => { + if (code !== 0) { + console.log(`grep process exited with code ${code}`); + } +}); +``` Example of checking for failed exec: - const spawn = require('child_process').spawn; - const child = spawn('bad_command'); +```js +const spawn = require('child_process').spawn; +const child = spawn('bad_command'); - child.on('error', (err) => { - console.log('Failed to start child process.'); - }); +child.on('error', (err) => { + console.log('Failed to start child process.'); +}); +``` #### options.detached @@ -371,17 +389,19 @@ there is an established IPC channel between the child and parent. Example of detaching a long-running process and redirecting its output to a file: - const fs = require('fs'); - const spawn = require('child_process').spawn; - const out = fs.openSync('./out.log', 'a'); - const err = fs.openSync('./out.log', 'a'); +```js +const fs = require('fs'); +const spawn = require('child_process').spawn; +const out = fs.openSync('./out.log', 'a'); +const err = fs.openSync('./out.log', 'a'); - const child = spawn('prg', [], { - detached: true, - stdio: [ 'ignore', out, err ] - }); +const child = spawn('prg', [], { + detached: true, + stdio: [ 'ignore', out, err ] +}); - child.unref(); +child.unref(); +``` When using the `detached` option to start a long-running process, the process will not stay running in the background after the parent exits unless it is @@ -441,17 +461,19 @@ pipes between the parent and child. The value is one of the following: Example: - const spawn = require('child_process').spawn; +```js +const spawn = require('child_process').spawn; - // Child will use parent's stdios - spawn('prg', [], { stdio: 'inherit' }); +// Child will use parent's stdios +spawn('prg', [], { stdio: 'inherit' }); - // Spawn child sharing only stderr - spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] }); +// Spawn child sharing only stderr +spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] }); - // Open an extra fd=4, to interact with programs presenting a - // startd-style interface. - spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); +// Open an extra fd=4, to interact with programs presenting a +// startd-style interface. +spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); +``` *It is worth noting that when an IPC channel is established between the parent and child processes, and the child is a Node.js process, the child @@ -679,16 +701,18 @@ The `child.kill()` methods sends a signal to the child process. If no argument is given, the process will be sent the `'SIGTERM'` signal. See `signal(7)` for a list of available signals. - const spawn = require('child_process').spawn; - const grep = spawn('grep', ['ssh']); +```js +const spawn = require('child_process').spawn; +const grep = spawn('grep', ['ssh']); - grep.on('close', (code, signal) => { - console.log( - `child process terminated due to receipt of signal ${signal}`); - }); +grep.on('close', (code, signal) => { + console.log( + `child process terminated due to receipt of signal ${signal}`); +}); - // Send SIGHUP to process - grep.kill('SIGHUP'); +// Send SIGHUP to process +grep.kill('SIGHUP'); +``` The `ChildProcess` object may emit an `'error'` event if the signal cannot be delivered. Sending a signal to a child process that has already exited is not @@ -709,11 +733,13 @@ Returns the process identifier (PID) of the child process. Example: - const spawn = require('child_process').spawn; - const grep = spawn('grep', ['ssh']); +```js +const spawn = require('child_process').spawn; +const grep = spawn('grep', ['ssh']); - console.log(`Spawned child pid: ${grep.pid}`); - grep.stdin.end(); +console.log(`Spawned child pid: ${grep.pid}`); +grep.stdin.end(); +``` ### child.send(message[, sendHandle][, callback]) @@ -729,22 +755,26 @@ instance, these messages can be received via the `process.on('message')` event. For example, in the parent script: - const cp = require('child_process'); - const n = cp.fork(`${__dirname}/sub.js`); +```js +const cp = require('child_process'); +const n = cp.fork(`${__dirname}/sub.js`); - n.on('message', (m) => { - console.log('PARENT got message:', m); - }); +n.on('message', (m) => { + console.log('PARENT got message:', m); +}); - n.send({ hello: 'world' }); +n.send({ hello: 'world' }); +``` And then the child script, `'sub.js'` might look like this: - process.on('message', (m) => { - console.log('CHILD got message:', m); - }); +```js +process.on('message', (m) => { + console.log('CHILD got message:', m); +}); - process.send({ foo: 'bar' }); +process.send({ foo: 'bar' }); +``` Child Node.js processes will have a `process.send()` method of their own that allows the child to send messages back to the parent. @@ -780,26 +810,30 @@ used to implement flow control. The `sendHandle` argument can be used, for instance, to pass the handle of a TSCP server object to the child process as illustrated in the example below: - const child = require('child_process').fork('child.js'); +```js +const child = require('child_process').fork('child.js'); - // Open up the server object and send the handle. - const server = require('net').createServer(); - server.on('connection', (socket) => { - socket.end('handled by parent'); - }); - server.listen(1337, () => { - child.send('server', server); - }); +// Open up the server object and send the handle. +const server = require('net').createServer(); +server.on('connection', (socket) => { + socket.end('handled by parent'); +}); +server.listen(1337, () => { + child.send('server', server); +}); +``` The child would then receive the server object as: - process.on('message', (m, server) => { - if (m === 'server') { - server.on('connection', (socket) => { - socket.end('handled by child'); - }); - } +```js +process.on('message', (m, server) => { + if (m === 'server') { + server.on('connection', (socket) => { + socket.end('handled by child'); }); + } +}); +``` Once the server is now shared between the parent and child, some connections can be handled by the parent and some by the child. @@ -815,31 +849,35 @@ Similarly, the `sendHandler` argument can be used to pass the handle of a socket to the child process. The example below spawns two children that each handle connections with "normal" or "special" priority: - const normal = require('child_process').fork('child.js', ['normal']); - const special = require('child_process').fork('child.js', ['special']); - - // Open up the server and send sockets to child - const server = require('net').createServer(); - server.on('connection', (socket) => { - - // If this is special priority - if (socket.remoteAddress === '74.125.127.100') { - special.send('socket', socket); - return; - } - // This is normal priority - normal.send('socket', socket); - }); - server.listen(1337); +```js +const normal = require('child_process').fork('child.js', ['normal']); +const special = require('child_process').fork('child.js', ['special']); + +// Open up the server and send sockets to child +const server = require('net').createServer(); +server.on('connection', (socket) => { + + // If this is special priority + if (socket.remoteAddress === '74.125.127.100') { + special.send('socket', socket); + return; + } + // This is normal priority + normal.send('socket', socket); +}); +server.listen(1337); +``` The `child.js` would receive the socket handle as the second argument passed to the event callback function: - process.on('message', (m, socket) => { - if (m === 'socket') { - socket.end(`Request handled with ${process.argv[2]} priority`); - } - }); +```js +process.on('message', (m, socket) => { + if (m === 'socket') { + socket.end(`Request handled with ${process.argv[2]} priority`); + } +}); +``` Once a socket has been passed to a child, the parent is no longer capable of tracking when the socket is destroyed. To indicate this, the `.connections` @@ -887,26 +925,28 @@ In the following example, only the child's fd `1` (stdout) is configured as a pipe, so only the parent's `child.stdio[1]` is a stream, all other values in the array are `null`. - const assert = require('assert'); - const fs = require('fs'); - const child_process = require('child_process'); +```js +const assert = require('assert'); +const fs = require('fs'); +const child_process = require('child_process'); - const child = child_process.spawn('ls', { - stdio: [ - 0, // Use parents stdin for child - 'pipe', // Pipe child's stdout to parent - fs.openSync('err.out', 'w') // Direct child's stderr to a file - ] - }); +const child = child_process.spawn('ls', { + stdio: [ + 0, // Use parents stdin for child + 'pipe', // Pipe child's stdout to parent + fs.openSync('err.out', 'w') // Direct child's stderr to a file + ] +}); - assert.equal(child.stdio[0], null); - assert.equal(child.stdio[0], child.stdin); +assert.equal(child.stdio[0], null); +assert.equal(child.stdio[0], child.stdin); - assert(child.stdout); - assert.equal(child.stdio[1], child.stdout); +assert(child.stdout); +assert.equal(child.stdio[1], child.stdout); - assert.equal(child.stdio[2], null); - assert.equal(child.stdio[2], child.stderr); +assert.equal(child.stdio[2], null); +assert.equal(child.stdio[2], child.stderr); +``` ### child.stdout diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index b29c13694b..554bedcf08 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -9,35 +9,39 @@ processes to handle the load. The cluster module allows you to easily create child processes that all share server ports. - const cluster = require('cluster'); - const http = require('http'); - const numCPUs = require('os').cpus().length; - - if (cluster.isMaster) { - // Fork workers. - for (var i = 0; i < numCPUs; i++) { - cluster.fork(); - } - - cluster.on('exit', (worker, code, signal) => { - console.log(`worker ${worker.process.pid} died`); - }); - } else { - // Workers can share any TCP connection - // In this case it is an HTTP server - http.createServer((req, res) => { - res.writeHead(200); - res.end('hello world\n'); - }).listen(8000); - } +```js +const cluster = require('cluster'); +const http = require('http'); +const numCPUs = require('os').cpus().length; + +if (cluster.isMaster) { + // Fork workers. + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('exit', (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`); + }); +} else { + // Workers can share any TCP connection + // In this case it is an HTTP server + http.createServer((req, res) => { + res.writeHead(200); + res.end('hello world\n'); + }).listen(8000); +} +``` Running Node.js will now share port 8000 between the workers: - % NODE_DEBUG=cluster node server.js - 23521,Master Worker 23524 online - 23521,Master Worker 23526 online - 23521,Master Worker 23523 online - 23521,Master Worker 23528 online +``` +% NODE_DEBUG=cluster node server.js +23521,Master Worker 23524 online +23521,Master Worker 23526 online +23521,Master Worker 23523 online +23521,Master Worker 23528 online +``` Please note that, on Windows, it is not yet possible to set up a named pipe server in a worker. @@ -113,9 +117,11 @@ it can be obtained using `cluster.worker`. Similar to the `cluster.on('disconnect')` event, but specific to this worker. - cluster.fork().on('disconnect', () => { - // Worker has disconnected - }); +```js +cluster.fork().on('disconnect', () => { + // Worker has disconnected +}); +``` ### Event: 'error' @@ -131,16 +137,18 @@ In a worker you can also use `process.on('error')`. Similar to the `cluster.on('exit')` event, but specific to this worker. - const worker = cluster.fork(); - worker.on('exit', (code, signal) => { - if( signal ) { - console.log(`worker was killed by signal: ${signal}`); - } else if( code !== 0 ) { - console.log(`worker exited with error code: ${code}`); - } else { - console.log('worker success!'); - } - }); +```js +const worker = cluster.fork(); +worker.on('exit', (code, signal) => { + if( signal ) { + console.log(`worker was killed by signal: ${signal}`); + } else if( code !== 0 ) { + console.log(`worker exited with error code: ${code}`); + } else { + console.log('worker success!'); + } +}); +``` ### Event: 'listening' @@ -148,9 +156,11 @@ Similar to the `cluster.on('exit')` event, but specific to this worker. Similar to the `cluster.on('listening')` event, but specific to this worker. - cluster.fork().on('listening', (address) => { - // Worker is listening - }); +```js +cluster.fork().on('listening', (address) => { + // Worker is listening +}); +``` It is not emitted in the worker. @@ -167,53 +177,57 @@ In a worker you can also use `process.on('message')`. As an example, here is a cluster that keeps count of the number of requests in the master process using the message system: - const cluster = require('cluster'); - const http = require('http'); +```js +const cluster = require('cluster'); +const http = require('http'); - if (cluster.isMaster) { +if (cluster.isMaster) { - // Keep track of http requests - var numReqs = 0; - setInterval(() => { - console.log('numReqs =', numReqs); - }, 1000); + // Keep track of http requests + var numReqs = 0; + setInterval(() => { + console.log('numReqs =', numReqs); + }, 1000); - // Count requests - function messageHandler(msg) { - if (msg.cmd && msg.cmd == 'notifyRequest') { - numReqs += 1; - } - } + // Count requests + function messageHandler(msg) { + if (msg.cmd && msg.cmd == 'notifyRequest') { + numReqs += 1; + } + } - // Start workers and listen for messages containing notifyRequest - const numCPUs = require('os').cpus().length; - for (var i = 0; i < numCPUs; i++) { - cluster.fork(); - } + // Start workers and listen for messages containing notifyRequest + const numCPUs = require('os').cpus().length; + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } - Object.keys(cluster.workers).forEach((id) => { - cluster.workers[id].on('message', messageHandler); - }); + Object.keys(cluster.workers).forEach((id) => { + cluster.workers[id].on('message', messageHandler); + }); - } else { +} else { - // Worker processes have a http server. - http.Server((req, res) => { - res.writeHead(200); - res.end('hello world\n'); + // Worker processes have a http server. + http.Server((req, res) => { + res.writeHead(200); + res.end('hello world\n'); - // notify master about the request - process.send({ cmd: 'notifyRequest' }); - }).listen(8000); - } + // notify master about the request + process.send({ cmd: 'notifyRequest' }); + }).listen(8000); +} +``` ### Event: 'online' Similar to the `cluster.on('online')` event, but specific to this worker. - cluster.fork().on('online', () => { - // Worker is online - }); +```js +cluster.fork().on('online', () => { + // Worker is online +}); +``` It is not emitted in the worker. @@ -245,36 +259,38 @@ may be useful to send a message, so application specific actions may be taken to close them. It also may be useful to implement a timeout, killing a worker if the `'disconnect'` event has not been emitted after some time. - if (cluster.isMaster) { - var worker = cluster.fork(); - var timeout; - - worker.on('listening', (address) => { - worker.send('shutdown'); - worker.disconnect(); - timeout = setTimeout(() => { - worker.kill(); - }, 2000); - }); - - worker.on('disconnect', () => { - clearTimeout(timeout); - }); - - } else if (cluster.isWorker) { - const net = require('net'); - var server = net.createServer((socket) => { - // connections never end - }); - - server.listen(8000); - - process.on('message', (msg) => { - if(msg === 'shutdown') { - // initiate graceful close of any connections to server - } - }); +```js +if (cluster.isMaster) { + var worker = cluster.fork(); + var timeout; + + worker.on('listening', (address) => { + worker.send('shutdown'); + worker.disconnect(); + timeout = setTimeout(() => { + worker.kill(); + }, 2000); + }); + + worker.on('disconnect', () => { + clearTimeout(timeout); + }); + +} else if (cluster.isWorker) { + const net = require('net'); + var server = net.createServer((socket) => { + // connections never end + }); + + server.listen(8000); + + process.on('message', (msg) => { + if(msg === 'shutdown') { + // initiate graceful close of any connections to server } + }); +} +``` ### worker.id @@ -344,15 +360,17 @@ In a worker this sends a message to the master. It is identical to This example will echo back all messages from the master: - if (cluster.isMaster) { - var worker = cluster.fork(); - worker.send('hi there'); +```js +if (cluster.isMaster) { + var worker = cluster.fork(); + worker.send('hi there'); - } else if (cluster.isWorker) { - process.on('message', (msg) => { - process.send(msg); - }); - } +} else if (cluster.isWorker) { + process.on('message', (msg) => { + process.send(msg); + }); +} +``` ### worker.suicide @@ -363,14 +381,16 @@ Set by calling `.kill()` or `.disconnect()`, until then it is `undefined`. The boolean `worker.suicide` lets you distinguish between voluntary and accidental exit, the master may choose not to respawn a worker based on this value. - cluster.on('exit', (worker, code, signal) => { - if (worker.suicide === true) { - console.log('Oh, it was just suicide\' – no need to worry'). - } - }); +```js +cluster.on('exit', (worker, code, signal) => { + if (worker.suicide === true) { + console.log('Oh, it was just suicide\' – no need to worry'). + } +}); - // kill worker - worker.kill(); +// kill worker +worker.kill(); +``` ## Event: 'disconnect' @@ -384,9 +404,11 @@ There may be a delay between the `'disconnect'` and `'exit'` events. These even can be used to detect if the process is stuck in a cleanup or if there are long-living connections. - cluster.on('disconnect', (worker) => { - console.log(`The worker #${worker.id} has disconnected`); - }); +```js +cluster.on('disconnect', (worker) => { + console.log(`The worker #${worker.id} has disconnected`); +}); +``` ## Event: 'exit' @@ -399,11 +421,13 @@ When any of the workers die the cluster module will emit the `'exit'` event. This can be used to restart the worker by calling `.fork()` again. - cluster.on('exit', (worker, code, signal) => { - console.log('worker %d died (%s). restarting...', - worker.process.pid, signal || code); - cluster.fork(); - }); +```js +cluster.on('exit', (worker, code, signal) => { + console.log('worker %d died (%s). restarting...', + worker.process.pid, signal || code); + cluster.fork(); +}); +``` See [child_process event: 'exit'][]. @@ -414,21 +438,23 @@ See [child_process event: 'exit'][]. When a new worker is forked the cluster module will emit a `'fork'` event. This can be used to log worker activity, and create your own timeout. - var timeouts = []; - function errorMsg() { - console.error('Something must be wrong with the connection ...'); - } - - cluster.on('fork', (worker) => { - timeouts[worker.id] = setTimeout(errorMsg, 2000); - }); - cluster.on('listening', (worker, address) => { - clearTimeout(timeouts[worker.id]); - }); - cluster.on('exit', (worker, code, signal) => { - clearTimeout(timeouts[worker.id]); - errorMsg(); - }); +```js +var timeouts = []; +function errorMsg() { + console.error('Something must be wrong with the connection ...'); +} + +cluster.on('fork', (worker) => { + timeouts[worker.id] = setTimeout(errorMsg, 2000); +}); +cluster.on('listening', (worker, address) => { + clearTimeout(timeouts[worker.id]); +}); +cluster.on('exit', (worker, code, signal) => { + clearTimeout(timeouts[worker.id]); + errorMsg(); +}); +``` ## Event: 'listening' @@ -443,10 +469,12 @@ object and the `address` object contains the following connection properties: `address`, `port` and `addressType`. This is very useful if the worker is listening on more than one address. - cluster.on('listening', (worker, address) => { - console.log( - `A worker is now connected to ${address.address}:${address.port}`); - }); +```js +cluster.on('listening', (worker, address) => { + console.log( + `A worker is now connected to ${address.address}:${address.port}`); +}); +``` The `addressType` is one of: @@ -473,9 +501,11 @@ When the master receives an online message it will emit this event. The difference between `'fork'` and `'online'` is that fork is emitted when the master forks a worker, and 'online' is emitted when the worker is running. - cluster.on('online', (worker) => { - console.log('Yay, the worker responded after it was forked'); - }); +```js +cluster.on('online', (worker) => { + console.log('Yay, the worker responded after it was forked'); +}); +``` ## Event: 'setup' @@ -585,17 +615,19 @@ Note that: Example: - const cluster = require('cluster'); - cluster.setupMaster({ - exec: 'worker.js', - args: ['--use', 'https'], - silent: true - }); - cluster.fork(); // https worker - cluster.setupMaster({ - args: ['--use', 'http'] - }); - cluster.fork(); // http worker +```js +const cluster = require('cluster'); +cluster.setupMaster({ + exec: 'worker.js', + args: ['--use', 'https'], + silent: true +}); +cluster.fork(); // https worker +cluster.setupMaster({ + args: ['--use', 'http'] +}); +cluster.fork(); // http worker +``` This can only be called from the master process. @@ -605,15 +637,17 @@ This can only be called from the master process. A reference to the current worker object. Not available in the master process. - const cluster = require('cluster'); +```js +const cluster = require('cluster'); - if (cluster.isMaster) { - console.log('I am master'); - cluster.fork(); - cluster.fork(); - } else if (cluster.isWorker) { - console.log(`I am worker #${cluster.worker.id}`); - } +if (cluster.isMaster) { + console.log('I am master'); + cluster.fork(); + cluster.fork(); +} else if (cluster.isWorker) { + console.log(`I am worker #${cluster.worker.id}`); +} +``` ## cluster.workers @@ -628,22 +662,26 @@ exited. The order between these two events cannot be determined in advance. However, it is guaranteed that the removal from the cluster.workers list happens before last `'disconnect'` or `'exit'` event is emitted. - // Go through all workers - function eachWorker(callback) { - for (var id in cluster.workers) { - callback(cluster.workers[id]); - } - } - eachWorker((worker) => { - worker.send('big announcement to all workers'); - }); +```js +// Go through all workers +function eachWorker(callback) { + for (var id in cluster.workers) { + callback(cluster.workers[id]); + } +} +eachWorker((worker) => { + worker.send('big announcement to all workers'); +}); +``` Should you wish to reference a worker over a communication channel, using the worker's unique id is the easiest way to find the worker. - socket.on('data', (id) => { - var worker = cluster.workers[id]; - }); +```js +socket.on('data', (id) => { + var worker = cluster.workers[id]; +}); +``` [`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options [`ChildProcess.send()`]: child_process.html#child_process_child_send_message_sendhandle_callback diff --git a/doc/api/console.markdown b/doc/api/console.markdown index 5c2596fe60..b6214c4792 100644 --- a/doc/api/console.markdown +++ b/doc/api/console.markdown @@ -15,33 +15,37 @@ The module exports two specific components: Example using the global `console`: - console.log('hello world'); - // Prints: hello world, to stdout - console.log('hello %s', 'world'); - // Prints: hello world, to stdout - console.error(new Error('Whoops, something bad happened')); - // Prints: [Error: Whoops, something bad happened], to stderr - - const name = 'Will Robinson'; - console.warn(`Danger ${name}! Danger!`); - // Prints: Danger Will Robinson! Danger!, to stderr +```js +console.log('hello world'); + // Prints: hello world, to stdout +console.log('hello %s', 'world'); + // Prints: hello world, to stdout +console.error(new Error('Whoops, something bad happened')); + // Prints: [Error: Whoops, something bad happened], to stderr + +const name = 'Will Robinson'; +console.warn(`Danger ${name}! Danger!`); + // Prints: Danger Will Robinson! Danger!, to stderr +``` Example using the `Console` class: - const out = getStreamSomehow(); - const err = getStreamSomehow(); - const myConsole = new console.Console(out, err); +```js +const out = getStreamSomehow(); +const err = getStreamSomehow(); +const myConsole = new console.Console(out, err); - myConsole.log('hello world'); - // Prints: hello world, to out - myConsole.log('hello %s', 'world'); - // Prints: hello world, to out - myConsole.error(new Error('Whoops, something bad happened')); - // Prints: [Error: Whoops, something bad happened], to err +myConsole.log('hello world'); + // Prints: hello world, to out +myConsole.log('hello %s', 'world'); + // Prints: hello world, to out +myConsole.error(new Error('Whoops, something bad happened')); + // Prints: [Error: Whoops, something bad happened], to err - const name = 'Will Robinson'; - myConsole.warn(`Danger ${name}! Danger!`); - // Prints: Danger Will Robinson! Danger!, to err +const name = 'Will Robinson'; +myConsole.warn(`Danger ${name}! Danger!`); + // Prints: Danger Will Robinson! Danger!, to err +``` While the API for the `Console` class is designed fundamentally around the Web browser `console` object, the `Console` is Node.js is *not* intended to @@ -55,7 +59,9 @@ when the destination is a pipe (to avoid blocking for long periods of time). In the following example, stdout is non-blocking while stderr is blocking: - $ node script.js 2> error.log | tee info.log +``` +$ node script.js 2> error.log | tee info.log +``` Typically, the distinction between blocking/non-blocking is not important unless an application is logging significant amounts of data. High volume @@ -69,8 +75,10 @@ The `Console` class can be used to create a simple logger with configurable output streams and can be accessed using either `require('console').Console` or `console.Console`: - const Console = require('console').Console; - const Console = console.Console; +```js +const Console = require('console').Console; +const Console = console.Console; +``` ### new Console(stdout[, stderr]) @@ -79,19 +87,23 @@ Creates a new `Console` by passing one or two writable stream instances. is used for warning or error output. If `stderr` isn't passed, the warning and error output will be sent to the `stdout`. - const output = fs.createWriteStream('./stdout.log'); - const errorOutput = fs.createWriteStream('./stderr.log'); - // custom simple logger - const logger = new Console(output, errorOutput); - // use it like console - var count = 5; - logger.log('count: %d', count); - // in stdout.log: count 5 +```js +const output = fs.createWriteStream('./stdout.log'); +const errorOutput = fs.createWriteStream('./stderr.log'); +// custom simple logger +const logger = new Console(output, errorOutput); +// use it like console +var count = 5; +logger.log('count: %d', count); +// in stdout.log: count 5 +``` The global `console` is a special `Console` whose output is sent to `process.stdout` and `process.stderr`. It is equivalent to calling: - new Console(process.stdout, process.stderr); +```js +new Console(process.stdout, process.stderr); +``` ### console.assert(value[, message][, ...]) @@ -99,10 +111,12 @@ A simple assertion test that verifies whether `value` is truthy. If it is not, an `AssertionError` is throw. If provided, the error `message` is formatted using [`util.format()`][] and used as the error message. - console.assert(true, 'does nothing'); - // OK - console.assert(false, 'Whoops %s', 'didn\'t work'); - // AssertionError: Whoops didn't work +```js +console.assert(true, 'does nothing'); + // OK +console.assert(false, 'Whoops %s', 'didn\'t work'); + // AssertionError: Whoops didn't work +``` ### console.dir(obj[, options]) @@ -129,11 +143,13 @@ used as the primary message and all additional used as substitution values similar to `printf()` (the arguments are all passed to [`util.format()`][]). - const code = 5; - console.error('error #%d', code); - // Prints: error #5, to stderr - console.error('error', code); - // Prints: error 5, to stderr +```js +const code = 5; +console.error('error #%d', code); + // Prints: error #5, to stderr +console.error('error', code); + // Prints: error 5, to stderr +``` If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`][] is called on each argument and the resulting string @@ -150,11 +166,13 @@ used as the primary message and all additional used as substitution values similar to `printf()` (the arguments are all passed to [`util.format()`][]). - var count = 5; - console.log('count: %d', count); - // Prints: count: 5, to stdout - console.log('count: ', count); - // Prints: count: 5, to stdout +```js +var count = 5; +console.log('count: %d', count); + // Prints: count: 5, to stdout +console.log('count: ', count); + // Prints: count: 5, to stdout +``` If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`][] is called on each argument and the resulting string @@ -172,31 +190,35 @@ milliseconds to stdout. Timer durations are accurate to the sub-millisecond. Stops a timer that was previously started by calling [`console.time()`][] and prints the result to stdout: - console.time('100-elements'); - for (var i = 0; i < 100; i++) { - ; - } - console.timeEnd('100-elements'); - // prints 100-elements: 225.438ms +```js +console.time('100-elements'); +for (var i = 0; i < 100; i++) { + ; +} +console.timeEnd('100-elements'); +// prints 100-elements: 225.438ms +``` ### console.trace(message[, ...]) Prints to stderr the string `'Trace :'`, followed by the [`util.format()`][] formatted message and stack trace to the current position in the code. - console.trace('Show me'); - // Prints: (stack trace will vary based on where trace is called) - // Trace: Show me - // at repl:2:9 - // at REPLServer.defaultEval (repl.js:248:27) - // at bound (domain.js:287:14) - // at REPLServer.runBound [as eval] (domain.js:300:12) - // at REPLServer. (repl.js:412:12) - // at emitOne (events.js:82:20) - // at REPLServer.emit (events.js:169:7) - // at REPLServer.Interface._onLine (readline.js:210:10) - // at REPLServer.Interface._line (readline.js:549:8) - // at REPLServer.Interface._ttyWrite (readline.js:826:14) +```js +console.trace('Show me'); + // Prints: (stack trace will vary based on where trace is called) + // Trace: Show me + // at repl:2:9 + // at REPLServer.defaultEval (repl.js:248:27) + // at bound (domain.js:287:14) + // at REPLServer.runBound [as eval] (domain.js:300:12) + // at REPLServer. (repl.js:412:12) + // at emitOne (events.js:82:20) + // at REPLServer.emit (events.js:169:7) + // at REPLServer.Interface._onLine (readline.js:210:10) + // at REPLServer.Interface._line (readline.js:549:8) + // at REPLServer.Interface._ttyWrite (readline.js:826:14) +``` ### console.warn([data][, ...]) diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 8d39f5ad24..dea78df8f7 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -7,15 +7,17 @@ wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign and verify functions. Use `require('crypto')` to access this module. - const crypto = require('crypto'); - - const secret = 'abcdefg'; - const hash = crypto.createHmac('sha256', secret) - .update('I love cupcakes') - .digest('hex'); - console.log(hash); - // Prints: - // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e +```js +const crypto = require('crypto'); + +const secret = 'abcdefg'; +const hash = crypto.createHmac('sha256', secret) + .update('I love cupcakes') + .digest('hex'); +console.log(hash); + // Prints: + // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e +``` ## Class: Certificate @@ -31,10 +33,12 @@ data. The most common usage is handling output generated by the HTML5 Instances of the `Certificate` class can be created using the `new` keyword or by calling `crypto.Certificate()` as a function: - const crypto = require('crypto'); +```js +const crypto = require('crypto'); - const cert1 = new crypto.Certificate(); - const cert2 = crypto.Certificate(); +const cert1 = new crypto.Certificate(); +const cert2 = crypto.Certificate(); +``` ### certificate.exportChallenge(spkac) @@ -43,11 +47,13 @@ The `spkac` data structure includes a public key and a challenge. The form of a Node.js [`Buffer`][]. The `spkac` argument can be either a string or a [`Buffer`][]. - const cert = require('crypto').Certificate(); - const spkac = getSpkacSomehow(); - const challenge = cert.exportChallenge(spkac); - console.log(challenge.toString('utf8')); - // Prints the challenge as a UTF8 string +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +const challenge = cert.exportChallenge(spkac); +console.log(challenge.toString('utf8')); + // Prints the challenge as a UTF8 string +``` ### Certificate.exportPublicKey(spkac) @@ -56,21 +62,25 @@ The `spkac` data structure includes a public key and a challenge. The form of a Node.js [`Buffer`][]. The `spkac` argument can be either a string or a [`Buffer`][]. - const cert = require('crypto').Certificate(); - const spkac = getSpkacSomehow(); - const publicKey = cert.exportPublicKey(spkac); - console.log(publicKey); - // Prints the public key as +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +const publicKey = cert.exportPublicKey(spkac); +console.log(publicKey); + // Prints the public key as +``` ### Certificate.verifySpkac(spkac) Returns `true` if the given `spkac` data structure is valid, `false` otherwise. The `spkac` argument must be a Node.js [`Buffer`][]. - const cert = require('crypto').Certificate(); - const spkac = getSpkacSomehow(); - console.log(cert.verifySpkac(new Buffer(spkac))); - // Prints true or false +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +console.log(cert.verifySpkac(new Buffer(spkac))); + // Prints true or false +``` ## Class: Cipher @@ -88,38 +98,44 @@ using the `new` keyword. Example: Using `Cipher` objects as streams: - const crypto = require('crypto'); - const cipher = crypto.createCipher('aes192', 'a password'); +```js +const crypto = require('crypto'); +const cipher = crypto.createCipher('aes192', 'a password'); - cipher.on('readable', () => { - var data = cipher.read(); - if (data) - console.log(data.toString('hex')); - // Prints: b919f20fc5ac2f9c1d2cce94cb1d9c2d - }); +cipher.on('readable', () => { + var data = cipher.read(); + if (data) + console.log(data.toString('hex')); + // Prints: b919f20fc5ac2f9c1d2cce94cb1d9c2d +}); - cipher.write('clear text data'); - cipher.end(); +cipher.write('clear text data'); +cipher.end(); +``` Example: Using `Cipher` and piped streams: - const crypto = require('crypto'); - const fs = require('fs'); - const cipher = crypto.createCipher('aes192', 'a password'); +```js +const crypto = require('crypto'); +const fs = require('fs'); +const cipher = crypto.createCipher('aes192', 'a password'); - const input = fs.createReadStream('test.js'); - const output = fs.createWriteStream('test.enc'); +const input = fs.createReadStream('test.js'); +const output = fs.createWriteStream('test.enc'); - input.pipe(cipher).pipe(output); +input.pipe(cipher).pipe(output); +``` Example: Using the `cipher.update()` and `cipher.final()` methods: - const crypto = require('crypto'); - const cipher = crypto.createCipher('aes192', 'a password'); +```js +const crypto = require('crypto'); +const cipher = crypto.createCipher('aes192', 'a password'); - cipher.update('clear text data'); - console.log(cipher.final('hex')); - // Prints: b919f20fc5ac2f9c1d2cce94cb1d9c2d +cipher.update('clear text data'); +console.log(cipher.final('hex')); + // Prints: b919f20fc5ac2f9c1d2cce94cb1d9c2d +``` ### cipher.final([output_encoding]) @@ -192,38 +208,44 @@ directly using the `new` keyword. Example: Using `Decipher` objects as streams: - const crypto = require('crypto'); - const decipher = crypto.createDecipher('aes192', 'a password'); +```js +const crypto = require('crypto'); +const decipher = crypto.createDecipher('aes192', 'a password'); - decipher.on('readable', () => { - var data = decipher.read(); - if (data) - console.log(data.toString()); - // Prints: clear text data - }); +decipher.on('readable', () => { + var data = decipher.read(); + if (data) + console.log(data.toString()); + // Prints: clear text data +}); - decipher.write('b919f20fc5ac2f9c1d2cce94cb1d9c2d', 'hex'); - decipher.end(); +decipher.write('b919f20fc5ac2f9c1d2cce94cb1d9c2d', 'hex'); +decipher.end(); +``` Example: Using `Decipher` and piped streams: - const crypto = require('crypto'); - const fs = require('fs'); - const decipher = crypto.createDecipher('aes192', 'a password'); +``` +const crypto = require('crypto'); +const fs = require('fs'); +const decipher = crypto.createDecipher('aes192', 'a password'); - const input = fs.createReadStream('test.enc'); - const output = fs.createWriteStream('test.js'); +const input = fs.createReadStream('test.enc'); +const output = fs.createWriteStream('test.js'); - input.pipe(decipher).pipe(output); +input.pipe(decipher).pipe(output); +``` Example: Using the `decipher.update()` and `decipher.final()` methods: - const crypto = require('crypto'); - const decipher = crypto.createDecipher('aes192', 'a password'); +```js +const crypto = require('crypto'); +const decipher = crypto.createDecipher('aes192', 'a password'); - decipher.update('b919f20fc5ac2f9c1d2cce94cb1d9c2d', 'hex'); - console.log(decipher.final('utf8')); - // Prints: clear text data +decipher.update('b919f20fc5ac2f9c1d2cce94cb1d9c2d', 'hex'); +console.log(decipher.final('utf8')); + // Prints: clear text data +``` ### decipher.final([output_encoding]) @@ -286,23 +308,25 @@ exchanges. Instances of the `DiffieHellman` class can be created using the `crypto.createDiffieHellman()` function. - const crypto = require('crypto'); - const assert = require('assert'); +```js +const crypto = require('crypto'); +const assert = require('assert'); - // Generate Alice's keys... - const alice = crypto.createDiffieHellman(11); - const alice_key = alice.generateKeys(); +// Generate Alice's keys... +const alice = crypto.createDiffieHellman(11); +const alice_key = alice.generateKeys(); - // Generate Bob's keys... - const bob = crypto.createDiffieHellman(11); - const bob_key = bob.generateKeys(); +// Generate Bob's keys... +const bob = crypto.createDiffieHellman(11); +const bob_key = bob.generateKeys(); - // Exchange and generate the secret... - const alice_secret = alice.computeSecret(bob_key); - const bob_secret = bob.computeSecret(alice_key); +// Exchange and generate the secret... +const alice_secret = alice.computeSecret(bob_key); +const bob_secret = bob.computeSecret(alice_key); - assert(alice_secret, bob_secret); - // OK +assert(alice_secret, bob_secret); + // OK +``` ### diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding]) @@ -383,23 +407,25 @@ key exchanges. Instances of the `ECDH` class can be created using the `crypto.createECDH()` function. - const crypto = require('crypto'); - const assert = require('assert'); +```js +const crypto = require('crypto'); +const assert = require('assert'); - // Generate Alice's keys... - const alice = crypto.createECDH('secp521r1'); - const alice_key = alice.generateKeys(); +// Generate Alice's keys... +const alice = crypto.createECDH('secp521r1'); +const alice_key = alice.generateKeys(); - // Generate Bob's keys... - const bob = crypto.createECDH('secp521r1'); - const bob_key = bob.generateKeys(); +// Generate Bob's keys... +const bob = crypto.createECDH('secp521r1'); +const bob_key = bob.generateKeys(); - // Exchange and generate the secret... - const alice_secret = alice.computeSecret(bob_key); - const bob_secret = bob.computeSecret(alice_key); +// Exchange and generate the secret... +const alice_secret = alice.computeSecret(bob_key); +const bob_secret = bob.computeSecret(alice_key); - assert(alice_secret, bob_secret); - // OK +assert(alice_secret, bob_secret); + // OK +``` ### ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding]) @@ -471,25 +497,27 @@ public point/key associated with the private key being set. Example (obtaining a shared secret): - const crypto = require('crypto'); - const alice = crypto.createECDH('secp256k1'); - const bob = crypto.createECDH('secp256k1'); +```js +const crypto = require('crypto'); +const alice = crypto.createECDH('secp256k1'); +const bob = crypto.createECDH('secp256k1'); - // Note: This is a shortcut way to specify one of Alice's previous private - // keys. It would be unwise to use such a predictable private key in a real - // application. - alice.setPrivateKey( - crypto.createHash('sha256').update('alice', 'utf8').digest() - ); +// Note: This is a shortcut way to specify one of Alice's previous private +// keys. It would be unwise to use such a predictable private key in a real +// application. +alice.setPrivateKey( + crypto.createHash('sha256').update('alice', 'utf8').digest() +); - // Bob uses a newly generated cryptographically strong - // pseudorandom key pair bob.generateKeys(); +// Bob uses a newly generated cryptographically strong +// pseudorandom key pair bob.generateKeys(); - const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); - const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); +const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); - // alice_secret and bob_secret should be the same shared secret value - console.log(alice_secret === bob_secret); +// alice_secret and bob_secret should be the same shared secret value +console.log(alice_secret === bob_secret); +``` ## Class: Hash @@ -506,38 +534,44 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hash` objects as streams: - const crypto = require('crypto'); - const hash = crypto.createHash('sha256'); +```js +const crypto = require('crypto'); +const hash = crypto.createHash('sha256'); - hash.on('readable', () => { - var data = hash.read(); - if (data) - console.log(data.toString('hex')); - // Prints: - // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 - }); +hash.on('readable', () => { + var data = hash.read(); + if (data) + console.log(data.toString('hex')); + // Prints: + // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 +}); - hash.write('some data to hash'); - hash.end(); +hash.write('some data to hash'); +hash.end(); +``` Example: Using `Hash` and piped streams: - const crypto = require('crypto'); - const fs = require('fs'); - const hash = crypto.createHash('sha256'); +```js +const crypto = require('crypto'); +const fs = require('fs'); +const hash = crypto.createHash('sha256'); - const input = fs.createReadStream('test.js'); - input.pipe(hash).pipe(process.stdout); +const input = fs.createReadStream('test.js'); +input.pipe(hash).pipe(process.stdout); +``` Example: Using the `hash.update()` and `hash.digest()` methods: - const crypto = require('crypto'); - const hash = crypto.createHash('sha256'); +```js +const crypto = require('crypto'); +const hash = crypto.createHash('sha256'); - hash.update('some data to hash'); - console.log(hash.digest('hex')); - // Prints: - // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 +hash.update('some data to hash'); +console.log(hash.digest('hex')); + // Prints: + // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 +``` ### hash.digest([encoding]) @@ -574,38 +608,44 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hmac` objects as streams: - const crypto = require('crypto'); - const hmac = crypto.createHmac('sha256', 'a secret'); +```js +const crypto = require('crypto'); +const hmac = crypto.createHmac('sha256', 'a secret'); - hmac.on('readable', () => { - var data = hmac.read(); - if (data) - console.log(data.toString('hex')); - // Prints: - // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e - }); +hmac.on('readable', () => { + var data = hmac.read(); + if (data) + console.log(data.toString('hex')); + // Prints: + // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e +}); - hmac.write('some data to hash'); - hmac.end(); +hmac.write('some data to hash'); +hmac.end(); +``` Example: Using `Hmac` and piped streams: - const crypto = require('crypto'); - const fs = require('fs'); - const hmac = crypto.createHmac('sha256', 'a secret'); +```js +const crypto = require('crypto'); +const fs = require('fs'); +const hmac = crypto.createHmac('sha256', 'a secret'); - const input = fs.createReadStream('test.js'); - input.pipe(hmac).pipe(process.stdout); +const input = fs.createReadStream('test.js'); +input.pipe(hmac).pipe(process.stdout); +``` Example: Using the `hmac.update()` and `hmac.digest()` methods: - const crypto = require('crypto'); - const hmac = crypto.createHmac('sha256', 'a secret'); +```js +const crypto = require('crypto'); +const hmac = crypto.createHmac('sha256', 'a secret'); - hmac.update('some data to hash'); - console.log(hmac.digest('hex')); - // Prints: - // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e +hmac.update('some data to hash'); +console.log(hmac.digest('hex')); + // Prints: + // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e +``` ### hmac.digest([encoding]) @@ -636,26 +676,30 @@ objects are not to be created directly using the `new` keyword. Example: Using `Sign` objects as streams: - const crypto = require('crypto'); - const sign = crypto.createSign('rsa-sha256'); +```js +const crypto = require('crypto'); +const sign = crypto.createSign('rsa-sha256'); - sign.write('some data to sign'); - sign.end(); +sign.write('some data to sign'); +sign.end(); - const private_key = getPrivateKeySomehow(); - console.log(sign.sign(private_key, 'hex')); - // Prints the calculated signature +const private_key = getPrivateKeySomehow(); +console.log(sign.sign(private_key, 'hex')); + // Prints the calculated signature +``` Example: Using the `sign.update()` and `sign.sign()` methods: - const crypto = require('crypto'); - const sign = crypto.createSign('rsa-sha256'); +```js +const crypto = require('crypto'); +const sign = crypto.createSign('rsa-sha256'); - sign.update('some data to sign'); +sign.update('some data to sign'); - const private_key = getPrivateKeySomehow(); - console.log(sign.sign(private_key, 'hex')); - // Prints the calculated signature +const private_key = getPrivateKeySomehow(); +console.log(sign.sign(private_key, 'hex')); + // Prints the calculated signature +``` ### sign.sign(private_key[, output_format]) @@ -696,28 +740,32 @@ of two ways: Example: Using `Verify` objects as streams: - const crypto = require('crypto'); - const verify = crypto.createVerify('rsa-sha256'); +```js +const crypto = require('crypto'); +const verify = crypto.createVerify('rsa-sha256'); - verify.write('some data to sign'); - verify.end(); +verify.write('some data to sign'); +verify.end(); - const public_key = getPublicKeySomehow(); - const signature = getSignatureToVerify(); - console.log(sign.verify(public_key, signature)); - // Prints true or false +const public_key = getPublicKeySomehow(); +const signature = getSignatureToVerify(); +console.log(sign.verify(public_key, signature)); + // Prints true or false +``` Example: Using the `verify.update()` and `verify.verify()` methods: - const crypto = require('crypto'); - const verify = crypto.createVerify('rsa-sha256'); +```js +const crypto = require('crypto'); +const verify = crypto.createVerify('rsa-sha256'); - verify.update('some data to sign'); +verify.update('some data to sign'); - const public_key = getPublicKeySomehow(); - const signature = getSignatureToVerify(); - console.log(verify.verify(public_key, signature)); - // Prints true or false +const public_key = getPublicKeySomehow(); +const signature = getSignatureToVerify(); +console.log(verify.verify(public_key, signature)); + // Prints true or false +``` ### verifier.update(data) @@ -890,21 +938,23 @@ display the available digest algorithms. Example: generating the sha256 sum of a file - const filename = process.argv[2]; - const crypto = require('crypto'); - const fs = require('fs'); +```js +const filename = process.argv[2]; +const crypto = require('crypto'); +const fs = require('fs'); - const hash = crypto.createHash('sha256'); +const hash = crypto.createHash('sha256'); - const input = fs.createReadStream(filename); - input.on('readable', () => { - var data = input.read(); - if (data) - hash.update(data); - else { - console.log(`${hash.digest('hex')} ${filename}`); - } - }); +const input = fs.createReadStream(filename); +input.on('readable', () => { + var data = input.read(); + if (data) + hash.update(data); + else { + console.log(`${hash.digest('hex')} ${filename}`); + } +}); +``` ### crypto.createHmac(algorithm, key) @@ -919,21 +969,23 @@ The `key` is the HMAC key used to generate the cryptographic HMAC hash. Example: generating the sha256 HMAC of a file - const filename = process.argv[2]; - const crypto = require('crypto'); - const fs = require('fs'); +```js +const filename = process.argv[2]; +const crypto = require('crypto'); +const fs = require('fs'); - const hmac = crypto.createHmac('sha256', 'a secret'); +const hmac = crypto.createHmac('sha256', 'a secret'); - const input = fs.createReadStream(filename); - input.on('readable', () => { - var data = input.read(); - if (data) - hmac.update(data); - else { - console.log(`${hmac.digest('hex')} ${filename}`); - } - }); +const input = fs.createReadStream(filename); +input.on('readable', () => { + var data = input.read(); + if (data) + hmac.update(data); + else { + console.log(`${hmac.digest('hex')} ${filename}`); + } +}); +``` ### crypto.createSign(algorithm) @@ -953,8 +1005,10 @@ Returns an array with the names of the supported cipher algorithms. Example: - const ciphers = crypto.getCiphers(); - console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...] +```js +const ciphers = crypto.getCiphers(); +console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...] +``` ### crypto.getCurves() @@ -962,8 +1016,10 @@ Returns an array with the names of the supported elliptic curves. Example: - const curves = crypto.getCurves(); - console.log(curves); // ['secp256k1', 'secp384r1', ...] +```js +const curves = crypto.getCurves(); +console.log(curves); // ['secp256k1', 'secp384r1', ...] +``` ### crypto.getDiffieHellman(group_name) @@ -980,18 +1036,20 @@ and communication time. Example (obtaining a shared secret): - const crypto = require('crypto'); - const alice = crypto.getDiffieHellman('modp14'); - const bob = crypto.getDiffieHellman('modp14'); +```js +const crypto = require('crypto'); +const alice = crypto.getDiffieHellman('modp14'); +const bob = crypto.getDiffieHellman('modp14'); - alice.generateKeys(); - bob.generateKeys(); +alice.generateKeys(); +bob.generateKeys(); - const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); - const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); +const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); - /* alice_secret and bob_secret should be the same */ - console.log(alice_secret == bob_secret); +/* alice_secret and bob_secret should be the same */ +console.log(alice_secret == bob_secret); +``` ### crypto.getHashes() @@ -999,8 +1057,10 @@ Returns an array with the names of the supported hash algorithms. Example: - const hashes = crypto.getHashes(); - console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] +```js +const hashes = crypto.getHashes(); +console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] +``` ### crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback) @@ -1024,11 +1084,13 @@ salts are random and their lengths are greater than 16 bytes. See Example: - const crypto = require('crypto'); - crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => { - if (err) throw err; - console.log(key.toString('hex')); // 'c5e478d...1469e50' - }); +```js +const crypto = require('crypto'); +crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => { + if (err) throw err; + console.log(key.toString('hex')); // 'c5e478d...1469e50' +}); +``` An array of supported digest functions can be retrieved using [`crypto.getHashes()`][]. @@ -1054,9 +1116,11 @@ salts are random and their lengths are greater than 16 bytes. See Example: - const crypto = require('crypto'); - const key = crypto.pbkdf2sync('secret', 'salt', 100000, 512, 'sha512'); - console.log(key.toString('hex')); // 'c5e478d...1469e50' +```js +const crypto = require('crypto'); +const key = crypto.pbkdf2sync('secret', 'salt', 100000, 512, 'sha512'); +console.log(key.toString('hex')); // 'c5e478d...1469e50' +``` An array of supported digest functions can be retrieved using [`crypto.getHashes()`][]. @@ -1149,22 +1213,26 @@ and the `callback` function is invoked with two arguments: `err` and `buf`. If an error occurs, `err` will be an Error object; otherwise it is null. The `buf` argument is a [`Buffer`][] containing the generated bytes. - // Asynchronous - const crypto = require('crypto'); - crypto.randomBytes(256, (err, buf) => { - if (err) throw err; - console.log( - `${buf.length}` bytes of random data: ${buf.toString('hex')}); - }); +```js +// Asynchronous +const crypto = require('crypto'); +crypto.randomBytes(256, (err, buf) => { + if (err) throw err; + console.log( + `${buf.length}` bytes of random data: ${buf.toString('hex')}); +}); +``` If the `callback` function is not provided, the random bytes are generated synchronously and returned as a [`Buffer`][]. An error will be thrown if there is a problem generating the bytes. - // Synchronous - const buf = crypto.randomBytes(256); - console.log( - `${buf.length}` bytes of random data: ${buf.toString('hex')}); +```js +// Synchronous +const buf = crypto.randomBytes(256); +console.log( + `${buf.length}` bytes of random data: ${buf.toString('hex')}); +``` The `crypto.randomBytes()` method will block until there is sufficient entropy. This should normally never take longer than a few milliseconds. The only time diff --git a/doc/api/debugger.markdown b/doc/api/debugger.markdown index 1f9d6703b7..f7aec3d58c 100644 --- a/doc/api/debugger.markdown +++ b/doc/api/debugger.markdown @@ -9,14 +9,16 @@ via a simple [TCP-based protocol][] and built-in debugging client. To use it, start Node.js with the `debug` argument followed by the path to the script to debug; a prompt will be displayed indicating successful launch of the debugger: - % node debug myscript.js - < debugger listening on port 5858 - connecting... ok - break in /home/indutny/Code/git/indutny/myscript.js:1 - 1 x = 5; - 2 setTimeout(function () { - 3 debugger; - debug> +``` +% node debug myscript.js +< debugger listening on port 5858 +connecting... ok +break in /home/indutny/Code/git/indutny/myscript.js:1 + 1 x = 5; + 2 setTimeout(function () { + 3 debugger; +debug> +``` Node.js's debugger client does not yet support the full range of commands, but simple step and inspection are possible. @@ -26,55 +28,58 @@ enable a breakpoint at that position in the code. For example, suppose `myscript.js` is written as: - // myscript.js - x = 5; - setTimeout(function () { - debugger; - console.log('world'); - }, 1000); - console.log('hello'); +```js +// myscript.js +x = 5; +setTimeout(function () { + debugger; + console.log('world'); +}, 1000); +console.log('hello'); +``` Once the debugger is run, a breakpoint will occur at line 4: - % node debug myscript.js - < debugger listening on port 5858 - connecting... ok - break in /home/indutny/Code/git/indutny/myscript.js:1 - 1 x = 5; - 2 setTimeout(function () { - 3 debugger; - debug> cont - < hello - break in /home/indutny/Code/git/indutny/myscript.js:3 - 1 x = 5; - 2 setTimeout(function () { - 3 debugger; - 4 console.log('world'); - 5 }, 1000); - debug> next - break in /home/indutny/Code/git/indutny/myscript.js:4 - 2 setTimeout(function () { - 3 debugger; - 4 console.log('world'); - 5 }, 1000); - 6 console.log('hello'); - debug> repl - Press Ctrl + C to leave debug repl - > x - 5 - > 2+2 - 4 - debug> next - < world - break in /home/indutny/Code/git/indutny/myscript.js:5 - 3 debugger; - 4 console.log('world'); - 5 }, 1000); - 6 console.log('hello'); - 7 - debug> quit - % - +``` +% node debug myscript.js +< debugger listening on port 5858 +connecting... ok +break in /home/indutny/Code/git/indutny/myscript.js:1 + 1 x = 5; + 2 setTimeout(function () { + 3 debugger; +debug> cont +< hello +break in /home/indutny/Code/git/indutny/myscript.js:3 + 1 x = 5; + 2 setTimeout(function () { + 3 debugger; + 4 console.log('world'); + 5 }, 1000); +debug> next +break in /home/indutny/Code/git/indutny/myscript.js:4 + 2 setTimeout(function () { + 3 debugger; + 4 console.log('world'); + 5 }, 1000); + 6 console.log('hello'); +debug> repl +Press Ctrl + C to leave debug repl +> x +5 +> 2+2 +4 +debug> next +< world +break in /home/indutny/Code/git/indutny/myscript.js:5 + 3 debugger; + 4 console.log('world'); + 5 }, 1000); + 6 console.log('hello'); + 7 +debug> quit +% +``` The `repl` command allows code to be evaluated remotely. The `next` command steps over to the next line. Type `help` to see what other commands are @@ -115,26 +120,28 @@ on line 1 It is also possible to set a breakpoint in a file (module) that isn't loaded yet: - % ./node debug test/fixtures/break-in-module/main.js - < debugger listening on port 5858 - connecting to port 5858... ok - break in test/fixtures/break-in-module/main.js:1 - 1 var mod = require('./mod.js'); - 2 mod.hello(); - 3 mod.hello(); - debug> setBreakpoint('mod.js', 23) - Warning: script 'mod.js' was not loaded yet. - 1 var mod = require('./mod.js'); - 2 mod.hello(); - 3 mod.hello(); - debug> c - break in test/fixtures/break-in-module/mod.js:23 - 21 - 22 exports.hello = function() { - 23 return 'hello from module'; - 24 }; - 25 - debug> +``` +% ./node debug test/fixtures/break-in-module/main.js +< debugger listening on port 5858 +connecting to port 5858... ok +break in test/fixtures/break-in-module/main.js:1 + 1 var mod = require('./mod.js'); + 2 mod.hello(); + 3 mod.hello(); +debug> setBreakpoint('mod.js', 23) +Warning: script 'mod.js' was not loaded yet. + 1 var mod = require('./mod.js'); + 2 mod.hello(); + 3 mod.hello(); +debug> c +break in test/fixtures/break-in-module/mod.js:23 + 21 + 22 exports.hello = function() { + 23 return 'hello from module'; + 24 }; + 25 +debug> +``` ### Info diff --git a/doc/api/dgram.markdown b/doc/api/dgram.markdown index 78bf3c2210..7818e508d2 100644 --- a/doc/api/dgram.markdown +++ b/doc/api/dgram.markdown @@ -6,25 +6,27 @@ The `dgram` module provides an implementation of UDP Datagram sockets. - const dgram = require('dgram'); - const server = dgram.createSocket('udp4'); +```js +const dgram = require('dgram'); +const server = dgram.createSocket('udp4'); - server.on('error', (err) => { - console.log(`server error:\n${err.stack}`); - server.close(); - }); +server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); + server.close(); +}); - server.on('message', (msg, rinfo) => { - console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); - }); +server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); +}); - server.on('listening', () => { - var address = server.address(); - console.log(`server listening ${address.address}:${address.port}`); - }); +server.on('listening', () => { + var address = server.address(); + console.log(`server listening ${address.address}:${address.port}`); +}); - server.bind(41234); - // server listening 0.0.0.0:41234 +server.bind(41234); +// server listening 0.0.0.0:41234 +``` ## Class: dgram.Socket @@ -61,10 +63,12 @@ The event handler function is passed two arguments: `msg` and `rinfo`. The `msg` argument is a [`Buffer`][] and `rinfo` is an object with the sender's address information provided by the `address`, `family` and `port` properties: - socket.on('message', (msg, rinfo) => { - console.log('Received %d bytes from %s:%d\n', - msg.length, rinfo.address, rinfo.port); - }); +```js +socket.on('message', (msg, rinfo) => { + console.log('Received %d bytes from %s:%d\n', + msg.length, rinfo.address, rinfo.port); +}); +``` ### socket.addMembership(multicastAddress[, multicastInterface]) @@ -108,25 +112,27 @@ attempting to bind with a closed socket), an [`Error`][] may be thrown. Example of a UDP server listening on port 41234: - const dgram = require('dgram'); - const server = dgram.createSocket('udp4'); +```js +const dgram = require('dgram'); +const server = dgram.createSocket('udp4'); - server.on('error', (err) => { - console.log(`server error:\n${err.stack}`); - server.close(); - }); +server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); + server.close(); +}); - server.on('message', (msg, rinfo) => { - console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); - }); +server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); +}); - server.on('listening', () => { - var address = server.address(); - console.log(`server listening ${address.address}:${address.port}`); - }); +server.on('listening', () => { + var address = server.address(); + console.log(`server listening ${address.address}:${address.port}`); +}); - server.bind(41234); - // server listening 0.0.0.0:41234 +server.bind(41234); +// server listening 0.0.0.0:41234 +``` ### socket.bind(options[, callback]) @@ -153,11 +159,13 @@ port sharing results in an error. An example socket listening on an exclusive port is shown below. - socket.bind({ - address: 'localhost', - port: 8000, - exclusive: true - }); +```js +socket.bind({ + address: 'localhost', + port: 8000, + exclusive: true +}); +``` ### socket.close([callback]) @@ -218,12 +226,14 @@ the error is emitted as an `'error'` event on the `socket` object. Example of sending a UDP packet to a random port on `localhost`; - const dgram = require('dgram'); - const message = new Buffer('Some bytes'); - const client = dgram.createSocket('udp4'); - client.send(message, 0, message.length, 41234, 'localhost', (err) => { - client.close(); - }); +```js +const dgram = require('dgram'); +const message = new Buffer('Some bytes'); +const client = dgram.createSocket('udp4'); +client.send(message, 0, message.length, 41234, 'localhost', (err) => { + client.close(); +}); +``` **A Note about UDP datagram size** @@ -324,17 +334,21 @@ As of Node.js v0.10, [`dgram.Socket#bind()`][] changed to an asynchronous execution model. Legacy code that assumes synchronous behavior, as in the following example: - const s = dgram.createSocket('udp4'); - s.bind(1234); - s.addMembership('224.0.0.114'); +```js +const s = dgram.createSocket('udp4'); +s.bind(1234); +s.addMembership('224.0.0.114'); +``` Must be changed to pass a callback function to the [`dgram.Socket#bind()`][] function: - const s = dgram.createSocket('udp4'); - s.bind(1234, () => { - s.addMembership('224.0.0.114'); - }); +```js +const s = dgram.createSocket('udp4'); +s.bind(1234, () => { + s.addMembership('224.0.0.114'); +}); +``` ## `dgram` module functions diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index ed59051238..7888f14d72 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -12,11 +12,13 @@ the same operating system behave should use [`dns.lookup()`][].__ For example, looking up `nodejs.org`. - const dns = require('dns'); +```js +const dns = require('dns'); - dns.lookup('nodejs.org', (err, addresses, family) => { - console.log('addresses:', addresses); - }); +dns.lookup('nodejs.org', (err, addresses, family) => { + console.log('addresses:', addresses); +}); +``` 2) Functions that connect to an actual DNS server to perform name resolution, and that _always_ use the network to perform DNS queries. This category @@ -29,22 +31,24 @@ for name resolution, and instead want to _always_ perform DNS queries. Below is an example that resolves `'nodejs.org'` then reverse resolves the IP addresses that are returned. - const dns = require('dns'); +```js +const dns = require('dns'); - dns.resolve4('nodejs.org', (err, addresses) => { - if (err) throw err; +dns.resolve4('nodejs.org', (err, addresses) => { + if (err) throw err; - console.log(`addresses: ${JSON.stringify(addresses)}`); + console.log(`addresses: ${JSON.stringify(addresses)}`); - addresses.forEach((a) => { - dns.reverse(a, (err, hostnames) => { - if (err) { - throw err; - } - console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); - }); - }); + addresses.forEach((a) => { + dns.reverse(a, (err, hostnames) => { + if (err) { + throw err; + } + console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); }); + }); +}); +``` There are subtle consequences in choosing one over the other, please consult the [Implementation considerations section][] for more information. @@ -76,11 +80,13 @@ Alternatively, `options` can be an object containing these properties: All properties are optional. An example usage of options is shown below. - { - family: 4, - hints: dns.ADDRCONFIG | dns.V4MAPPED, - all: false - } +``` +{ + family: 4, + hints: dns.ADDRCONFIG | dns.V4MAPPED, + all: false +} +``` The `callback` function has arguments `(err, address, family)`. `address` is a string representation of an IPv4 or IPv6 address. `family` is either the @@ -125,11 +131,13 @@ The callback has arguments `(err, hostname, service)`. The `hostname` and On error, `err` is an [`Error`][] object, where `err.code` is the error code. - const dns = require('dns'); - dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { - console.log(hostname, service); - // Prints: localhost ssh - }); +```js +const dns = require('dns'); +dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { + console.log(hostname, service); + // Prints: localhost ssh +}); +``` ## dns.resolve(hostname[, rrtype], callback) @@ -204,15 +212,17 @@ be an object with the following properties: * `expire` * `minttl` - { - nsname: 'ns.example.com', - hostmaster: 'root.example.com', - serial: 2013101809, - refresh: 10000, - retry: 2400, - expire: 604800, - minttl: 3600 - } +``` +{ + nsname: 'ns.example.com', + hostmaster: 'root.example.com', + serial: 2013101809, + refresh: 10000, + retry: 2400, + expire: 604800, + minttl: 3600 +} +``` ## dns.resolveSrv(hostname, callback) @@ -225,12 +235,14 @@ be an array of objects with the following properties: * `port` * `name` - { - priority: 10, - weight: 5, - port: 21223, - name: 'service.example.com' - } +``` +{ + priority: 10, + weight: 5, + port: 21223, + name: 'service.example.com' +} +``` ## dns.resolveTxt(hostname, callback) diff --git a/doc/api/domain.markdown b/doc/api/domain.markdown index 410a74498d..91fbe566f7 100644 --- a/doc/api/domain.markdown +++ b/doc/api/domain.markdown @@ -44,7 +44,7 @@ the failure, and react accordingly. For example, this is not a good idea: -```javascript +```js // XXX WARNING! BAD IDEA! var d = require('domain').create(); @@ -66,7 +66,7 @@ By using the context of a domain, and the resilience of separating our program into multiple worker processes, we can react more appropriately, and handle errors with much greater safety. -```javascript +```js // Much better! const cluster = require('cluster'); @@ -227,7 +227,7 @@ That is possible via explicit binding. For example: -``` +```js // create a top-level domain for the server const domain = require('domain'); const http = require('http'); @@ -282,7 +282,7 @@ This is the most basic way to use a domain. Example: -``` +```js const domain = require('domain'); const fs = require('fs'); const d = domain.create(); @@ -345,20 +345,22 @@ thrown will be routed to the domain's `'error'` event. #### Example - const d = domain.create(); +```js +const d = domain.create(); - function readSomeFile(filename, cb) { - fs.readFile(filename, 'utf8', d.bind(function(er, data) { - // if this throws, it will also be passed to the domain - return cb(er, data ? JSON.parse(data) : null); - })); - } +function readSomeFile(filename, cb) { + fs.readFile(filename, 'utf8', d.bind(function(er, data) { + // if this throws, it will also be passed to the domain + return cb(er, data ? JSON.parse(data) : null); + })); +} - d.on('error', (er) => { - // an error occurred somewhere. - // if we throw it now, it will crash the program - // with the normal line number and stack message. - }); +d.on('error', (er) => { + // an error occurred somewhere. + // if we throw it now, it will crash the program + // with the normal line number and stack message. +}); +``` ### domain.intercept(callback) @@ -374,27 +376,29 @@ with a single error handler in a single place. #### Example - const d = domain.create(); - - function readSomeFile(filename, cb) { - fs.readFile(filename, 'utf8', d.intercept(function(data) { - // note, the first argument is never passed to the - // callback since it is assumed to be the 'Error' argument - // and thus intercepted by the domain. +```js +const d = domain.create(); - // if this throws, it will also be passed to the domain - // so the error-handling logic can be moved to the 'error' - // event on the domain instead of being repeated throughout - // the program. - return cb(null, JSON.parse(data)); - })); - } +function readSomeFile(filename, cb) { + fs.readFile(filename, 'utf8', d.intercept(function(data) { + // note, the first argument is never passed to the + // callback since it is assumed to be the 'Error' argument + // and thus intercepted by the domain. + + // if this throws, it will also be passed to the domain + // so the error-handling logic can be moved to the 'error' + // event on the domain instead of being repeated throughout + // the program. + return cb(null, JSON.parse(data)); + })); +} - d.on('error', (er) => { - // an error occurred somewhere. - // if we throw it now, it will crash the program - // with the normal line number and stack message. - }); +d.on('error', (er) => { + // an error occurred somewhere. + // if we throw it now, it will crash the program + // with the normal line number and stack message. +}); +``` ### domain.enter() diff --git a/doc/api/errors.markdown b/doc/api/errors.markdown index b0c3da8e24..342fd9710e 100644 --- a/doc/api/errors.markdown +++ b/doc/api/errors.markdown @@ -39,13 +39,15 @@ and throw an error using the standard JavaScript `throw` mechanism. These are handled using the [`try / catch` construct][] provided by the JavaScript language. - // Throws with a ReferenceError because z is undefined - try { - const m = 1; - const n = m + z; - } catch (err) { - // Handle the error here. - } +```js +// Throws with a ReferenceError because z is undefined +try { + const m = 1; + const n = m + z; +} catch (err) { + // Handle the error here. +} +``` Any use of the JavaScript `throw` mechanism will raise an exception that *must* be handled using `try / catch` or the Node.js process will exit @@ -62,7 +64,7 @@ Errors that occur within _Asynchronous APIs_ may be reported in multiple ways: argument is not `null` and is an instance of `Error`, then an error occurred that should be handled. - ``` + ```js const fs = require('fs'); fs.readFile('a file that does not exist', (err, data) => { if (err) { @@ -75,7 +77,7 @@ Errors that occur within _Asynchronous APIs_ may be reported in multiple ways: - When an asynchronous method is called on an object that is an `EventEmitter`, errors can be routed to that object's `'error'` event. - ``` + ```js const net = require('net'); const connection = net.connect('localhost'); @@ -107,14 +109,16 @@ unhandled exception and crash unless either: The [`domain`][] module is used appropriately or a handler has been registered for the [`process.on('uncaughtException')`][] event. - const EventEmitter = require('events'); - const ee = new EventEmitter(); +```js +const EventEmitter = require('events'); +const ee = new EventEmitter(); - setImmediate(() => { - // This will crash the process because no 'error' event - // handler has been added. - ee.emit('error', new Error('This will crash')); - }); +setImmediate(() => { + // This will crash the process because no 'error' event + // handler has been added. + ee.emit('error', new Error('This will crash')); +}); +``` Errors generated in this way *cannot* be intercepted using `try / catch` as they are thrown *after* the calling code has already exited. @@ -133,37 +137,41 @@ either completes or an error is raised, the callback function is called with the Error object (if any) passed as the first argument. If no error was raised, the first argument will be passed as `null`. - const fs = require('fs'); +```js +const fs = require('fs'); - function nodeStyleCallback(err, data) { - if (err) { - console.error('There was an error', err); - return; - } - console.log(data); - } +function nodeStyleCallback(err, data) { + if (err) { + console.error('There was an error', err); + return; + } + console.log(data); +} - fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback); - fs.readFile('/some/file/that/does-exist', nodeStyleCallback) +fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback); +fs.readFile('/some/file/that/does-exist', nodeStyleCallback) +``` The JavaScript `try / catch` mechanism **cannot** be used to intercept errors generated by asynchronous APIs. A common mistake for beginners is to try to use `throw` inside a Node.js style callback: - // THIS WILL NOT WORK: - const fs = require('fs'); - - try { - fs.readFile('/some/file/that/does-not-exist', (err, data) => { - // mistaken assumption: throwing here... - if (err) { - throw err; - } - }); - } catch(err) { - // This will not catch the throw! - console.log(err); +```js +// THIS WILL NOT WORK: +const fs = require('fs'); + +try { + fs.readFile('/some/file/that/does-not-exist', (err, data) => { + // mistaken assumption: throwing here... + if (err) { + throw err; } + }); +} catch(err) { + // This will not catch the throw! + console.log(err); +} +``` This will not work because the callback function passed to `fs.readFile()` is called asynchronously. By the time the callback has been called, the @@ -201,9 +209,11 @@ Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. - const myObject = {}; - Error.captureStackTrace(myObject); - myObject.stack // similar to `new Error().stack` +```js +const myObject = {}; +Error.captureStackTrace(myObject); +myObject.stack // similar to `new Error().stack` +``` The first line of the trace, instead of being prefixed with `ErrorType: message`, will be the result of calling `targetObject.toString()`. @@ -215,14 +225,16 @@ generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from an end user. For instance: - function MyError() { - Error.captureStackTrace(this, MyError); - } +```js +function MyError() { + Error.captureStackTrace(this, MyError); +} - // Without passing MyError to captureStackTrace, the MyError - // frame would should up in the .stack property. by passing - // the constructor, we omit that frame and all frames above it. - new MyError().stack +// Without passing MyError to captureStackTrace, the MyError +// frame would should up in the .stack property. by passing +// the constructor, we omit that frame and all frames above it. +new MyError().stack +``` ### Error.stackTraceLimit @@ -243,9 +255,11 @@ The `message` passed to the constructor will also appear in the first line of the stack trace of the `Error`, however changing this property after the `Error` object is created *may not* change the first line of the stack trace. - const err = new Error('The message'); - console.log(err.message); - // Prints: The message +```js +const err = new Error('The message'); +console.log(err.message); + // Prints: The message +``` #### error.stack @@ -254,11 +268,13 @@ instantiated. For example: - Error: Things keep happening! - at /home/gbusey/file.js:525:2 - at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21) - at Actor. (/home/gbusey/actors.js:400:8) - at increaseSynergy (/home/gbusey/actors.js:701:6) +``` +Error: Things keep happening! + at /home/gbusey/file.js:525:2 + at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21) + at Actor. (/home/gbusey/actors.js:400:8) + at increaseSynergy (/home/gbusey/actors.js:701:6) +``` The first line is formatted as `: `, and is followed by a series of stack frames (each line beginning with "at "). @@ -276,30 +292,32 @@ function called `cheetahify`, which itself calls a JavaScript function, the frame representing the `cheetahify` call will **not** be present in the stack traces: - const cheetahify = require('./native-binding.node'); - - function makeFaster() { - // cheetahify *synchronously* calls speedy. - cheetahify(function speedy() { - throw new Error('oh no!'); - }); - } +```js +const cheetahify = require('./native-binding.node'); - makeFaster(); // will throw: - // /home/gbusey/file.js:6 - // throw new Error('oh no!'); - // ^ - // Error: oh no! - // at speedy (/home/gbusey/file.js:6:11) - // at makeFaster (/home/gbusey/file.js:5:3) - // at Object. (/home/gbusey/file.js:10:1) - // at Module._compile (module.js:456:26) - // at Object.Module._extensions..js (module.js:474:10) - // at Module.load (module.js:356:32) - // at Function.Module._load (module.js:312:12) - // at Function.Module.runMain (module.js:497:10) - // at startup (node.js:119:16) - // at node.js:906:3 +function makeFaster() { + // cheetahify *synchronously* calls speedy. + cheetahify(function speedy() { + throw new Error('oh no!'); + }); +} + +makeFaster(); // will throw: + // /home/gbusey/file.js:6 + // throw new Error('oh no!'); + // ^ + // Error: oh no! + // at speedy (/home/gbusey/file.js:6:11) + // at makeFaster (/home/gbusey/file.js:5:3) + // at Object. (/home/gbusey/file.js:10:1) + // at Module._compile (module.js:456:26) + // at Object.Module._extensions..js (module.js:474:10) + // at Module.load (module.js:356:32) + // at Function.Module._load (module.js:312:12) + // at Function.Module.runMain (module.js:497:10) + // at startup (node.js:119:16) + // at node.js:906:3 +``` The location information will be one of: @@ -327,8 +345,10 @@ range, or outside the set of options for a given function parameter. For example: - require('net').connect(-1); - // throws RangeError, port should be > 0 && < 65536 +```js +require('net').connect(-1); + // throws RangeError, port should be > 0 && < 65536 +``` Node.js will generate and throw `RangeError` instances *immediately* as a form of argument validation. @@ -342,19 +362,23 @@ an otherwise broken program. While client code may generate and propagate these errors, in practice, only V8 will do so. - doesNotExist; - // throws ReferenceError, doesNotExist is not a variable in this program. +```js +doesNotExist; + // throws ReferenceError, doesNotExist is not a variable in this program. +``` `ReferenceError` instances will have an `error.arguments` property whose value is an array containing a single element: a string representing the variable that was not defined. - const assert = require('assert'); - try { - doesNotExist; - } catch(err) { - assert(err.arguments[0], 'doesNotExist'); - } +```js +const assert = require('assert'); +try { + doesNotExist; +} catch(err) { + assert(err.arguments[0], 'doesNotExist'); +} +``` Unless an application is dynamically generating and running code, `ReferenceError` instances should always be considered a bug in the code @@ -368,11 +392,13 @@ evaluation. Code evaluation may happen as a result of `eval`, `Function`, `require`, or [vm][]. These errors are almost always indicative of a broken program. - try { - require('vm').runInThisContext('binary ! isNotOk'); - } catch(err) { - // err will be a SyntaxError - } +```js +try { + require('vm').runInThisContext('binary ! isNotOk'); +} catch(err) { + // err will be a SyntaxError +} +``` `SyntaxError` instances are unrecoverable in the context that created them – they may only be caught by other contexts. @@ -383,8 +409,10 @@ A subclass of `Error` that indicates that a provided argument is not an allowable type. For example, passing a function to a parameter which expects a string would be considered a TypeError. - require('url').parse(function() { }); - // throws TypeError, since it expected a string +```js +require('url').parse(function() { }); + // throws TypeError, since it expected a string +``` Node.js will generate and throw `TypeError` instances *immediately* as a form of argument validation. diff --git a/doc/api/events.markdown b/doc/api/events.markdown index 0fdfc07874..3aa996a95d 100644 --- a/doc/api/events.markdown +++ b/doc/api/events.markdown @@ -27,34 +27,38 @@ The following example shows a simple `EventEmitter` instance with a single listener. The `eventEmitter.on()` method is used to register listeners, while the `eventEmitter.emit()` method is used to trigger the event. - const EventEmitter = require('events'); - const util = require('util'); - - function MyEmitter() { - EventEmitter.call(this); - } - util.inherits(MyEmitter, EventEmitter); - - const myEmitter = new MyEmitter(); - myEmitter.on('event', function() { - console.log('an event occurred!'); - }); - myEmitter.emit('event'); +```js +const EventEmitter = require('events'); +const util = require('util'); + +function MyEmitter() { + EventEmitter.call(this); +} +util.inherits(MyEmitter, EventEmitter); + +const myEmitter = new MyEmitter(); +myEmitter.on('event', function() { + console.log('an event occurred!'); +}); +myEmitter.emit('event'); +``` Any object can become an `EventEmitter` through inheritance. The example above uses the traditional Node.js style prototypical inheritance using the `util.inherits()` method. It is, however, possible to use ES6 classes as well: - const EventEmitter = require('events'); +```js +const EventEmitter = require('events'); - class MyEmitter extends EventEmitter {} +class MyEmitter extends EventEmitter {} - const myEmitter = new MyEmitter(); - myEmitter.on('event', function() { - console.log('an event occurred!'); - }); - myEmitter.emit('event'); +const myEmitter = new MyEmitter(); +myEmitter.on('event', function() { + console.log('an event occurred!'); +}); +myEmitter.emit('event'); +``` ## Passing arguments and `this` to listeners @@ -64,27 +68,31 @@ ordinary listener function is called by the `EventEmitter`, the standard `this` keyword is intentionally set to reference the `EventEmitter` to which the listener is attached. - const myEmitter = new MyEmitter(); - myEmitter.on('event', function(a, b) { - console.log(a, b, this); - // Prints: - // a b MyEmitter { - // domain: null, - // _events: { event: [Function] }, - // _eventsCount: 1, - // _maxListeners: undefined } - }); - myEmitter.emit('event', 'a', 'b'); +```js +const myEmitter = new MyEmitter(); +myEmitter.on('event', function(a, b) { + console.log(a, b, this); + // Prints: + // a b MyEmitter { + // domain: null, + // _events: { event: [Function] }, + // _eventsCount: 1, + // _maxListeners: undefined } +}); +myEmitter.emit('event', 'a', 'b'); +``` It is possible to use ES6 Arrow Functions as listeners, however, when doing so, the `this` keyword will no longer reference the `EventEmitter` instance: - const myEmitter = new MyEmitter(); - myEmitter.on('event', (a, b) => { - console.log(a, b, this); - // Prints: a b {} - }); - myEmitter.emit('event', 'a', 'b'); +```js +const myEmitter = new MyEmitter(); +myEmitter.on('event', (a, b) => { + console.log(a, b, this); + // Prints: a b {} +}); +myEmitter.emit('event', 'a', 'b'); +``` ## Asynchronous vs. Synchronous @@ -94,41 +102,47 @@ events and to avoid race conditions or logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the `setImmediate()` or `process.nextTick()` methods: - const myEmitter = new MyEmitter(); - myEmitter.on('event', (a, b) => { - setImmediate(() => { - console.log('this happens asynchronously'); - }); - }); - myEmitter.emit('event', 'a', 'b'); +```js +const myEmitter = new MyEmitter(); +myEmitter.on('event', (a, b) => { + setImmediate(() => { + console.log('this happens asynchronously'); + }); +}); +myEmitter.emit('event', 'a', 'b'); +``` ## Handling events only once When a listener is registered using the `eventEmitter.on()` method, that listener will be invoked _every time_ the named event is emitted. - const myEmitter = new MyEmitter(); - var m = 0; - myEmitter.on('event', () => { - console.log(++m); - }); - myEmitter.emit('event'); - // Prints: 1 - myEmitter.emit('event'); - // Prints: 2 +```js +const myEmitter = new MyEmitter(); +var m = 0; +myEmitter.on('event', () => { + console.log(++m); +}); +myEmitter.emit('event'); + // Prints: 1 +myEmitter.emit('event'); + // Prints: 2 +``` Using the `eventEmitter.once()` method, it is possible to register a listener that is immediately unregistered after it is called. - const myEmitter = new MyEmitter(); - var m = 0; - myEmitter.once('event', () => { - console.log(++m); - }); - myEmitter.emit('event'); - // Prints: 1 - myEmitter.emit('event'); - // Ignored +```js +const myEmitter = new MyEmitter(); +var m = 0; +myEmitter.once('event', () => { + console.log(++m); +}); +myEmitter.emit('event'); + // Prints: 1 +myEmitter.emit('event'); + // Ignored +``` ## Error events @@ -140,39 +154,47 @@ If an `EventEmitter` does _not_ have at least one listener registered for the `'error'` event, and an `'error'` event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits. - const myEmitter = new MyEmitter(); - myEmitter.emit('error', new Error('whoops!')); - // Throws and crashes Node.js +```js +const myEmitter = new MyEmitter(); +myEmitter.emit('error', new Error('whoops!')); + // Throws and crashes Node.js +``` To guard against crashing the Node.js process, developers can either register a listener for the `process.on('uncaughtException')` event or use the [`domain`][] module (_Note, however, that the `domain` module has been deprecated_). - const myEmitter = new MyEmitter(); +```js +const myEmitter = new MyEmitter(); - process.on('uncaughtException', (err) => { - console.log('whoops! there was an error'); - }); +process.on('uncaughtException', (err) => { + console.log('whoops! there was an error'); +}); - myEmitter.emit('error', new Error('whoops!')); - // Prints: whoops! there was an error +myEmitter.emit('error', new Error('whoops!')); + // Prints: whoops! there was an error +``` As a best practice, developers should always register listeners for the `'error'` event: - const myEmitter = new MyEmitter(); - myEmitter.on('error', (err) => { - console.log('whoops! there was an error'); - }); - myEmitter.emit('error', new Error('whoops!')); - // Prints: whoops! there was an error +```js +const myEmitter = new MyEmitter(); +myEmitter.on('error', (err) => { + console.log('whoops! there was an error'); +}); +myEmitter.emit('error', new Error('whoops!')); + // Prints: whoops! there was an error +``` ## Class: EventEmitter The `EventEmitter` class is defined and exposed by the `events` module: - const EventEmitter = require('events'); +```js +const EventEmitter = require('events'); +``` All EventEmitters emit the event `'newListener'` when new listeners are added and `'removeListener'` when a listener is removed. @@ -193,23 +215,25 @@ but important side effect: any *additional* listeners registered to the same `name` *within* the `'newListener'` callback will be inserted *before* the listener that is in the process of being added. - const myEmitter = new MyEmitter(); - // Only do this once so we don't loop forever - myEmitter.once('newListener', (event, listener) => { - if (event === 'event') { - // Insert a new listener in front - myEmitter.on('event', () => { - console.log('B'); - }); - } - }); +```js +const myEmitter = new MyEmitter(); +// Only do this once so we don't loop forever +myEmitter.once('newListener', (event, listener) => { + if (event === 'event') { + // Insert a new listener in front myEmitter.on('event', () => { - console.log('A'); + console.log('B'); }); - myEmitter.emit('event'); - // Prints: - // B - // A + } +}); +myEmitter.on('event', () => { + console.log('A'); +}); +myEmitter.emit('event'); + // Prints: + // B + // A +``` ### Event: 'removeListener' @@ -225,11 +249,13 @@ The `'removeListener'` event is emitted *after* a listener is removed. A class method that returns the number of listeners for the given `event` registered on the given `emitter`. - const myEmitter = new MyEmitter(); - myEmitter.on('event', () => {}); - myEmitter.on('event', () => {}); - console.log(EventEmitter.listenerCount(myEmitter, 'event')); - // Prints: 2 +```js +const myEmitter = new MyEmitter(); +myEmitter.on('event', () => {}); +myEmitter.on('event', () => {}); +console.log(EventEmitter.listenerCount(myEmitter, 'event')); + // Prints: 2 +``` ### EventEmitter.defaultMaxListeners @@ -250,11 +276,13 @@ that a `possible EventEmitter memory leak` has been detected. For any single `EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` methods can be used to temporarily avoid this warning: - emitter.setMaxListeners(emitter.getMaxListeners() + 1); - emitter.once('event', () => { - // do stuff - emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); - }); +```js +emitter.setMaxListeners(emitter.getMaxListeners() + 1); +emitter.once('event', () => { + // do stuff + emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); +}); +``` ### emitter.addListener(event, listener) @@ -283,11 +311,13 @@ Returns the number of listeners listening to the `event` type. Returns a copy of the array of listeners for the specified `event`. - server.on('connection', (stream) => { - console.log('someone connected!'); - }); - console.log(util.inspect(server.listeners('connection'))); - // Prints: [ [Function] ] +```js +server.on('connection', (stream) => { + console.log('someone connected!'); +}); +console.log(util.inspect(server.listeners('connection'))); + // Prints: [ [Function] ] +``` ### emitter.on(event, listener) @@ -297,9 +327,11 @@ been added. Multiple calls passing the same combination of `event` and `listener` will result in the `listener` being added, and called, multiple times. - server.on('connection', (stream) => { - console.log('someone connected!'); - }); +```js +server.on('connection', (stream) => { + console.log('someone connected!'); +}); +``` Returns a reference to the `EventEmitter` so calls can be chained. @@ -308,9 +340,11 @@ Returns a reference to the `EventEmitter` so calls can be chained. Adds a **one time** `listener` function for the `event`. This listener is invoked only the next time `event` is triggered, after which it is removed. - server.once('connection', (stream) => { - console.log('Ah, we have our first user!'); - }); +```js +server.once('connection', (stream) => { + console.log('Ah, we have our first user!'); +}); +``` Returns a reference to the `EventEmitter` so calls can be chained. @@ -329,12 +363,14 @@ Returns a reference to the `EventEmitter` so calls can be chained. Removes the specified `listener` from the listener array for the specified `event`. - var callback = function(stream) { - console.log('someone connected!'); - }; - server.on('connection', callback); - // ... - server.removeListener('connection', callback); +```js +var callback = function(stream) { + console.log('someone connected!'); +}; +server.on('connection', callback); +// ... +server.removeListener('connection', callback); +``` `removeListener` will remove, at most, one instance of a listener from the listener array. If any single listener has been added multiple times to the diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 0f2c2575bb..9a7a50d68c 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -18,42 +18,50 @@ You can use try/catch to handle exceptions or allow them to bubble up. Here is an example of the asynchronous version: - const fs = require('fs'); +```js +const fs = require('fs'); - fs.unlink('/tmp/hello', (err) => { - if (err) throw err; - console.log('successfully deleted /tmp/hello'); - }); +fs.unlink('/tmp/hello', (err) => { + if (err) throw err; + console.log('successfully deleted /tmp/hello'); +}); +``` Here is the synchronous version: - const fs = require('fs'); +```js +const fs = require('fs'); - fs.unlinkSync('/tmp/hello'); - console.log('successfully deleted /tmp/hello'); +fs.unlinkSync('/tmp/hello'); +console.log('successfully deleted /tmp/hello'); +``` With the asynchronous methods there is no guaranteed ordering. So the following is prone to error: - fs.rename('/tmp/hello', '/tmp/world', (err) => { - if (err) throw err; - console.log('renamed complete'); - }); - fs.stat('/tmp/world', (err, stats) => { - if (err) throw err; - console.log(`stats: ${JSON.stringify(stats)}`); - }); +```js +fs.rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + console.log('renamed complete'); +}); +fs.stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); +}); +``` It could be that `fs.stat` is executed before `fs.rename`. The correct way to do this is to chain the callbacks. - fs.rename('/tmp/hello', '/tmp/world', (err) => { - if (err) throw err; - fs.stat('/tmp/world', (err, stats) => { - if (err) throw err; - console.log(`stats: ${JSON.stringify(stats)}`); - }); - }); +```js +fs.rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + fs.stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); + }); +}); +``` In busy processes, the programmer is _strongly encouraged_ to use the asynchronous versions of these calls. The synchronous versions will block @@ -66,23 +74,25 @@ Most fs functions let you omit the callback argument. If you do, a default callback is used that rethrows errors. To get a trace to the original call site, set the `NODE_DEBUG` environment variable: - $ cat script.js - function bad() { - require('fs').readFile('/'); - } - bad(); - - $ env NODE_DEBUG=fs node script.js - fs.js:66 - throw err; - ^ - Error: EISDIR, read - at rethrow (fs.js:61:21) - at maybeCallback (fs.js:79:42) - at Object.fs.readFile (fs.js:153:18) - at bad (/path/to/script.js:2:17) - at Object. (/path/to/script.js:5:1) - +``` +$ cat script.js +function bad() { + require('fs').readFile('/'); +} +bad(); + +$ env NODE_DEBUG=fs node script.js +fs.js:66 + throw err; + ^ +Error: EISDIR, read + at rethrow (fs.js:61:21) + at maybeCallback (fs.js:79:42) + at Object.fs.readFile (fs.js:153:18) + at bad (/path/to/script.js:2:17) + at Object. (/path/to/script.js:5:1) + +``` ## Class: fs.FSWatcher @@ -136,20 +146,24 @@ synchronous counterparts are of this type. For a regular file [`util.inspect(stats)`][] would return a string very similar to this: - { dev: 2114, - ino: 48064969, - mode: 33188, - nlink: 1, - uid: 85, - gid: 100, - rdev: 0, - size: 527, - blksize: 4096, - blocks: 8, - atime: Mon, 10 Oct 2011 23:24:11 GMT, - mtime: Mon, 10 Oct 2011 23:24:11 GMT, - ctime: Mon, 10 Oct 2011 23:24:11 GMT, - birthtime: Mon, 10 Oct 2011 23:24:11 GMT } +```js +{ + dev: 2114, + ino: 48064969, + mode: 33188, + nlink: 1, + uid: 85, + gid: 100, + rdev: 0, + size: 527, + blksize: 4096, + blocks: 8, + atime: Mon, 10 Oct 2011 23:24:11 GMT, + mtime: Mon, 10 Oct 2011 23:24:11 GMT, + ctime: Mon, 10 Oct 2011 23:24:11 GMT, + birthtime: Mon, 10 Oct 2011 23:24:11 GMT +} +``` Please note that `atime`, `mtime`, `birthtime`, and `ctime` are instances of [`Date`][MDN-Date] object and to compare the values of @@ -224,9 +238,11 @@ a possible error argument. If any of the accessibility checks fail, the error argument will be populated. The following example checks if the file `/etc/passwd` can be read and written by the current process. - fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) { - console.log(err ? 'no access!' : 'can read/write'); - }); +```js +fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) { + console.log(err ? 'no access!' : 'can read/write'); +}); +``` ## fs.accessSync(path[, mode]) @@ -248,14 +264,18 @@ Asynchronously append data to a file, creating the file if it does not yet exist Example: - fs.appendFile('message.txt', 'data to append', (err) => { - if (err) throw err; - console.log('The "data to append" was appended to file!'); - }); +```js +fs.appendFile('message.txt', 'data to append', (err) => { + if (err) throw err; + console.log('The "data to append" was appended to file!'); +}); +``` If `options` is a string, then it specifies the encoding. Example: - fs.appendFile('message.txt', 'data to append', 'utf8', callback); +```js +fs.appendFile('message.txt', 'data to append', 'utf8', callback); +``` Any specified file descriptor has to have been opened for appending. @@ -302,12 +322,15 @@ default value of 64 kb for the same parameter. `options` is an object or string with the following defaults: - { flags: 'r', - encoding: null, - fd: null, - mode: 0o666, - autoClose: true - } +```js +{ + flags: 'r', + encoding: null, + fd: null, + mode: 0o666, + autoClose: true +} +``` `options` can include `start` and `end` values to read a range of bytes from the file instead of the entire file. Both `start` and `end` are inclusive and @@ -329,7 +352,9 @@ file was created. An example to read the last 10 bytes of a file which is 100 bytes long: - fs.createReadStream('sample.txt', {start: 90, end: 99}); +```js +fs.createReadStream('sample.txt', {start: 90, end: 99}); +``` If `options` is a string, then it specifies the encoding. @@ -339,11 +364,15 @@ Returns a new [`WriteStream`][] object. (See [Writable Stream][]). `options` is an object or string with the following defaults: - { flags: 'w', - defaultEncoding: 'utf8', - fd: null, - mode: 0o666, - autoClose: true } +```js +{ + flags: 'w', + defaultEncoding: 'utf8', + fd: null, + mode: 0o666, + autoClose: true +} +``` `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather @@ -370,9 +399,11 @@ If `options` is a string, then it specifies the encoding. Test whether or not the given path exists by checking with the file system. Then call the `callback` argument with either true or false. Example: - fs.exists('/etc/passwd', (exists) => { - console.log(exists ? 'it\'s there' : 'no passwd!'); - }); +```js +fs.exists('/etc/passwd', (exists) => { + console.log(exists ? 'it\'s there' : 'no passwd!'); +}); +``` `fs.exists()` should not be used to check if a file exists before calling `fs.open()`. Doing so introduces a race condition since other processes may @@ -594,10 +625,12 @@ Synchronous readdir(3). Returns an array of filenames excluding `'.'` and Asynchronously reads the entire contents of a file. Example: - fs.readFile('/etc/passwd', (err, data) => { - if (err) throw err; - console.log(data); - }); +```js +fs.readFile('/etc/passwd', (err, data) => { + if (err) throw err; + console.log(data); +}); +``` The callback is passed two arguments `(err, data)`, where `data` is the contents of the file. @@ -606,7 +639,9 @@ If no encoding is specified, then the raw buffer is returned. If `options` is a string, then it specifies the encoding. Example: - fs.readFile('/etc/passwd', 'utf8', callback); +```js +fs.readFile('/etc/passwd', 'utf8', callback); +``` Any specified file descriptor has to support reading. @@ -637,11 +672,13 @@ resolution or avoid additional `fs.stat` calls for known real paths. Example: - var cache = {'/etc':'/private/etc'}; - fs.realpath('/etc/passwd', cache, (err, resolvedPath) => { - if (err) throw err; - console.log(resolvedPath); - }); +```js +var cache = {'/etc':'/private/etc'}; +fs.realpath('/etc/passwd', cache, (err, resolvedPath) => { + if (err) throw err; + console.log(resolvedPath); +}); +``` ## fs.readSync(fd, buffer, offset, length, position) @@ -692,7 +729,9 @@ Note that Windows junction points require the destination path to be absolute. Here is an example below: - fs.symlink('./foo', './new-port'); +```js +fs.symlink('./foo', './new-port'); +``` It would create a symlic link named with "new-port" that points to "foo". @@ -805,14 +844,16 @@ Windows. Even on supported platforms, `filename` is not always guaranteed to be provided. Therefore, don't assume that `filename` argument is always provided in the callback, and have some fallback logic if it is null. - fs.watch('somedir', (event, filename) => { - console.log(`event is: ${event}`); - if (filename) { - console.log(`filename provided: ${filename}`); - } else { - console.log('filename not provided'); - } - }); +```js +fs.watch('somedir', (event, filename) => { + console.log(`event is: ${event}`); + if (filename) { + console.log(`filename provided: ${filename}`); + } else { + console.log('filename not provided'); + } +}); +``` ## fs.watchFile(filename[, options], listener) @@ -829,10 +870,12 @@ target should be polled in milliseconds. The default is The `listener` gets two arguments the current stat object and the previous stat object: - fs.watchFile('message.text', (curr, prev) => { - console.log(`the current mtime is: ${curr.mtime}`); - console.log(`the previous mtime was: ${prev.mtime}`); - }); +```js +fs.watchFile('message.text', (curr, prev) => { + console.log(`the current mtime is: ${curr.mtime}`); + console.log(`the previous mtime was: ${prev.mtime}`); +}); +``` These stat objects are instances of `fs.Stat`. @@ -915,14 +958,18 @@ to `'utf8'`. Example: - fs.writeFile('message.txt', 'Hello Node.js', (err) => { - if (err) throw err; - console.log('It\'s saved!'); - }); +```js +fs.writeFile('message.txt', 'Hello Node.js', (err) => { + if (err) throw err; + console.log('It\'s saved!'); +}); +``` If `options` is a string, then it specifies the encoding. Example: - fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback); +```js +fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback); +``` Any specified file descriptor has to support writing. diff --git a/doc/api/globals.markdown b/doc/api/globals.markdown index 5ac7bd9a0c..90c1a306a4 100644 --- a/doc/api/globals.markdown +++ b/doc/api/globals.markdown @@ -23,8 +23,10 @@ The name of the directory that the currently executing script resides in. Example: running `node example.js` from `/Users/mjr` - console.log(__dirname); - // /Users/mjr +```js +console.log(__dirname); +// /Users/mjr +``` `__dirname` isn't actually a global but rather local to each module. @@ -41,8 +43,10 @@ to that module file. Example: running `node example.js` from `/Users/mjr` - console.log(__filename); - // /Users/mjr/example.js +```js +console.log(__filename); +// /Users/mjr/example.js +``` `__filename` isn't actually a global but rather local to each module. @@ -139,7 +143,9 @@ Instruct `require` on how to handle certain file extensions. Process files with the extension `.sjs` as `.js`: - require.extensions['.sjs'] = require.extensions['.js']; +```js +require.extensions['.sjs'] = require.extensions['.js']; +``` **Deprecated** In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 74941cc578..079736b0a4 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -12,11 +12,13 @@ user is able to stream data. HTTP message headers are represented by an object like this: - { 'content-length': '123', - 'content-type': 'text/plain', - 'connection': 'keep-alive', - 'host': 'mysite.com', - 'accept': '*/*' } +``` +{ 'content-length': '123', + 'content-type': 'text/plain', + 'connection': 'keep-alive', + 'host': 'mysite.com', + 'accept': '*/*' } +``` Keys are lowercased. Values are not modified. @@ -32,12 +34,14 @@ property, which is an array of `[key, value, key2, value2, ...]`. For example, the previous message header object might have a `rawHeaders` list like the following: - [ 'ConTent-Length', '123456', - 'content-LENGTH', '123', - 'content-type', 'text/plain', - 'CONNECTION', 'keep-alive', - 'Host', 'mysite.com', - 'accepT', '*/*' ] +``` +[ 'ConTent-Length', '123456', + 'content-LENGTH', '123', + 'content-type', 'text/plain', + 'CONNECTION', 'keep-alive', + 'Host', 'mysite.com', + 'accepT', '*/*' ] +``` ## Class: http.Agent @@ -64,23 +68,27 @@ a `'close'` event or a special `'agentRemove'` event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of: - http.get(options, (res) => { - // Do stuff - }).on('socket', (socket) => { - socket.emit('agentRemove'); - }); +```js +http.get(options, (res) => { + // Do stuff +}).on('socket', (socket) => { + socket.emit('agentRemove'); +}); +``` Alternatively, you could just opt out of pooling entirely using `agent:false`: - http.get({ - hostname: 'localhost', - port: 80, - path: '/', - agent: false // create a new agent just for this one request - }, (res) => { - // Do stuff with response - }) +```js +http.get({ + hostname: 'localhost', + port: 80, + path: '/', + agent: false // create a new agent just for this one request +}, (res) => { + // Do stuff with response +}) +``` ### new Agent([options]) @@ -102,7 +110,7 @@ of these values set to their respective defaults. To configure any of them, you must create your own [`http.Agent`][] object. -```javascript +```js const http = require('http'); var keepAliveAgent = new http.Agent({ keepAlive: true }); options.agent = keepAliveAgent; @@ -213,58 +221,60 @@ their connections closed. A client server pair that show you how to listen for the `'connect'` event. - const http = require('http'); - const net = require('net'); - const url = require('url'); - - // Create an HTTP tunneling proxy - var proxy = http.createServer( (req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('okay'); - }); - proxy.on('connect', (req, cltSocket, head) => { - // connect to an origin server - var srvUrl = url.parse(`http://${req.url}`); - var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => { - cltSocket.write('HTTP/1.1 200 Connection Established\r\n' + - 'Proxy-agent: Node.js-Proxy\r\n' + - '\r\n'); - srvSocket.write(head); - srvSocket.pipe(cltSocket); - cltSocket.pipe(srvSocket); - }); +```js +const http = require('http'); +const net = require('net'); +const url = require('url'); + +// Create an HTTP tunneling proxy +var proxy = http.createServer( (req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('okay'); +}); +proxy.on('connect', (req, cltSocket, head) => { + // connect to an origin server + var srvUrl = url.parse(`http://${req.url}`); + var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => { + cltSocket.write('HTTP/1.1 200 Connection Established\r\n' + + 'Proxy-agent: Node.js-Proxy\r\n' + + '\r\n'); + srvSocket.write(head); + srvSocket.pipe(cltSocket); + cltSocket.pipe(srvSocket); + }); +}); + +// now that proxy is running +proxy.listen(1337, '127.0.0.1', () => { + + // make a request to a tunneling proxy + var options = { + port: 1337, + hostname: '127.0.0.1', + method: 'CONNECT', + path: 'www.google.com:80' + }; + + var req = http.request(options); + req.end(); + + req.on('connect', (res, socket, head) => { + console.log('got connected!'); + + // make a request over an HTTP tunnel + socket.write('GET / HTTP/1.1\r\n' + + 'Host: www.google.com:80\r\n' + + 'Connection: close\r\n' + + '\r\n'); + socket.on('data', (chunk) => { + console.log(chunk.toString()); }); - - // now that proxy is running - proxy.listen(1337, '127.0.0.1', () => { - - // make a request to a tunneling proxy - var options = { - port: 1337, - hostname: '127.0.0.1', - method: 'CONNECT', - path: 'www.google.com:80' - }; - - var req = http.request(options); - req.end(); - - req.on('connect', (res, socket, head) => { - console.log('got connected!'); - - // make a request over an HTTP tunnel - socket.write('GET / HTTP/1.1\r\n' + - 'Host: www.google.com:80\r\n' + - 'Connection: close\r\n' + - '\r\n'); - socket.on('data', (chunk) => { - console.log(chunk.toString()); - }); - socket.on('end', () => { - proxy.close(); - }); - }); + socket.on('end', () => { + proxy.close(); }); + }); +}); +``` ### Event: 'continue' @@ -303,44 +313,46 @@ their connections closed. A client server pair that show you how to listen for the `'upgrade'` event. - const http = require('http'); - - // Create an HTTP server - var srv = http.createServer( (req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('okay'); - }); - srv.on('upgrade', (req, socket, head) => { - socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + - 'Upgrade: WebSocket\r\n' + - 'Connection: Upgrade\r\n' + - '\r\n'); - - socket.pipe(socket); // echo back - }); +```js +const http = require('http'); - // now that server is running - srv.listen(1337, '127.0.0.1', () => { - - // make a request - var options = { - port: 1337, - hostname: '127.0.0.1', - headers: { - 'Connection': 'Upgrade', - 'Upgrade': 'websocket' - } - }; - - var req = http.request(options); - req.end(); - - req.on('upgrade', (res, socket, upgradeHead) => { - console.log('got upgraded!'); - socket.end(); - process.exit(0); - }); - }); +// Create an HTTP server +var srv = http.createServer( (req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('okay'); +}); +srv.on('upgrade', (req, socket, head) => { + socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + + 'Upgrade: WebSocket\r\n' + + 'Connection: Upgrade\r\n' + + '\r\n'); + + socket.pipe(socket); // echo back +}); + +// now that server is running +srv.listen(1337, '127.0.0.1', () => { + + // make a request + var options = { + port: 1337, + hostname: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket' + } + }; + + var req = http.request(options); + req.end(); + + req.on('upgrade', (res, socket, upgradeHead) => { + console.log('got upgraded!'); + socket.end(); + process.exit(0); + }); +}); +``` ### request.abort() @@ -624,11 +636,13 @@ be silently discarded. Note that HTTP requires the `Trailer` header to be sent if you intend to emit trailers, with a list of the header fields in its value. E.g., - response.writeHead(200, { 'Content-Type': 'text/plain', - 'Trailer': 'Content-MD5' }); - response.write(fileData); - response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'}); - response.end(); +```js +response.writeHead(200, { 'Content-Type': 'text/plain', + 'Trailer': 'Content-MD5' }); +response.write(fileData); +response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'}); +response.end(); +``` Attempting to set a trailer field name that contains invalid characters will result in a [`TypeError`][] being thrown. @@ -658,7 +672,9 @@ implicitly flushed. Example: - var contentType = response.getHeader('content-type'); +```js +var contentType = response.getHeader('content-type'); +``` ### response.headersSent @@ -670,7 +686,9 @@ Removes a header that's queued for implicit sending. Example: - response.removeHeader('Content-Encoding'); +```js +response.removeHeader('Content-Encoding'); +``` ### response.sendDate @@ -688,11 +706,15 @@ here if you need to send multiple headers with the same name. Example: - response.setHeader('Content-Type', 'text/html'); +```js +response.setHeader('Content-Type', 'text/html'); +``` or - response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); +```js +response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); +``` Attempting to set a header field name that contains invalid characters will result in a [`TypeError`][] being thrown. @@ -722,7 +744,9 @@ the headers get flushed. Example: - response.statusCode = 404; +```js +response.statusCode = 404; +``` After response header was sent to the client, this property indicates the status code which was sent out. @@ -736,7 +760,9 @@ code will be used. Example: - response.statusMessage = 'Not found'; +```js +response.statusMessage = 'Not found'; +``` After response header was sent to the client, this property indicates the status message which was sent out. @@ -781,10 +807,12 @@ argument. Example: - var body = 'hello world'; - response.writeHead(200, { - 'Content-Length': body.length, - 'Content-Type': 'text/plain' }); +```js +var body = 'hello world'; +response.writeHead(200, { + 'Content-Length': body.length, + 'Content-Type': 'text/plain' }); +``` This method must only be called once on a message and it must be called before [`response.end()`][] is called. @@ -823,12 +851,14 @@ The request/response headers object. Key-value pairs of header names and values. Header names are lower-cased. Example: - // Prints something like: - // - // { 'user-agent': 'curl/7.22.0', - // host: '127.0.0.1:8000', - // accept: '*/*' } - console.log(request.headers); +```js +// Prints something like: +// +// { 'user-agent': 'curl/7.22.0', +// host: '127.0.0.1:8000', +// accept: '*/*' } +console.log(request.headers); +``` Duplicates in raw headers are handled in the following ways, depending on the header name: @@ -866,17 +896,19 @@ odd-numbered offsets are the associated values. Header names are not lowercased, and duplicates are not merged. - // Prints something like: - // - // [ 'user-agent', - // 'this is invalid because there can be only one', - // 'User-Agent', - // 'curl/7.22.0', - // 'Host', - // '127.0.0.1:8000', - // 'ACCEPT', - // '*/*' ] - console.log(request.rawHeaders); +```js +// Prints something like: +// +// [ 'user-agent', +// 'this is invalid because there can be only one', +// 'User-Agent', +// 'curl/7.22.0', +// 'Host', +// '127.0.0.1:8000', +// 'ACCEPT', +// '*/*' ] +console.log(request.rawHeaders); +``` ### message.rawTrailers @@ -922,32 +954,44 @@ The request/response trailers object. Only populated at the `'end'` event. Request URL string. This contains only the URL that is present in the actual HTTP request. If the request is: - GET /status?name=ryan HTTP/1.1\r\n - Accept: text/plain\r\n - \r\n +``` +GET /status?name=ryan HTTP/1.1\r\n +Accept: text/plain\r\n +\r\n +``` Then `request.url` will be: - '/status?name=ryan' +``` +'/status?name=ryan' +``` If you would like to parse the URL into its parts, you can use `require('url').parse(request.url)`. Example: - node> require('url').parse('/status?name=ryan') - { href: '/status?name=ryan', - search: '?name=ryan', - query: 'name=ryan', - pathname: '/status' } +``` +node> require('url').parse('/status?name=ryan') +{ + href: '/status?name=ryan', + search: '?name=ryan', + query: 'name=ryan', + pathname: '/status' +} +``` If you would like to extract the params from the query string, you can use the `require('querystring').parse` function, or pass `true` as the second argument to `require('url').parse`. Example: - node> require('url').parse('/status?name=ryan', true) - { href: '/status?name=ryan', - search: '?name=ryan', - query: { name: 'ryan' }, - pathname: '/status' } +``` +node> require('url').parse('/status?name=ryan', true) +{ + href: '/status?name=ryan', + search: '?name=ryan', + query: {name: 'ryan'}, + pathname: '/status' +} +``` ## http.METHODS @@ -985,13 +1029,15 @@ is that it sets the method to GET and calls `req.end()` automatically. Example: - http.get('http://www.google.com/index.html', (res) => { - console.log(`Got response: ${res.statusCode}`); - // consume response body - res.resume(); - }).on('error', (e) => { - console.log(`Got error: ${e.message}`); - }); +```js +http.get('http://www.google.com/index.html', (res) => { + console.log(`Got response: ${res.statusCode}`); + // consume response body + res.resume(); +}).on('error', (e) => { + console.log(`Got error: ${e.message}`); +}); +``` ## http.globalAgent @@ -1043,40 +1089,42 @@ upload a file with a POST request, then write to the `ClientRequest` object. Example: - var postData = querystring.stringify({ - 'msg' : 'Hello World!' - }); - - var options = { - hostname: 'www.google.com', - port: 80, - path: '/upload', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': postData.length - } - }; - - var req = http.request(options, (res) => { - console.log(`STATUS: ${res.statusCode}`); - console.log(`HEADERS: ${JSON.stringify(res.headers)}`); - res.setEncoding('utf8'); - res.on('data', (chunk) => { - console.log(`BODY: ${chunk}`); - }); - res.on('end', () => { - console.log('No more data in response.') - }) - }); - - req.on('error', (e) => { - console.log(`problem with request: ${e.message}`); - }); - - // write data to request body - req.write(postData); - req.end(); +```js +var postData = querystring.stringify({ + 'msg' : 'Hello World!' +}); + +var options = { + hostname: 'www.google.com', + port: 80, + path: '/upload', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': postData.length + } +}; + +var req = http.request(options, (res) => { + console.log(`STATUS: ${res.statusCode}`); + console.log(`HEADERS: ${JSON.stringify(res.headers)}`); + res.setEncoding('utf8'); + res.on('data', (chunk) => { + console.log(`BODY: ${chunk}`); + }); + res.on('end', () => { + console.log('No more data in response.') + }) +}); + +req.on('error', (e) => { + console.log(`problem with request: ${e.message}`); +}); + +// write data to request body +req.write(postData); +req.end(); +``` Note that in the example `req.end()` was called. With `http.request()` one must always call `req.end()` to signify that you're done with the request - diff --git a/doc/api/https.markdown b/doc/api/https.markdown index 9341663374..c39a6c4856 100644 --- a/doc/api/https.markdown +++ b/doc/api/https.markdown @@ -31,33 +31,37 @@ automatically added to the `'request'` event. Example: - // curl -k https://localhost:8000/ - const https = require('https'); - const fs = require('fs'); - - const options = { - key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), - cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') - }; - - https.createServer(options, (req, res) => { - res.writeHead(200); - res.end('hello world\n'); - }).listen(8000); +```js +// curl -k https://localhost:8000/ +const https = require('https'); +const fs = require('fs'); + +const options = { + key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), + cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') +}; + +https.createServer(options, (req, res) => { + res.writeHead(200); + res.end('hello world\n'); +}).listen(8000); +``` Or - const https = require('https'); - const fs = require('fs'); +```js +const https = require('https'); +const fs = require('fs'); - const options = { - pfx: fs.readFileSync('server.pfx') - }; +const options = { + pfx: fs.readFileSync('server.pfx') +}; - https.createServer(options, (req, res) => { - res.writeHead(200); - res.end('hello world\n'); - }).listen(8000); +https.createServer(options, (req, res) => { + res.writeHead(200); + res.end('hello world\n'); +}).listen(8000); +``` ### server.close([callback]) @@ -78,19 +82,21 @@ automatically parsed with [`url.parse()`][]. Example: - const https = require('https'); +```js +const https = require('https'); - https.get('https://encrypted.google.com/', (res) => { - console.log('statusCode: ', res.statusCode); - console.log('headers: ', res.headers); +https.get('https://encrypted.google.com/', (res) => { + console.log('statusCode: ', res.statusCode); + console.log('headers: ', res.headers); - res.on('data', (d) => { - process.stdout.write(d); - }); + res.on('data', (d) => { + process.stdout.write(d); + }); - }).on('error', (e) => { - console.error(e); - }); +}).on('error', (e) => { + console.error(e); +}); +``` ## https.globalAgent @@ -107,28 +113,30 @@ All options from [`http.request()`][] are valid. Example: - const https = require('https'); +```js +const https = require('https'); - var options = { - hostname: 'encrypted.google.com', - port: 443, - path: '/', - method: 'GET' - }; +var options = { + hostname: 'encrypted.google.com', + port: 443, + path: '/', + method: 'GET' +}; - var req = https.request(options, (res) => { - console.log('statusCode: ', res.statusCode); - console.log('headers: ', res.headers); +var req = https.request(options, (res) => { + console.log('statusCode: ', res.statusCode); + console.log('headers: ', res.headers); - res.on('data', (d) => { - process.stdout.write(d); - }); - }); - req.end(); + res.on('data', (d) => { + process.stdout.write(d); + }); +}); +req.end(); - req.on('error', (e) => { - console.error(e); - }); +req.on('error', (e) => { + console.error(e); +}); +``` The options argument has the following options @@ -182,37 +190,41 @@ In order to specify these options, use a custom [`Agent`][]. Example: - var options = { - hostname: 'encrypted.google.com', - port: 443, - path: '/', - method: 'GET', - key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), - cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') - }; - options.agent = new https.Agent(options); - - var req = https.request(options, (res) => { - ... - } +```js +var options = { + hostname: 'encrypted.google.com', + port: 443, + path: '/', + method: 'GET', + key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), + cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') +}; +options.agent = new https.Agent(options); + +var req = https.request(options, (res) => { + ... +} +``` Alternatively, opt out of connection pooling by not using an `Agent`. Example: - var options = { - hostname: 'encrypted.google.com', - port: 443, - path: '/', - method: 'GET', - key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), - cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'), - agent: false - }; - - var req = https.request(options, (res) => { - ... - } +```js +var options = { + hostname: 'encrypted.google.com', + port: 443, + path: '/', + method: 'GET', + key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), + cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'), + agent: false +}; + +var req = https.request(options, (res) => { + ... +} +``` [`Agent`]: #https_class_https_agent [`globalAgent`]: #https_https_globalagent diff --git a/doc/api/modules.markdown b/doc/api/modules.markdown index 7a523c54ac..09a255ab0f 100644 --- a/doc/api/modules.markdown +++ b/doc/api/modules.markdown @@ -10,20 +10,24 @@ in one-to-one correspondence. As an example, `foo.js` loads the module The contents of `foo.js`: - const circle = require('./circle.js'); - console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); +```js +const circle = require('./circle.js'); +console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); +``` The contents of `circle.js`: - const PI = Math.PI; +```js +const PI = Math.PI; - exports.area = function (r) { - return PI * r * r; - }; +exports.area = function (r) { + return PI * r * r; +}; - exports.circumference = function (r) { - return 2 * PI * r; - }; +exports.circumference = function (r) { + return 2 * PI * r; +}; +``` The module `circle.js` has exported the functions `area()` and `circumference()`. To add functions and objects to the root of your module, @@ -39,20 +43,24 @@ instead of `exports`. Below, `bar.js` makes use of the `square` module, which exports a constructor: - const square = require('./square.js'); - var mySquare = square(2); - console.log(`The area of my square is ${mySquare.area()}`); +```js +const square = require('./square.js'); +var mySquare = square(2); +console.log(`The area of my square is ${mySquare.area()}`); +``` The `square` module is defined in `square.js`: - // assigning to exports will not modify module, must use module.exports - module.exports = function(width) { - return { - area: function() { - return width * width; - } - }; +```js +// assigning to exports will not modify module, must use module.exports +module.exports = function(width) { + return { + area: function() { + return width * width; } + }; +} +``` The module system is implemented in the `require("module")` module. @@ -64,7 +72,9 @@ When a file is run directly from Node.js, `require.main` is set to its `module`. That means that you can determine whether a file has been run directly by testing - require.main === module +```js +require.main === module +``` For a file `foo.js`, this will be `true` if run via `node foo.js`, but `false` if run by `require('./foo')`. @@ -137,47 +147,49 @@ the `require.resolve()` function. Putting together all of the above, here is the high-level algorithm in pseudocode of what require.resolve does: - require(X) from module at path Y - 1. If X is a core module, - a. return the core module - b. STOP - 2. If X begins with './' or '/' or '../' - a. LOAD_AS_FILE(Y + X) - b. LOAD_AS_DIRECTORY(Y + X) - 3. LOAD_NODE_MODULES(X, dirname(Y)) - 4. THROW "not found" - - LOAD_AS_FILE(X) - 1. If X is a file, load X as JavaScript text. STOP - 2. If X.js is a file, load X.js as JavaScript text. STOP - 3. If X.json is a file, parse X.json to a JavaScript Object. STOP - 4. If X.node is a file, load X.node as binary addon. STOP - - LOAD_AS_DIRECTORY(X) - 1. If X/package.json is a file, - a. Parse X/package.json, and look for "main" field. - b. let M = X + (json main field) - c. LOAD_AS_FILE(M) - 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP - 3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP - 4. If X/index.node is a file, load X/index.node as binary addon. STOP - - LOAD_NODE_MODULES(X, START) - 1. let DIRS=NODE_MODULES_PATHS(START) - 2. for each DIR in DIRS: - a. LOAD_AS_FILE(DIR/X) - b. LOAD_AS_DIRECTORY(DIR/X) - - NODE_MODULES_PATHS(START) - 1. let PARTS = path split(START) - 2. let I = count of PARTS - 1 - 3. let DIRS = [] - 4. while I >= 0, - a. if PARTS[I] = "node_modules" CONTINUE - c. DIR = path join(PARTS[0 .. I] + "node_modules") - b. DIRS = DIRS + DIR - c. let I = I - 1 - 5. return DIRS +``` +require(X) from module at path Y +1. If X is a core module, + a. return the core module + b. STOP +2. If X begins with './' or '/' or '../' + a. LOAD_AS_FILE(Y + X) + b. LOAD_AS_DIRECTORY(Y + X) +3. LOAD_NODE_MODULES(X, dirname(Y)) +4. THROW "not found" + +LOAD_AS_FILE(X) +1. If X is a file, load X as JavaScript text. STOP +2. If X.js is a file, load X.js as JavaScript text. STOP +3. If X.json is a file, parse X.json to a JavaScript Object. STOP +4. If X.node is a file, load X.node as binary addon. STOP + +LOAD_AS_DIRECTORY(X) +1. If X/package.json is a file, + a. Parse X/package.json, and look for "main" field. + b. let M = X + (json main field) + c. LOAD_AS_FILE(M) +2. If X/index.js is a file, load X/index.js as JavaScript text. STOP +3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP +4. If X/index.node is a file, load X/index.node as binary addon. STOP + +LOAD_NODE_MODULES(X, START) +1. let DIRS=NODE_MODULES_PATHS(START) +2. for each DIR in DIRS: + a. LOAD_AS_FILE(DIR/X) + b. LOAD_AS_DIRECTORY(DIR/X) + +NODE_MODULES_PATHS(START) +1. let PARTS = path split(START) +2. let I = count of PARTS - 1 +3. let DIRS = [] +4. while I >= 0, + a. if PARTS[I] = "node_modules" CONTINUE + c. DIR = path join(PARTS[0 .. I] + "node_modules") + b. DIRS = DIRS + DIR + c. let I = I - 1 +5. return DIRS +``` ## Caching @@ -230,28 +242,34 @@ Consider this situation: `a.js`: - console.log('a starting'); - exports.done = false; - const b = require('./b.js'); - console.log('in a, b.done = %j', b.done); - exports.done = true; - console.log('a done'); +``` +console.log('a starting'); +exports.done = false; +const b = require('./b.js'); +console.log('in a, b.done = %j', b.done); +exports.done = true; +console.log('a done'); +``` `b.js`: - console.log('b starting'); - exports.done = false; - const a = require('./a.js'); - console.log('in b, a.done = %j', a.done); - exports.done = true; - console.log('b done'); +``` +console.log('b starting'); +exports.done = false; +const a = require('./a.js'); +console.log('in b, a.done = %j', a.done); +exports.done = true; +console.log('b done'); +``` `main.js`: - console.log('main starting'); - const a = require('./a.js'); - const b = require('./b.js'); - console.log('in main, a.done=%j, b.done=%j', a.done, b.done); +``` +console.log('main starting'); +const a = require('./a.js'); +const b = require('./b.js'); +console.log('in main, a.done=%j, b.done=%j', a.done, b.done); +``` When `main.js` loads `a.js`, then `a.js` in turn loads `b.js`. At that point, `b.js` tries to load `a.js`. In order to prevent an infinite @@ -262,15 +280,17 @@ provided to the `a.js` module. By the time `main.js` has loaded both modules, they're both finished. The output of this program would thus be: - $ node main.js - main starting - a starting - b starting - in b, a.done = false - b done - in a, b.done = true - a done - in main, a.done=true, b.done=true +``` +$ node main.js +main starting +a starting +b starting +in b, a.done = false +b done +in a, b.done = true +a done +in main, a.done=true, b.done=true +``` If you have cyclic module dependencies in your program, make sure to plan accordingly. @@ -314,8 +334,10 @@ The first is to create a `package.json` file in the root of the folder, which specifies a `main` module. An example package.json file might look like this: - { "name" : "some-library", - "main" : "./lib/some-library.js" } +``` +{ "name" : "some-library", + "main" : "./lib/some-library.js" } +``` If this was in a folder at `./some-library`, then `require('./some-library')` would attempt to load @@ -424,22 +446,26 @@ which is probably not what you want to do. For example suppose we were making a module called `a.js` - const EventEmitter = require('events'); +```js +const EventEmitter = require('events'); - module.exports = new EventEmitter(); +module.exports = new EventEmitter(); - // Do some work, and after some time emit - // the 'ready' event from the module itself. - setTimeout(() => { - module.exports.emit('ready'); - }, 1000); +// Do some work, and after some time emit +// the 'ready' event from the module itself. +setTimeout(() => { + module.exports.emit('ready'); +}, 1000); +``` Then in another file we could do - const a = require('./a'); - a.on('ready', () => { - console.log('module a is ready'); - }); +```js +const a = require('./a'); +a.on('ready', () => { + console.log('module a is ready'); +}); +``` Note that assignment to `module.exports` must be done immediately. It cannot be @@ -447,14 +473,18 @@ done in any callbacks. This does not work: x.js: - setTimeout(() => { - module.exports = { a: 'hello' }; - }, 0); +```js +setTimeout(() => { + module.exports = { a: 'hello' }; +}, 0); +``` y.js: - const x = require('./x'); - console.log(x.a); +```js +const x = require('./x'); +console.log(x.a); +``` #### exports alias @@ -465,16 +495,18 @@ is no longer bound to the previous value. To illustrate the behavior, imagine this hypothetical implementation of `require()`: - function require(...) { - // ... - function (module, exports) { - // Your module code here - exports = some_func; // re-assigns exports, exports is no longer - // a shortcut, and nothing is exported. - module.exports = some_func; // makes your module export 0 - } (module, module.exports); - return module; - } +```js +function require(...) { + // ... + function (module, exports) { + // Your module code here + exports = some_func; // re-assigns exports, exports is no longer + // a shortcut, and nothing is exported. + module.exports = some_func; // makes your module export 0 + } (module, module.exports); + return module; +} +``` As a guideline, if the relationship between `exports` and `module.exports` seems like magic to you, ignore `exports` and only use `module.exports`. diff --git a/doc/api/net.markdown b/doc/api/net.markdown index 7e898596f5..a3cc4716a6 100644 --- a/doc/api/net.markdown +++ b/doc/api/net.markdown @@ -45,15 +45,17 @@ Returns an object with three properties, e.g. Example: - var server = net.createServer((socket) => { - socket.end('goodbye\n'); - }); - - // grab a random port. - server.listen(() => { - address = server.address(); - console.log('opened server on %j', address); - }); +```js +var server = net.createServer((socket) => { + socket.end('goodbye\n'); +}); + +// grab a random port. +server.listen(() => { + address = server.address(); + console.log('opened server on %j', address); +}); +``` Don't call `server.address()` until the `'listening'` event has been emitted. @@ -127,11 +129,13 @@ underlying handle, allowing connection handling duties to be shared. When results in an error. An example which listens on an exclusive port is shown below. - server.listen({ - host: 'localhost', - port: 80, - exclusive: true - }); +```js +server.listen({ + host: 'localhost', + port: 80, + exclusive: true +}); +``` ### server.listen(path[, backlog][, callback]) @@ -184,15 +188,17 @@ One issue some users run into is getting `EADDRINUSE` errors. This means that another server is already running on the requested port. One way of handling this would be to wait a second and then try again. This can be done with - server.on('error', (e) => { - if (e.code == 'EADDRINUSE') { - console.log('Address in use, retrying...'); - setTimeout(() => { - server.close(); - server.listen(PORT, HOST); - }, 1000); - } - }); +```js +server.on('error', (e) => { + if (e.code == 'EADDRINUSE') { + console.log('Address in use, retrying...'); + setTimeout(() => { + server.close(); + server.listen(PORT, HOST); + }, 1000); + } +}); +``` (Note: All sockets in Node.js set `SO_REUSEADDR` already) @@ -233,11 +239,14 @@ Construct a new socket object. `options` is an object with the following defaults: - { fd: null, - allowHalfOpen: false, - readable: false, - writable: false - } +```js +{ + fd: null, + allowHalfOpen: false, + readable: false, + writable: false +} +``` `fd` allows you to specify the existing file descriptor of socket. Set `readable` and/or `writable` to `true` to allow reads and/or writes on this @@ -512,23 +521,27 @@ The `connectListener` parameter will be added as a listener for the Here is an example of a client of the previously described echo server: - const net = require('net'); - const client = net.connect({port: 8124}, () => { //'connect' listener - console.log('connected to server!'); - client.write('world!\r\n'); - }); - client.on('data', (data) => { - console.log(data.toString()); - client.end(); - }); - client.on('end', () => { - console.log('disconnected from server'); - }); +```js +const net = require('net'); +const client = net.connect({port: 8124}, () => { //'connect' listener + console.log('connected to server!'); + client.write('world!\r\n'); +}); +client.on('data', (data) => { + console.log(data.toString()); + client.end(); +}); +client.on('end', () => { + console.log('disconnected from server'); +}); +``` To connect on the socket `/tmp/echo.sock` the second line would just be changed to - const client = net.connect({path: '/tmp/echo.sock'}); +```js +const client = net.connect({path: '/tmp/echo.sock'}); +``` ## net.connect(path[, connectListener]) @@ -561,24 +574,28 @@ The `connectListener` parameter will be added as a listener for the Here is an example of a client of the previously described echo server: - const net = require('net'); - const client = net.connect({port: 8124}, - () => { //'connect' listener - console.log('connected to server!'); - client.write('world!\r\n'); - }); - client.on('data', (data) => { - console.log(data.toString()); - client.end(); - }); - client.on('end', () => { - console.log('disconnected from server'); - }); +```js +const net = require('net'); +const client = net.connect({port: 8124}, + () => { //'connect' listener + console.log('connected to server!'); + client.write('world!\r\n'); +}); +client.on('data', (data) => { + console.log(data.toString()); + client.end(); +}); +client.on('end', () => { + console.log('disconnected from server'); +}); +``` To connect on the socket `/tmp/echo.sock` the second line would just be changed to - const client = net.connect({path: '/tmp/echo.sock'}); +```js +const client = net.connect({path: '/tmp/echo.sock'}); +``` ## net.createConnection(path[, connectListener]) @@ -605,10 +622,12 @@ automatically set as a listener for the [`'connection'`][] event. `options` is an object with the following defaults: - { - allowHalfOpen: false, - pauseOnConnect: false - } +```js +{ + allowHalfOpen: false, + pauseOnConnect: false +} +``` If `allowHalfOpen` is `true`, then the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. The socket becomes @@ -623,31 +642,39 @@ original process. To begin reading data from a paused socket, call [`resume()`][ Here is an example of an echo server which listens for connections on port 8124: - const net = require('net'); - const server = net.createServer((c) => { //'connection' listener - console.log('client connected'); - c.on('end', () => { - console.log('client disconnected'); - }); - c.write('hello\r\n'); - c.pipe(c); - }); - server.listen(8124, () => { //'listening' listener - console.log('server bound'); - }); +```js +const net = require('net'); +const server = net.createServer((c) => { //'connection' listener + console.log('client connected'); + c.on('end', () => { + console.log('client disconnected'); + }); + c.write('hello\r\n'); + c.pipe(c); +}); +server.listen(8124, () => { //'listening' listener + console.log('server bound'); +}); +``` Test this by using `telnet`: - telnet localhost 8124 +``` +telnet localhost 8124 +``` To listen on the socket `/tmp/echo.sock` the third line from the last would just be changed to - server.listen('/tmp/echo.sock', () => { //'listening' listener +```js +server.listen('/tmp/echo.sock', () => { /* 'listening' listener*/ }) +``` Use `nc` to connect to a UNIX domain socket server: - nc -U /tmp/echo.sock +```js +nc -U /tmp/echo.sock +``` ## net.isIP(input) diff --git a/doc/api/os.markdown b/doc/api/os.markdown index bef2c34f6a..6c1a6f3634 100644 --- a/doc/api/os.markdown +++ b/doc/api/os.markdown @@ -24,70 +24,72 @@ milliseconds the CPU/core spent in: user, nice, sys, idle, and irq). Example inspection of os.cpus: - [ { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 252020, - nice: 0, - sys: 30340, - idle: 1070356870, - irq: 0 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 306960, - nice: 0, - sys: 26980, - idle: 1071569080, - irq: 0 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 248450, - nice: 0, - sys: 21750, - idle: 1070919370, - irq: 0 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 256880, - nice: 0, - sys: 19430, - idle: 1070905480, - irq: 20 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 511580, - nice: 20, - sys: 40900, - idle: 1070842510, - irq: 0 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 291660, - nice: 0, - sys: 34360, - idle: 1070888000, - irq: 10 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 308260, - nice: 0, - sys: 55410, - idle: 1071129970, - irq: 880 } }, - { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', - speed: 2926, - times: - { user: 266450, - nice: 1480, - sys: 34920, - idle: 1072572010, - irq: 30 } } ] +```js +[ { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 252020, + nice: 0, + sys: 30340, + idle: 1070356870, + irq: 0 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 306960, + nice: 0, + sys: 26980, + idle: 1071569080, + irq: 0 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 248450, + nice: 0, + sys: 21750, + idle: 1070919370, + irq: 0 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 256880, + nice: 0, + sys: 19430, + idle: 1070905480, + irq: 20 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 511580, + nice: 20, + sys: 40900, + idle: 1070842510, + irq: 0 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 291660, + nice: 0, + sys: 34360, + idle: 1070888000, + irq: 10 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 308260, + nice: 0, + sys: 55410, + idle: 1071129970, + irq: 880 } }, + { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', + speed: 2926, + times: + { user: 266450, + nice: 1480, + sys: 34920, + idle: 1072572010, + irq: 30 } } ] +``` Note that since `nice` values are UNIX centric in Windows the `nice` values of all processors are always 0. @@ -125,28 +127,30 @@ Windows. Get a list of network interfaces: - { lo: - [ { address: '127.0.0.1', - netmask: '255.0.0.0', - family: 'IPv4', - mac: '00:00:00:00:00:00', - internal: true }, - { address: '::1', - netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', - family: 'IPv6', - mac: '00:00:00:00:00:00', - internal: true } ], - eth0: - [ { address: '192.168.1.108', - netmask: '255.255.255.0', - family: 'IPv4', - mac: '01:02:03:0a:0b:0c', - internal: false }, - { address: 'fe80::a00:27ff:fe4e:66a1', - netmask: 'ffff:ffff:ffff:ffff::', - family: 'IPv6', - mac: '01:02:03:0a:0b:0c', - internal: false } ] } +```js +{ lo: + [ { address: '127.0.0.1', + netmask: '255.0.0.0', + family: 'IPv4', + mac: '00:00:00:00:00:00', + internal: true }, + { address: '::1', + netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + family: 'IPv6', + mac: '00:00:00:00:00:00', + internal: true } ], + eth0: + [ { address: '192.168.1.108', + netmask: '255.255.255.0', + family: 'IPv4', + mac: '01:02:03:0a:0b:0c', + internal: false }, + { address: 'fe80::a00:27ff:fe4e:66a1', + netmask: 'ffff:ffff:ffff:ffff::', + family: 'IPv6', + mac: '01:02:03:0a:0b:0c', + internal: false } ] } +``` Note that due to the underlying implementation this will only return network interfaces that have been assigned an address. diff --git a/doc/api/path.markdown b/doc/api/path.markdown index 4e99a163a5..10dadabd22 100644 --- a/doc/api/path.markdown +++ b/doc/api/path.markdown @@ -14,13 +14,15 @@ Return the last portion of a path. Similar to the Unix `basename` command. Example: - path.basename('/foo/bar/baz/asdf/quux.html') - // returns - 'quux.html' +```js +path.basename('/foo/bar/baz/asdf/quux.html') +// returns +'quux.html' - path.basename('/foo/bar/baz/asdf/quux.html', '.html') - // returns - 'quux' +path.basename('/foo/bar/baz/asdf/quux.html', '.html') +// returns +'quux' +``` ## path.delimiter @@ -28,21 +30,25 @@ The platform-specific path delimiter, `;` or `':'`. An example on *nix: - console.log(process.env.PATH) - // '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin' +```js +console.log(process.env.PATH) +// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin' - process.env.PATH.split(path.delimiter) - // returns - ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin'] +process.env.PATH.split(path.delimiter) +// returns +['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin'] +``` An example on Windows: - console.log(process.env.PATH) - // 'C:\Windows\system32;C:\Windows;C:\Program Files\node\' +```js +console.log(process.env.PATH) +// 'C:\Windows\system32;C:\Windows;C:\Program Files\node\' - process.env.PATH.split(path.delimiter) - // returns - ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\'] +process.env.PATH.split(path.delimiter) +// returns +['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\'] +``` ## path.dirname(p) @@ -50,9 +56,11 @@ Return the directory name of a path. Similar to the Unix `dirname` command. Example: - path.dirname('/foo/bar/baz/asdf/quux') - // returns - '/foo/bar/baz/asdf' +```js +path.dirname('/foo/bar/baz/asdf/quux') +// returns +'/foo/bar/baz/asdf' +``` ## path.extname(p) @@ -61,49 +69,53 @@ in the last portion of the path. If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string. Examples: - path.extname('index.html') - // returns - '.html' +```js +path.extname('index.html') +// returns +'.html' - path.extname('index.coffee.md') - // returns - '.md' +path.extname('index.coffee.md') +// returns +'.md' - path.extname('index.') - // returns - '.' +path.extname('index.') +// returns +'.' - path.extname('index') - // returns - '' +path.extname('index') +// returns +'' - path.extname('.index') - // returns - '' +path.extname('.index') +// returns +'' +``` ## path.format(pathObject) Returns a path string from an object, the opposite of [`path.parse`][]. - path.format({ - root : "/", - dir : "/home/user/dir", - base : "file.txt", - ext : ".txt", - name : "file" - }) - // returns - '/home/user/dir/file.txt' - - // `root` will be used if `dir` is not specified and `name` + `ext` will be used - // if `base` is not specified - path.format({ - root : "/", - ext : ".txt", - name : "file" - }) - // returns - '/file.txt' +```js +path.format({ + root : "/", + dir : "/home/user/dir", + base : "file.txt", + ext : ".txt", + name : "file" +}) +// returns +'/home/user/dir/file.txt' + +// `root` will be used if `dir` is not specified and `name` + `ext` will be used +// if `base` is not specified +path.format({ + root : "/", + ext : ".txt", + name : "file" +}) +// returns +'/file.txt' +``` ## path.isAbsolute(path) @@ -112,17 +124,21 @@ resolve to the same location, regardless of the working directory. Posix examples: - path.isAbsolute('/foo/bar') // true - path.isAbsolute('/baz/..') // true - path.isAbsolute('qux/') // false - path.isAbsolute('.') // false +```js +path.isAbsolute('/foo/bar') // true +path.isAbsolute('/baz/..') // true +path.isAbsolute('qux/') // false +path.isAbsolute('.') // false +``` Windows examples: - path.isAbsolute('//server') // true - path.isAbsolute('C:/foo/..') // true - path.isAbsolute('bar\\baz') // false - path.isAbsolute('.') // false +```js +path.isAbsolute('//server') // true +path.isAbsolute('C:/foo/..') // true +path.isAbsolute('bar\\baz') // false +path.isAbsolute('.') // false +``` *Note:* If the path string passed as parameter is a zero-length string, unlike other path module functions, it will be used as-is and `false` will be @@ -137,13 +153,15 @@ silently ignored. In v0.10 and up, an exception is thrown. Example: - path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') - // returns - '/foo/bar/baz/asdf' +```js +path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') +// returns +'/foo/bar/baz/asdf' - path.join('foo', {}, 'bar') - // throws exception - TypeError: Arguments to path.join must be strings +path.join('foo', {}, 'bar') +// throws exception +TypeError: Arguments to path.join must be strings +``` *Note:* If the arguments to `join` have zero-length strings, unlike other path module functions, they will be ignored. If the joined path string is a @@ -160,9 +178,11 @@ On Windows backslashes are used. Example: - path.normalize('/foo/bar//baz/asdf/quux/..') - // returns - '/foo/bar/baz/asdf' +```js +path.normalize('/foo/bar//baz/asdf/quux/..') +// returns +'/foo/bar/baz/asdf' +``` *Note:* If the path string passed as argument is a zero-length string then `'.'` will be returned, which represents the current working directory. @@ -173,27 +193,31 @@ Returns an object from a path string. An example on *nix: - path.parse('/home/user/dir/file.txt') - // returns - { - root : "/", - dir : "/home/user/dir", - base : "file.txt", - ext : ".txt", - name : "file" - } +```js +path.parse('/home/user/dir/file.txt') +// returns +{ + root : "/", + dir : "/home/user/dir", + base : "file.txt", + ext : ".txt", + name : "file" +} +``` An example on Windows: - path.parse('C:\\path\\dir\\index.html') - // returns - { - root : "C:\\", - dir : "C:\\path\\dir", - base : "index.html", - ext : ".html", - name : "index" - } +```js +path.parse('C:\\path\\dir\\index.html') +// returns +{ + root : "C:\\", + dir : "C:\\path\\dir", + base : "index.html", + ext : ".html", + name : "index" +} +``` ## path.posix @@ -208,17 +232,21 @@ At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of `path.resolve`, which means we see that: - path.resolve(from, path.relative(from, to)) == path.resolve(to) +```js +path.resolve(from, path.relative(from, to)) == path.resolve(to) +``` Examples: - path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') - // returns - '..\\..\\impl\\bbb' +```js +path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') +// returns +'..\\..\\impl\\bbb' - path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') - // returns - '../../impl/bbb' +path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') +// returns +'../../impl/bbb' +``` *Note:* If the arguments to `relative` have zero-length strings then the current working directory will be used instead of the zero-length strings. If @@ -236,32 +264,38 @@ gets resolved to the root directory. Non-string `from` arguments are ignored. Another way to think of it is as a sequence of `cd` commands in a shell. - path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile') +```js +path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile') +``` Is similar to: - cd foo/bar - cd /tmp/file/ - cd .. - cd a/../subfile - pwd +``` +cd foo/bar +cd /tmp/file/ +cd .. +cd a/../subfile +pwd +``` The difference is that the different paths don't need to exist and may also be files. Examples: - path.resolve('/foo/bar', './baz') - // returns - '/foo/bar/baz' +```js +path.resolve('/foo/bar', './baz') +// returns +'/foo/bar/baz' - path.resolve('/foo/bar', '/tmp/file/') - // returns - '/tmp/file' +path.resolve('/foo/bar', '/tmp/file/') +// returns +'/tmp/file' - path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') - // if currently in /home/myself/node, it returns - '/home/myself/node/wwwroot/static_files/gif/image.gif' +path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') +// if currently in /home/myself/node, it returns +'/home/myself/node/wwwroot/static_files/gif/image.gif' +``` *Note:* If the arguments to `resolve` have zero-length strings then the current working directory will be used instead of them. @@ -272,15 +306,19 @@ The platform-specific file separator. `'\\'` or `'/'`. An example on *nix: - 'foo/bar/baz'.split(path.sep) - // returns - ['foo', 'bar', 'baz'] +```js +'foo/bar/baz'.split(path.sep) +// returns +['foo', 'bar', 'baz'] +``` An example on Windows: - 'foo\\bar\\baz'.split(path.sep) - // returns - ['foo', 'bar', 'baz'] +```js +'foo\\bar\\baz'.split(path.sep) +// returns +['foo', 'bar', 'baz'] +``` ## path.win32 diff --git a/doc/api/process.markdown b/doc/api/process.markdown index d40b319585..981125eecf 100644 --- a/doc/api/process.markdown +++ b/doc/api/process.markdown @@ -29,13 +29,15 @@ implicitly by the event loop draining. Example of listening for `'exit'`: - process.on('exit', (code) => { - // do *NOT* do this - setTimeout(() => { - console.log('This will not run'); - }, 0); - console.log('About to exit with code:', code); - }); +```js +process.on('exit', (code) => { + // do *NOT* do this + setTimeout(() => { + console.log('This will not run'); + }, 0); + console.log('About to exit with code:', code); +}); +``` ## Event: 'message' @@ -71,13 +73,15 @@ event tells you when the list of unhandled rejections shrinks. For example using the rejection detection hooks in order to keep a map of all the rejected promise reasons at a given time: - const unhandledRejections = new Map(); - process.on('unhandledRejection', (reason, p) => { - unhandledRejections.set(p, reason); - }); - process.on('rejectionHandled', (p) => { - unhandledRejections.delete(p); - }); +```js +const unhandledRejections = new Map(); +process.on('unhandledRejection', (reason, p) => { + unhandledRejections.set(p, reason); +}); +process.on('rejectionHandled', (p) => { + unhandledRejections.delete(p); +}); +``` This map will grow and shrink over time, reflecting rejections that start unhandled and then become handled. You could record the errors in some error @@ -93,17 +97,19 @@ a stack trace and exit) will not occur. Example of listening for `'uncaughtException'`: - process.on('uncaughtException', (err) => { - console.log(`Caught exception: ${err}`); - }); +```js +process.on('uncaughtException', (err) => { + console.log(`Caught exception: ${err}`); +}); - setTimeout(() => { - console.log('This will still run.'); - }, 500); +setTimeout(() => { + console.log('This will still run.'); +}, 500); - // Intentionally cause an exception, but don't catch it. - nonexistentFunc(); - console.log('This will not run.'); +// Intentionally cause an exception, but don't catch it. +nonexistentFunc(); +console.log('This will not run.'); +``` Note that `'uncaughtException'` is a very crude mechanism for exception handling. @@ -138,28 +144,34 @@ instance). Here is an example that logs every unhandled rejection to the console - process.on('unhandledRejection', (reason, p) => { - console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); - // application specific logging, throwing an error, or other logic here - }); +```js +process.on('unhandledRejection', (reason, p) => { + console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); + // application specific logging, throwing an error, or other logic here +}); +``` For example, here is a rejection that will trigger the `'unhandledRejection'` event: - somePromise.then((res) => { - return reportToUser(JSON.parse(res)); // note the typo - }); // no `.catch` or `.then` +```js +somePromise.then((res) => { + return reportToUser(JSON.parse(res)); // note the typo +}); // no `.catch` or `.then` +``` Here is an example of a coding pattern that will also trigger `'unhandledRejection'`: - function SomeResource() { - // Initially set the loaded status to a rejected promise - this.loaded = Promise.reject(new Error('Resource not yet loaded!')); - } +```js +function SomeResource() { + // Initially set the loaded status to a rejected promise + this.loaded = Promise.reject(new Error('Resource not yet loaded!')); +} - var resource = new SomeResource(); - // no .catch or .then on resource.loaded for at least a turn +var resource = new SomeResource(); +// no .catch or .then on resource.loaded for at least a turn +``` In cases like this, you may not want to track the rejection as a developer error like you would for other `'unhandledRejection'` events. To address @@ -222,12 +234,14 @@ standard POSIX signal names such as `SIGINT`, `SIGHUP`, etc. Example of listening for `SIGINT`: - // Start reading from stdin so we don't exit. - process.stdin.resume(); +```js +// Start reading from stdin so we don't exit. +process.stdin.resume(); - process.on('SIGINT', () => { - console.log('Got SIGINT. Press Control-D to exit.'); - }); +process.on('SIGINT', () => { + console.log('Got SIGINT. Press Control-D to exit.'); +}); +``` An easy way to send the `SIGINT` signal is with `Control-C` in most terminal programs. @@ -275,7 +289,9 @@ generate a core file. What processor architecture you're running on: `'arm'`, `'ia32'`, or `'x64'`. - console.log('This processor architecture is ' + process.arch); +```js +console.log('This processor architecture is ' + process.arch); +``` ## process.argv @@ -283,32 +299,38 @@ An array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments. - // print process.argv - process.argv.forEach((val, index, array) => { - console.log(`${index}: ${val}`); - }); +```js +// print process.argv +process.argv.forEach((val, index, array) => { + console.log(`${index}: ${val}`); +}); +``` This will generate: - $ node process-2.js one two=three four - 0: node - 1: /Users/mjr/work/node/process-2.js - 2: one - 3: two=three - 4: four +``` +$ node process-2.js one two=three four +0: node +1: /Users/mjr/work/node/process-2.js +2: one +3: two=three +4: four +``` ## process.chdir(directory) Changes the current working directory of the process or throws an exception if that fails. - console.log(`Starting directory: ${process.cwd()}`); - try { - process.chdir('/tmp'); - console.log(`New directory: ${process.cwd()}`); - } - catch (err) { - console.log(`chdir: ${err}`); - } +```js +console.log(`Starting directory: ${process.cwd()}`); +try { + process.chdir('/tmp'); + console.log(`New directory: ${process.cwd()}`); +} +catch (err) { + console.log(`chdir: ${err}`); +} +``` ## process.config @@ -318,26 +340,32 @@ the `config.gypi` file that was produced when running the `./configure` script. An example of the possible output looks like: - { target_defaults: - { cflags: [], - default_configuration: 'Release', - defines: [], - include_dirs: [], - libraries: [] }, - variables: - { host_arch: 'x64', - node_install_npm: 'true', - node_prefix: '', - node_shared_cares: 'false', - node_shared_http_parser: 'false', - node_shared_libuv: 'false', - node_shared_zlib: 'false', - node_use_dtrace: 'false', - node_use_openssl: 'true', - node_shared_openssl: 'false', - strict_aliasing: 'true', - target_arch: 'x64', - v8_use_snapshot: 'true' } } +``` +{ + target_defaults: + { cflags: [], + default_configuration: 'Release', + defines: [], + include_dirs: [], + libraries: [] }, + variables: + { + host_arch: 'x64', + node_install_npm: 'true', + node_prefix: '', + node_shared_cares: 'false', + node_shared_http_parser: 'false', + node_shared_libuv: 'false', + node_shared_zlib: 'false', + node_use_dtrace: 'false', + node_use_openssl: 'true', + node_shared_openssl: 'false', + strict_aliasing: 'true', + target_arch: 'x64', + v8_use_snapshot: 'true' + } +} +``` ## process.connected @@ -349,7 +377,9 @@ If `process.connected` is false, it is no longer possible to send messages. Returns the current working directory of the process. - console.log(`Current directory: ${process.cwd()}`); +```js +console.log(`Current directory: ${process.cwd()}`); +``` ## process.disconnect() @@ -367,26 +397,32 @@ An object containing the user environment. See environ(7). An example of this object looks like: - { TERM: 'xterm-256color', - SHELL: '/usr/local/bin/bash', - USER: 'maciej', - PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', - PWD: '/Users/maciej', - EDITOR: 'vim', - SHLVL: '1', - HOME: '/Users/maciej', - LOGNAME: 'maciej', - _: '/usr/local/bin/node' } +```js +{ TERM: 'xterm-256color', + SHELL: '/usr/local/bin/bash', + USER: 'maciej', + PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', + PWD: '/Users/maciej', + EDITOR: 'vim', + SHLVL: '1', + HOME: '/Users/maciej', + LOGNAME: 'maciej', + _: '/usr/local/bin/node' } +``` You can write to this object, but changes won't be reflected outside of your process. That means that the following won't work: - $ node -e 'process.env.foo = "bar"' && echo $foo +``` +$ node -e 'process.env.foo = "bar"' && echo $foo +``` But this will: - process.env.foo = 'bar'; - console.log(process.env.foo); +```js +process.env.foo = 'bar'; +console.log(process.env.foo); +``` ## process.execArgv @@ -399,15 +435,21 @@ environment as the parent. Example: - $ node --harmony script.js --version +``` +$ node --harmony script.js --version +``` results in process.execArgv: - ['--harmony'] +```js +['--harmony'] +``` and process.argv: - ['/usr/local/bin/node', 'script.js', '--version'] +```js +['/usr/local/bin/node', 'script.js', '--version'] +``` ## process.execPath @@ -415,7 +457,9 @@ This is the absolute pathname of the executable that started the process. Example: - /usr/local/bin/node +``` +/usr/local/bin/node +``` ## process.exit([code]) @@ -425,7 +469,9 @@ Ends the process with the specified `code`. If omitted, exit uses the To exit with a 'failure' code: - process.exit(1); +```js +process.exit(1); +``` The shell that executed Node.js should see the exit code as 1. @@ -448,9 +494,11 @@ Android) Gets the effective group identity of the process. (See getegid(2).) This is the numerical group id, not the group name. - if (process.getegid) { - console.log(`Current gid: ${process.getegid()}`); - } +```js +if (process.getegid) { + console.log(`Current gid: ${process.getegid()}`); +} +``` ## process.geteuid() @@ -461,9 +509,11 @@ Android) Gets the effective user identity of the process. (See geteuid(2).) This is the numerical userid, not the username. - if (process.geteuid) { - console.log(`Current uid: ${process.geteuid()}`); - } +```js +if (process.geteuid) { + console.log(`Current uid: ${process.geteuid()}`); +} +``` ## process.getgid() @@ -473,9 +523,11 @@ Android) Gets the group identity of the process. (See getgid(2).) This is the numerical group id, not the group name. - if (process.getgid) { - console.log(`Current gid: ${process.getgid()}`); - } +```js +if (process.getgid) { + console.log(`Current gid: ${process.getgid()}`); +} +``` ## process.getgroups() @@ -493,9 +545,11 @@ Android) Gets the user identity of the process. (See getuid(2).) This is the numerical userid, not the username. - if (process.getuid) { - console.log(`Current uid: ${process.getuid()}`); - } +```js +if (process.getuid) { + console.log(`Current uid: ${process.getuid()}`); +} +``` ## process.hrtime() @@ -507,16 +561,18 @@ primary use is for measuring performance between intervals. You may pass in the result of a previous call to `process.hrtime()` to get a diff reading, useful for benchmarks and measuring intervals: - var time = process.hrtime(); - // [ 1800216, 25 ] +```js +var time = process.hrtime(); +// [ 1800216, 25 ] - setTimeout(() => { - var diff = process.hrtime(time); - // [ 1, 552 ] +setTimeout(() => { + var diff = process.hrtime(time); + // [ 1, 552 ] - console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]); - // benchmark took 1000000527 nanoseconds - }, 1000); + console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]); + // benchmark took 1000000527 nanoseconds +}, 1000); +``` ## process.initgroups(user, extra_group) @@ -532,11 +588,13 @@ to be root or have the `CAP_SETGID` capability. Some care needs to be taken when dropping privileges. Example: - console.log(process.getgroups()); // [ 0 ] - process.initgroups('bnoordhuis', 1000); // switch user - console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] - process.setgid(1000); // drop root gid - console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] +```js +console.log(process.getgroups()); // [ 0 ] +process.initgroups('bnoordhuis', 1000); // switch user +console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] +process.setgid(1000); // drop root gid +console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] +``` ## process.kill(pid[, signal]) @@ -555,16 +613,18 @@ something other than kill the target process. Example of sending a signal to yourself: - process.on('SIGHUP', () => { - console.log('Got SIGHUP signal.'); - }); +```js +process.on('SIGHUP', () => { + console.log('Got SIGHUP signal.'); +}); - setTimeout(() => { - console.log('Exiting.'); - process.exit(0); - }, 100); +setTimeout(() => { + console.log('Exiting.'); + process.exit(0); +}, 100); - process.kill(process.pid, 'SIGHUP'); +process.kill(process.pid, 'SIGHUP'); +``` Note: When SIGUSR1 is received by Node.js it starts the debugger, see [Signal Events][]. @@ -583,15 +643,19 @@ As with `require.main`, it will be `undefined` if there was no entry script. Returns an object describing the memory usage of the Node.js process measured in bytes. - const util = require('util'); +```js +const util = require('util'); - console.log(util.inspect(process.memoryUsage())); +console.log(util.inspect(process.memoryUsage())); +``` This will generate: - { rss: 4935680, - heapTotal: 1826816, - heapUsed: 650472 } +```js +{ rss: 4935680, + heapTotal: 1826816, + heapUsed: 650472 } +``` `heapTotal` and `heapUsed` refer to V8's memory usage. @@ -607,65 +671,75 @@ This is *not* a simple alias to [`setTimeout(fn, 0)`][], it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop. - console.log('start'); - process.nextTick(() => { - console.log('nextTick callback'); - }); - console.log('scheduled'); - // Output: - // start - // scheduled - // nextTick callback +```js +console.log('start'); +process.nextTick(() => { + console.log('nextTick callback'); +}); +console.log('scheduled'); +// Output: +// start +// scheduled +// nextTick callback +``` This is important in developing APIs where you want to give the user the chance to assign event handlers after an object has been constructed, but before any I/O has occurred. - function MyThing(options) { - this.setupOptions(options); +```js +function MyThing(options) { + this.setupOptions(options); - process.nextTick(() => { - this.startDoingStuff(); - }.bind(this)); - } + process.nextTick(() => { + this.startDoingStuff(); + }.bind(this)); +} - var thing = new MyThing(); - thing.getReadyForStuff(); +var thing = new MyThing(); +thing.getReadyForStuff(); - // thing.startDoingStuff() gets called now, not before. +// thing.startDoingStuff() gets called now, not before. +``` It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example: - // WARNING! DO NOT USE! BAD UNSAFE HAZARD! - function maybeSync(arg, cb) { - if (arg) { - cb(); - return; - } +```js +// WARNING! DO NOT USE! BAD UNSAFE HAZARD! +function maybeSync(arg, cb) { + if (arg) { + cb(); + return; + } - fs.stat('file', cb); - } + fs.stat('file', cb); +} +``` This API is hazardous. If you do this: - maybeSync(true, function() { - foo(); - }); - bar(); +```js +maybeSync(true, function() { + foo(); +}); +bar(); +``` then it's not clear whether `foo()` or `bar()` will be called first. This approach is much better: - function definitelyAsync(arg, cb) { - if (arg) { - process.nextTick(cb); - return; - } +```js +function definitelyAsync(arg, cb) { + if (arg) { + process.nextTick(cb); + return; + } - fs.stat('file', cb); - } + fs.stat('file', cb); +} +``` Note: the nextTick queue is completely drained on each pass of the event loop **before** additional I/O is processed. As a result, @@ -676,14 +750,18 @@ happening, just like a `while(true);` loop. The PID of the process. - console.log(`This process is pid ${process.pid}`); +```js +console.log(`This process is pid ${process.pid}`); +``` ## process.platform What platform you're running on: `'darwin'`, `'freebsd'`, `'linux'`, `'sunos'` or `'win32'` - console.log(`This platform is ${process.platform}`); +```js +console.log(`This platform is ${process.platform}`); +``` ## process.release @@ -707,10 +785,12 @@ for the source tarball and headers-only tarball. e.g. - { name: 'node', - sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz', - headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz', - libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' } +```js +{ name: 'node', + sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz', + headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz', + libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' } +``` In custom builds from non-release versions of the source tree, only the `name` property may be present. The additional properties should not be @@ -736,16 +816,18 @@ Sets the effective group identity of the process. (See setegid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. - if (process.getegid && process.setegid) { - console.log(`Current gid: ${process.getegid()}`); - try { - process.setegid(501); - console.log(`New gid: ${process.getegid()}`); - } - catch (err) { - console.log(`Failed to set gid: ${err}`); - } - } +```js +if (process.getegid && process.setegid) { + console.log(`Current gid: ${process.getegid()}`); + try { + process.setegid(501); + console.log(`New gid: ${process.getegid()}`); + } + catch (err) { + console.log(`Failed to set gid: ${err}`); + } +} +``` ## process.seteuid(id) @@ -756,16 +838,18 @@ Sets the effective user identity of the process. (See seteuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. - if (process.geteuid && process.seteuid) { - console.log(`Current uid: ${process.geteuid()}`); - try { - process.seteuid(501); - console.log(`New uid: ${process.geteuid()}`); - } - catch (err) { - console.log(`Failed to set uid: ${err}`); - } - } +```js +if (process.geteuid && process.seteuid) { + console.log(`Current uid: ${process.geteuid()}`); + try { + process.seteuid(501); + console.log(`New uid: ${process.geteuid()}`); + } + catch (err) { + console.log(`Failed to set uid: ${err}`); + } +} +``` ## process.setgid(id) @@ -776,16 +860,18 @@ Sets the group identity of the process. (See setgid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. - if (process.getgid && process.setgid) { - console.log(`Current gid: ${process.getgid()}`); - try { - process.setgid(501); - console.log(`New gid: ${process.getgid()}`); - } - catch (err) { - console.log(`Failed to set gid: ${err}`); - } - } +```js +if (process.getgid && process.setgid) { + console.log(`Current gid: ${process.getgid()}`); + try { + process.setgid(501); + console.log(`New gid: ${process.getgid()}`); + } + catch (err) { + console.log(`Failed to set gid: ${err}`); + } +} +``` ## process.setgroups(groups) @@ -806,16 +892,18 @@ Sets the user identity of the process. (See setuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. - if (process.getuid && process.setuid) { - console.log(`Current uid: ${process.getuid()}`); - try { - process.setuid(501); - console.log(`New uid: ${process.getuid()}`); - } - catch (err) { - console.log(`Failed to set uid: ${err}`); - } - } +```js +if (process.getuid && process.setuid) { + console.log(`Current uid: ${process.getuid()}`); + try { + process.setuid(501); + console.log(`New uid: ${process.getuid()}`); + } + catch (err) { + console.log(`Failed to set uid: ${err}`); + } +} +``` ## process.stderr @@ -833,18 +921,20 @@ A `Readable Stream` for stdin (on fd `0`). Example of opening standard input and listening for both events: - process.stdin.setEncoding('utf8'); +```js +process.stdin.setEncoding('utf8'); - process.stdin.on('readable', () => { - var chunk = process.stdin.read(); - if (chunk !== null) { - process.stdout.write(`data: ${chunk}`); - } - }); +process.stdin.on('readable', () => { + var chunk = process.stdin.read(); + if (chunk !== null) { + process.stdout.write(`data: ${chunk}`); + } +}); - process.stdin.on('end', () => { - process.stdout.write('end'); - }); +process.stdin.on('end', () => { + process.stdout.write('end'); +}); +``` As a Stream, `process.stdin` can also be used in "old" mode that is compatible with scripts written for node.js prior to v0.10. @@ -863,9 +953,11 @@ A `Writable Stream` to `stdout` (on fd `1`). For example, a `console.log` equivalent could look like this: - console.log = function(msg) { - process.stdout.write(`${msg}\n`); - }; +```js +console.log = function(msg) { + process.stdout.write(`${msg}\n`); +}; +``` `process.stderr` and `process.stdout` are unlike other streams in Node.js in that they cannot be closed (`end()` will throw), they never emit the `'finish'` @@ -876,15 +968,17 @@ should be a very rare occurrence indeed.) To check if Node.js is being run in a TTY context, read the `isTTY` property on `process.stderr`, `process.stdout`, or `process.stdin`: - $ node -p "Boolean(process.stdin.isTTY)" - true - $ echo "foo" | node -p "Boolean(process.stdin.isTTY)" - false +``` +$ node -p "Boolean(process.stdin.isTTY)" +true +$ echo "foo" | node -p "Boolean(process.stdin.isTTY)" +false - $ node -p "Boolean(process.stdout.isTTY)" - true - $ node -p "Boolean(process.stdout.isTTY)" | cat - false +$ node -p "Boolean(process.stdout.isTTY)" +true +$ node -p "Boolean(process.stdout.isTTY)" | cat +false +``` See [the tty docs][] for more information. @@ -908,11 +1002,13 @@ Sets or reads the process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the old mask if `mask` argument is given, otherwise returns the current mask. - const newmask = 0o022; - const oldmask = process.umask(newmask); - console.log( - `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` - ); +```js +const newmask = 0o022; +const oldmask = process.umask(newmask); +console.log( + `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` +); +``` ## process.uptime() @@ -923,25 +1019,31 @@ Number of seconds Node.js has been running. A compiled-in property that exposes `NODE_VERSION`. - console.log(`Version: ${process.version}`); +```js +console.log(`Version: ${process.version}`); +``` ## process.versions A property exposing version strings of Node.js and its dependencies. - console.log(process.versions); +```js +console.log(process.versions); +``` Will print something like: - { http_parser: '2.3.0', - node: '1.1.1', - v8: '4.1.0.14', - uv: '1.3.0', - zlib: '1.2.8', - ares: '1.10.0-DEV', - modules: '43', - icu: '55.1', - openssl: '1.0.1k' } +```js +{ http_parser: '2.3.0', + node: '1.1.1', + v8: '4.1.0.14', + uv: '1.3.0', + zlib: '1.2.8', + ares: '1.10.0-DEV', + modules: '43', + icu: '55.1', + openssl: '1.0.1k' } +``` [`'message'`]: child_process.html#child_process_event_message [`ChildProcess.disconnect()`]: child_process.html#child_process_child_disconnect diff --git a/doc/api/punycode.markdown b/doc/api/punycode.markdown index 0b3f49d9ba..7f3617c12d 100644 --- a/doc/api/punycode.markdown +++ b/doc/api/punycode.markdown @@ -10,17 +10,21 @@ access it. (To use it with other Node.js versions, use npm to install the Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols. - // decode domain name parts - punycode.decode('maana-pta'); // 'mañana' - punycode.decode('--dqo34k'); // '☃-⌘' +```js +// decode domain name parts +punycode.decode('maana-pta'); // 'mañana' +punycode.decode('--dqo34k'); // '☃-⌘' +``` ## punycode.encode(string) Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols. - // encode domain name parts - punycode.encode('mañana'); // 'maana-pta' - punycode.encode('☃-⌘'); // '--dqo34k' +```js +// encode domain name parts +punycode.encode('mañana'); // 'maana-pta' +punycode.encode('☃-⌘'); // '--dqo34k' +``` ## punycode.toASCII(domain) @@ -28,9 +32,11 @@ Converts a Unicode string representing a domain name to Punycode. Only the non-ASCII parts of the domain name will be converted, i.e. it doesn't matter if you call it with a domain that's already in ASCII. - // encode domain names - punycode.toASCII('mañana.com'); // 'xn--maana-pta.com' - punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com' +```js +// encode domain names +punycode.toASCII('mañana.com'); // 'xn--maana-pta.com' +punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com' +``` ## punycode.toUnicode(domain) @@ -38,9 +44,11 @@ Converts a Punycode string representing a domain name to Unicode. Only the Punycoded parts of the domain name will be converted, i.e. it doesn't matter if you call it on a string that has already been converted to Unicode. - // decode domain names - punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com' - punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com' +```js +// decode domain names +punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com' +punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com' +``` ## punycode.ucs2 @@ -51,16 +59,20 @@ symbol in the string. While [JavaScript uses UCS-2 internally][], this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16. - punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63] - // surrogate pair for U+1D306 tetragram for centre: - punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306] +```js +punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63] +// surrogate pair for U+1D306 tetragram for centre: +punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306] +``` ### punycode.ucs2.encode(codePoints) Creates a string based on an array of numeric code point values. - punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc' - punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06' +```js +punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc' +punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06' +``` ## punycode.version diff --git a/doc/api/querystring.markdown b/doc/api/querystring.markdown index 8b16fb725a..052bd0ea41 100644 --- a/doc/api/querystring.markdown +++ b/doc/api/querystring.markdown @@ -26,16 +26,18 @@ it can be used to decode a `non-utf8` encoding string if necessary. Example: - querystring.parse('foo=bar&baz=qux&baz=quux&corge') - // returns - { foo: 'bar', baz: ['qux', 'quux'], corge: '' } - - // Suppose gbkDecodeURIComponent function already exists, - // it can decode `gbk` encoding string - querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null, - { decodeURIComponent: gbkDecodeURIComponent }) - // returns - { w: '中文', foo: 'bar' } +```js +querystring.parse('foo=bar&baz=qux&baz=quux&corge') +// returns +{ foo: 'bar', baz: ['qux', 'quux'], corge: '' } + +// Suppose gbkDecodeURIComponent function already exists, +// it can decode `gbk` encoding string +querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null, + { decodeURIComponent: gbkDecodeURIComponent }) +// returns +{ w: '中文', foo: 'bar' } +``` ## querystring.stringify(obj[, sep][, eq][, options]) @@ -48,20 +50,22 @@ it can be used to encode string with `non-utf8` encoding if necessary. Example: - querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' }) - // returns - 'foo=bar&baz=qux&baz=quux&corge=' - - querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':') - // returns - 'foo:bar;baz:qux' - - // Suppose gbkEncodeURIComponent function already exists, - // it can encode string with `gbk` encoding - querystring.stringify({ w: '中文', foo: 'bar' }, null, null, - { encodeURIComponent: gbkEncodeURIComponent }) - // returns - 'w=%D6%D0%CE%C4&foo=bar' +```js +querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' }) +// returns +'foo=bar&baz=qux&baz=quux&corge=' + +querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':') +// returns +'foo:bar;baz:qux' + +// Suppose gbkEncodeURIComponent function already exists, +// it can encode string with `gbk` encoding +querystring.stringify({ w: '中文', foo: 'bar' }, null, null, + { encodeURIComponent: gbkEncodeURIComponent }) +// returns +'w=%D6%D0%CE%C4&foo=bar' +``` ## querystring.unescape diff --git a/doc/api/readline.markdown b/doc/api/readline.markdown index a83b492b0b..82abf3e8c3 100644 --- a/doc/api/readline.markdown +++ b/doc/api/readline.markdown @@ -9,19 +9,21 @@ Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. Here's how to allow your program to gracefully exit: - const readline = require('readline'); +```js +const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); - rl.question('What do you think of Node.js? ', (answer) => { - // TODO: Log the answer in a database - console.log('Thank you for your valuable feedback:', answer); +rl.question('What do you think of Node.js? ', (answer) => { + // TODO: Log the answer in a database + console.log('Thank you for your valuable feedback:', answer); - rl.close(); - }); + rl.close(); +}); +``` ## Class: Interface @@ -66,9 +68,11 @@ nothing is displayed. Example usage: - interface.question('What is your favorite food?', (answer) => { - console.log(`Oh, so your favorite food is ${answer}`); - }); +```js +interface.question('What is your favorite food?', (answer) => { + console.log(`Oh, so your favorite food is ${answer}`); +}); +``` ### rl.resume() @@ -89,9 +93,11 @@ This will also resume the `input` stream if it has been paused. Example: - rl.write('Delete me!'); - // Simulate ctrl+u to delete the line written previously - rl.write(null, {ctrl: true, name: 'u'}); +```js +rl.write('Delete me!'); +// Simulate ctrl+u to delete the line written previously +rl.write(null, {ctrl: true, name: 'u'}); +``` ## Events @@ -117,9 +123,11 @@ user hits enter, or return. This is a good hook to listen for user input. Example of listening for `'line'`: - rl.on('line', (cmd) => { - console.log(`You just typed: ${cmd}`); - }); +```js +rl.on('line', (cmd) => { + console.log(`You just typed: ${cmd}`); +}); +``` ### Event: 'pause' @@ -132,9 +140,11 @@ Also emitted whenever the `input` stream is not paused and receives the Example of listening for `'pause'`: - rl.on('pause', () => { - console.log('Readline paused.'); - }); +```js +rl.on('pause', () => { + console.log('Readline paused.'); +}); +``` ### Event: 'resume' @@ -144,9 +154,11 @@ Emitted whenever the `input` stream is resumed. Example of listening for `'resume'`: - rl.on('resume', () => { - console.log('Readline resumed.'); - }); +```js +rl.on('resume', () => { + console.log('Readline resumed.'); +}); +``` ### Event: 'SIGCONT' @@ -161,10 +173,12 @@ background. Example of listening for `SIGCONT`: - rl.on('SIGCONT', () => { - // `prompt` will automatically resume the stream - rl.prompt(); - }); +```js +rl.on('SIGCONT', () => { + // `prompt` will automatically resume the stream + rl.prompt(); +}); +``` ### Event: 'SIGINT' @@ -176,11 +190,13 @@ stream receives a `SIGINT`, `pause` will be triggered. Example of listening for `SIGINT`: - rl.on('SIGINT', () => { - rl.question('Are you sure you want to exit?', (answer) => { - if (answer.match(/^y(es)?$/i)) rl.pause(); - }); - }); +```js +rl.on('SIGINT', () => { + rl.question('Are you sure you want to exit?', (answer) => { + if (answer.match(/^y(es)?$/i)) rl.pause(); + }); +}); +``` ### Event: 'SIGTSTP' @@ -200,53 +216,59 @@ before the program was sent to the background. Example of listening for `SIGTSTP`: - rl.on('SIGTSTP', () => { - // This will override SIGTSTP and prevent the program from going to the - // background. - console.log('Caught SIGTSTP.'); - }); +```js +rl.on('SIGTSTP', () => { + // This will override SIGTSTP and prevent the program from going to the + // background. + console.log('Caught SIGTSTP.'); +}); +``` ## Example: Tiny CLI Here's an example of how to use all these together to craft a tiny command line interface: - const readline = require('readline'); - const rl = readline.createInterface(process.stdin, process.stdout); - - rl.setPrompt('OHAI> '); - rl.prompt(); - - rl.on('line', (line) => { - switch(line.trim()) { - case 'hello': - console.log('world!'); - break; - default: - console.log('Say what? I might have heard `' + line.trim() + '`'); - break; - } - rl.prompt(); - }).on('close', () => { - console.log('Have a great day!'); - process.exit(0); - }); +```js +const readline = require('readline'); +const rl = readline.createInterface(process.stdin, process.stdout); + +rl.setPrompt('OHAI> '); +rl.prompt(); + +rl.on('line', (line) => { + switch(line.trim()) { + case 'hello': + console.log('world!'); + break; + default: + console.log('Say what? I might have heard `' + line.trim() + '`'); + break; + } + rl.prompt(); +}).on('close', () => { + console.log('Have a great day!'); + process.exit(0); +}); +``` ## Example: Read File Stream Line-by-Line A common case for `readline`'s `input` option is to pass a filesystem readable stream to it. This is how one could craft line-by-line parsing of a file: - const readline = require('readline'); - const fs = require('fs'); +```js +const readline = require('readline'); +const fs = require('fs'); - const rl = readline.createInterface({ - input: fs.createReadStream('sample.txt') - }); +const rl = readline.createInterface({ + input: fs.createReadStream('sample.txt') +}); - rl.on('line', function (line) { - console.log('Line from file:', line); - }); +rl.on('line', function (line) { + console.log('Line from file:', line); +}); +``` ## readline.clearLine(stream, dir) @@ -291,27 +313,33 @@ Which ends up looking something like: Example: - function completer(line) { - var completions = '.help .error .exit .quit .q'.split(' ') - var hits = completions.filter((c) => { return c.indexOf(line) == 0 }) - // show all completions if none found - return [hits.length ? hits : completions, line] - } +```js +function completer(line) { + var completions = '.help .error .exit .quit .q'.split(' ') + var hits = completions.filter((c) => { return c.indexOf(line) == 0 }) + // show all completions if none found + return [hits.length ? hits : completions, line] +} +``` Also `completer` can be run in async mode if it accepts two arguments: - function completer(linePartial, callback) { - callback(null, [['123'], linePartial]); - } +```js +function completer(linePartial, callback) { + callback(null, [['123'], linePartial]); +} +``` `createInterface` is commonly used with [`process.stdin`][] and [`process.stdout`][] in order to accept user input: - const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); +```js +const readline = require('readline'); +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); +``` Once you have a readline instance, you most commonly listen for the `'line'` event. diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown index d045d7c433..65e05a5062 100644 --- a/doc/api/repl.markdown +++ b/doc/api/repl.markdown @@ -10,16 +10,18 @@ just trying things out. By executing `node` without any arguments from the command-line you will be dropped into the REPL. It has simplistic emacs line-editing. - mjr:~$ node - Type '.help' for options. - > a = [ 1, 2, 3]; - [ 1, 2, 3 ] - > a.forEach(function (v) { - ... console.log(v); - ... }); - 1 - 2 - 3 +``` +mjr:~$ node +Type '.help' for options. +> a = [ 1, 2, 3]; +[ 1, 2, 3 ] +> a.forEach(function (v){ +... console.log(v); +... }); +1 +2 +3 +``` For advanced line-editors, start Node.js with the environmental variable `NODE_NO_READLINE=1`. This will start the main and debugger REPL in canonical @@ -27,7 +29,9 @@ terminal settings which will allow you to use with `rlwrap`. For example, you could add this to your bashrc file: - alias node="env NODE_NO_READLINE=1 rlwrap node" +``` +alias node="env NODE_NO_READLINE=1 rlwrap node" +``` ## Environment Variable Options @@ -73,28 +77,34 @@ accessing `fs` will `require()` the `fs` module as `global.fs`. The special variable `_` (underscore) contains the result of the last expression. - > [ 'a', 'b', 'c' ] - [ 'a', 'b', 'c' ] - > _.length - 3 - > _ += 1 - 4 +``` +> [ 'a', 'b', 'c' ] +[ 'a', 'b', 'c' ] +> _.length +3 +> _ += 1 +4 +``` The REPL provides access to any variables in the global scope. You can expose a variable to the REPL explicitly by assigning it to the `context` object associated with each `REPLServer`. For example: - // repl_test.js - const repl = require('repl'); - var msg = 'message'; +```js +// repl_test.js +const repl = require('repl'); +var msg = 'message'; - repl.start('> ').context.m = msg; +repl.start('> ').context.m = msg; +``` Things in the `context` object appear as local within the REPL: - mjr:~$ node repl_test.js - > m - 'message' +``` +mjr:~$ node repl_test.js +> m +'message' +``` There are a few special REPL commands: @@ -126,17 +136,21 @@ The REPL module internally uses For example, if you have defined an `inspect()` function on an object, like this: - > var obj = { foo: 'this will not show up in the inspect() output' }; - undefined - > obj.inspect = function() { - ... return { bar: 'baz' }; - ... }; - [Function] +``` +> var obj = {foo: 'this will not show up in the inspect() output'}; +undefined +> obj.inspect = function() { +... return {bar: 'baz'}; +... }; +[Function] +``` and try to print `obj` in REPL, it will invoke the custom `inspect()` function: - > obj - { bar: 'baz' } +``` +> obj +{bar: 'baz'} +``` ## Class: REPLServer @@ -152,10 +166,12 @@ to signal `'end'` on the `input` stream. Example of listening for `exit`: - replServer.on('exit', () => { - console.log('Got "exit" event from repl!'); - process.exit(); - }); +```js +replServer.on('exit', () => { + console.log('Got "exit" event from repl!'); + process.exit(); +}); +``` ### Event: 'reset' @@ -168,15 +184,17 @@ be emitted. Example of listening for `reset`: - // Extend the initial repl context. - var replServer = repl.start({ options ... }); - someExtension.extend(r.context); +```js +// Extend the initial repl context. +var replServer = repl.start({ options ... }); +someExtension.extend(r.context); - // When a new context is created extend it as well. - replServer.on('reset', (context) => { - console.log('repl has a new context'); - someExtension.extend(context); - }); +// When a new context is created extend it as well. +replServer.on('reset', (context) => { + console.log('repl has a new context'); + someExtension.extend(context); +}); +``` ### replServer.defineCommand(keyword, cmd) @@ -195,22 +213,26 @@ If a function is provided instead of an object for `cmd`, it is treated as the Example of defining a command: - // repl_test.js - const repl = require('repl'); +```js +// repl_test.js +const repl = require('repl'); - var replServer = repl.start(); - replServer.defineCommand('sayhello', { - help: 'Say hello', - action: function(name) { - this.write(`Hello, ${name}!\n'); - this.displayPrompt(); - } - }); +var replServer = repl.start(); +replServer.defineCommand('sayhello', { + help: 'Say hello', + action: function(name) { + this.write(`Hello, ${name}!\n`); + this.displayPrompt(); + } +}); +``` Example of invoking that command from the REPL: - > .sayhello Node.js User - Hello, Node.js User! +``` +> .sayhello Node.js User +Hello, Node.js User! +``` ### replServer.displayPrompt([preserveCursor]) @@ -277,37 +299,39 @@ will share the same global object but will have unique I/O. Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket: - const net = require('net'); - const repl = require('repl'); - var connections = 0; - - repl.start({ - prompt: 'Node.js via stdin> ', - input: process.stdin, - output: process.stdout - }); - - net.createServer((socket) => { - connections += 1; - repl.start({ - prompt: 'Node.js via Unix socket> ', - input: socket, - output: socket - }).on('exit', () => { - socket.end(); - }) - }).listen('/tmp/node-repl-sock'); - - net.createServer((socket) => { - connections += 1; - repl.start({ - prompt: 'Node.js via TCP socket> ', - input: socket, - output: socket - }).on('exit', () => { - socket.end(); - }); - }).listen(5001); +```js +const net = require('net'); +const repl = require('repl'); +var connections = 0; + +repl.start({ + prompt: 'Node.js via stdin> ', + input: process.stdin, + output: process.stdout +}); + +net.createServer((socket) => { + connections += 1; + repl.start({ + prompt: 'Node.js via Unix socket> ', + input: socket, + output: socket + }).on('exit', () => { + socket.end(); + }) +}).listen('/tmp/node-repl-sock'); + +net.createServer((socket) => { + connections += 1; + repl.start({ + prompt: 'Node.js via TCP socket> ', + input: socket, + output: socket + }).on('exit', () => { + socket.end(); + }); +}).listen(5001); +``` Running this program from the command line will start a REPL on stdin. Other REPL clients may connect through the Unix socket or TCP socket. `telnet` is useful diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index 554ddc222d..939adb08d9 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -47,7 +47,7 @@ interfaces in your own program, please also refer to Almost all Node.js programs, no matter how simple, use Streams in some way. Here is an example of using Streams in an Node.js program: -```javascript +```js const http = require('http'); var server = http.createServer( (req, res) => { @@ -172,7 +172,7 @@ then be passed as soon as it is available. If you just want to get all the data out of the stream as fast as possible, this is the best way to do so. -```javascript +```js var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); @@ -187,7 +187,7 @@ Note that the `'end'` event **will not fire** unless the data is completely consumed. This can be done by switching into flowing mode, or by calling `read()` repeatedly until you get to the end. -```javascript +```js var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); @@ -231,7 +231,7 @@ In the former case, `.read()` will return that data. In the latter case, `.read()` will return null. For instance, in the following example, `foo.txt` is an empty file: -```javascript +```js const fs = require('fs'); var rr = fs.createReadStream('foo.txt'); rr.on('readable', () => { @@ -245,7 +245,7 @@ rr.on('end', () => { The output of running this script is: ``` -bash-3.2$ node test.js +$ node test.js readable: null end ``` @@ -258,7 +258,7 @@ This method returns whether or not the `readable` has been **explicitly** paused by client code (using `readable.pause()` without a corresponding `readable.resume()`). -```javascript +```js var readable = new stream.Readable readable.isPaused() // === false @@ -276,7 +276,7 @@ This method will cause a stream in flowing mode to stop emitting `'data'` events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer. -```javascript +```js var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); @@ -301,7 +301,7 @@ the destination is not overwhelmed by a fast readable stream. Multiple destinations can be piped to safely. -```javascript +```js var readable = getReadableStreamSomehow(); var writable = fs.createWriteStream('file.txt'); // All the data from readable goes into 'file.txt' @@ -311,7 +311,7 @@ readable.pipe(writable); This function returns the destination stream, so you can set up pipe chains like so: -```javascript +```js var r = fs.createReadStream('file.txt'); var z = zlib.createGzip(); var w = fs.createWriteStream('file.txt.gz'); @@ -320,7 +320,7 @@ r.pipe(z).pipe(w); For example, emulating the Unix `cat` command: -```javascript +```js process.stdin.pipe(process.stdout); ``` @@ -331,7 +331,7 @@ false }` as `options` to keep the destination stream open. This keeps `writer` open so that "Goodbye" can be written at the end. -```javascript +```js reader.pipe(writer, { end: false }); reader.on('end', () => { writer.end('Goodbye\n'); @@ -362,7 +362,7 @@ This method should only be called in paused mode. In flowing mode, this method is called automatically until the internal buffer is drained. -```javascript +```js var readable = getReadableStreamSomehow(); readable.on('readable', () => { var chunk; @@ -390,7 +390,7 @@ want to consume the data from a stream, but you *do* want to get to its `'end'` event, you can call [`readable.resume()`][] to open the flow of data. -```javascript +```js var readable = getReadableStreamSomehow(); readable.resume(); readable.on('end', () => { @@ -415,7 +415,7 @@ potentially mangled if you simply pulled the Buffers directly and called `buf.toString(encoding)` on them. If you want to read the data as strings, always use this method. -```javascript +```js var readable = getReadableStreamSomehow(); readable.setEncoding('utf8'); readable.on('data', (chunk) => { @@ -435,7 +435,7 @@ If the destination is not specified, then all pipes are removed. If the destination is specified, but no pipe is set up for it, then this is a no-op. -```javascript +```js var readable = getReadableStreamSomehow(); var writable = fs.createWriteStream('file.txt'); // All the data from readable goes into 'file.txt', @@ -465,7 +465,7 @@ If you find that you must often call `stream.unshift(chunk)` in your programs, consider implementing a [Transform][] stream instead. (See [API for Stream Implementors][].) -```javascript +```js // Pull off a header delimited by \n\n // use unshift() if we get too much // Call the callback with (error, header, stream) @@ -499,6 +499,7 @@ function parseHeader(stream, callback) { } } ``` + Note that, unlike `stream.push(chunk)`, `stream.unshift(chunk)` will not end the reading process by resetting the internal reading state of the stream. This can cause unexpected results if `unshift` is called during a @@ -525,7 +526,7 @@ as a convenience for interacting with old Node.js programs and libraries. For example: -```javascript +```js const OldReader = require('./old-api-module.js').OldReader; const Readable = require('stream').Readable; const oreader = new OldReader; @@ -571,7 +572,7 @@ If a [`writable.write(chunk)`][] call returns false, then the `'drain'` event will indicate when it is appropriate to begin writing more data to the stream. -```javascript +```js // Write the data to the supplied writable stream one million times. // Be attentive to back-pressure. function writeOneMillionTimes(writer, data, encoding, callback) { @@ -628,7 +629,7 @@ writer.on('finish', () => { This is emitted whenever the `pipe()` method is called on a readable stream, adding this writable to its set of destinations. -```javascript +```js var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); writer.on('pipe', (src) => { @@ -645,7 +646,7 @@ reader.pipe(writer); This is emitted whenever the [`unpipe()`][] method is called on a readable stream, removing this writable from its set of destinations. -```javascript +```js var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); writer.on('unpipe', (src) => { @@ -673,7 +674,7 @@ supplied, the callback is attached as a listener on the `'finish'` event. Calling [`write()`][] after calling [`end()`][] will raise an error. -```javascript +```js // write 'hello, ' and then end with 'world!' var file = fs.createWriteStream('example.txt'); file.write('hello, '); @@ -862,7 +863,7 @@ In classes that extend the Readable class, make sure to call the Readable constructor so that the buffering settings can be properly initialized. -#### readable.\_read(size) +#### readable._read(size) * `size` {Number} Number of bytes to read asynchronously @@ -883,7 +884,7 @@ more data from the resource and pushing that data onto the queue. Note: once the `_read()` method is called, it will not be called again until the `push` method is called. -The `size` argument is advisory. Implementations where a "read" is a +The `size` argument is advisory. Implementations where a "read" is a single call that returns data can use this to know how much data to fetch. Implementations where that is not relevant, such as TCP or TLS, may ignore this argument, and simply provide data whenever it @@ -913,7 +914,7 @@ you may be wrapping a lower-level source which has some sort of pause/resume mechanism, and a data callback. In those cases, you could wrap the low-level source object by doing something like this: -```javascript +```js // source is an object with readStop() and readStart() methods, // and an `ondata` member that gets called when it has data, and // an `onend` member that gets called when the data is over. @@ -953,7 +954,7 @@ SourceWrapper.prototype._read = function(size) { This is a basic example of a Readable stream. It emits the numerals from 1 to 1,000,000 in ascending order, and then ends. -```javascript +```js const Readable = require('stream').Readable; const util = require('util'); util.inherits(Counter, Readable); @@ -986,7 +987,7 @@ string. However, this would be better implemented as a [Transform][] stream. See [SimpleProtocol v2][] for a better implementation. -```javascript +```js // A parser for a simple data protocol. // The "header" is a JSON object, followed by 2 \n characters, and // then a message body. @@ -1126,7 +1127,7 @@ and Readable classes respectively. The `'finish'` event is fired after `end` is fired after all data has been output which is after the callback in `_flush` has been called. -#### transform.\_flush(callback) +#### transform._flush(callback) * `callback` {Function} Call this function (optionally with an error argument) when you are done flushing any remaining data. @@ -1153,7 +1154,7 @@ the class that defines it, and should not be called directly by user programs. However, you **are** expected to override this method in your own extension classes. -#### transform.\_transform(chunk, encoding, callback) +#### transform._transform(chunk, encoding, callback) * `chunk` {Buffer | String} The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. @@ -1185,7 +1186,7 @@ particular input chunk. If you supply a second argument to the callback it will be passed to the push method. In other words the following are equivalent: -```javascript +```js transform.prototype._transform = function (data, encoding, callback) { this.push(data); callback(); @@ -1308,7 +1309,7 @@ In classes that extend the Writable class, make sure to call the constructor so that the buffering settings can be properly initialized. -#### writable.\_write(chunk, encoding, callback) +#### writable._write(chunk, encoding, callback) * `chunk` {Buffer | String} The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. @@ -1341,7 +1342,7 @@ the class that defines it, and should not be called directly by user programs. However, you **are** expected to override this method in your own extension classes. -#### writable.\_writev(chunks, callback) +#### writable._writev(chunks, callback) * `chunks` {Array} The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`. @@ -1368,7 +1369,8 @@ This can be done by passing the appropriate methods as constructor options: Examples: ### Duplex -```javascript + +```js var duplex = new stream.Duplex({ read: function(n) { // sets this._read under the hood @@ -1405,7 +1407,8 @@ var duplex = new stream.Duplex({ ``` ### Readable -```javascript + +```js var readable = new stream.Readable({ read: function(n) { // sets this._read under the hood @@ -1418,7 +1421,8 @@ var readable = new stream.Readable({ ``` ### Transform -```javascript + +```js var transform = new stream.Transform({ transform: function(chunk, encoding, next) { // sets this._transform under the hood @@ -1441,7 +1445,8 @@ var transform = new stream.Transform({ ``` ### Writable -```javascript + +```js var writable = new stream.Writable({ write: function(chunk, encoding, next) { // sets this._write under the hood @@ -1521,7 +1526,7 @@ introduces an edge case in the following conditions: For example, consider the following code: -```javascript +```js // WARNING! BROKEN! net.createServer((socket) => { @@ -1541,7 +1546,7 @@ the socket will remain paused forever. The workaround in this situation is to call the `resume()` method to start the flow of data: -```javascript +```js // Workaround net.createServer((socket) => { @@ -1593,7 +1598,7 @@ writable side with `readableObjectMode` and `writableObjectMode` respectively. These options can be used to implement parsers and serializers with Transform streams. -```javascript +```js const util = require('util'); const StringDecoder = require('string_decoder').StringDecoder; const Transform = require('stream').Transform; diff --git a/doc/api/string_decoder.markdown b/doc/api/string_decoder.markdown index 8bcba2cfbd..d1de27dc4a 100644 --- a/doc/api/string_decoder.markdown +++ b/doc/api/string_decoder.markdown @@ -6,14 +6,16 @@ To use this module, do `require('string_decoder')`. StringDecoder decodes a buffer to a string. It is a simple interface to `buffer.toString()` but provides additional support for utf8. - const StringDecoder = require('string_decoder').StringDecoder; - const decoder = new StringDecoder('utf8'); +```js +const StringDecoder = require('string_decoder').StringDecoder; +const decoder = new StringDecoder('utf8'); - const cent = new Buffer([0xC2, 0xA2]); - console.log(decoder.write(cent)); +const cent = new Buffer([0xC2, 0xA2]); +console.log(decoder.write(cent)); - const euro = new Buffer([0xE2, 0x82, 0xAC]); - console.log(decoder.write(euro)); +const euro = new Buffer([0xE2, 0x82, 0xAC]); +console.log(decoder.write(euro)); +``` ## Class: StringDecoder diff --git a/doc/api/synopsis.markdown b/doc/api/synopsis.markdown index 4a051013c4..57e2e3ce4c 100644 --- a/doc/api/synopsis.markdown +++ b/doc/api/synopsis.markdown @@ -5,20 +5,24 @@ An example of a [web server][] written with Node.js which responds with `'Hello World'`: - const http = require('http'); +```js +const http = require('http'); - http.createServer( (request, response) => { - response.writeHead(200, {'Content-Type': 'text/plain'}); - response.end('Hello World\n'); - }).listen(8124); +http.createServer( (request, response) => { + response.writeHead(200, {'Content-Type': 'text/plain'}); + response.end('Hello World\n'); +}).listen(8124); - console.log('Server running at http://127.0.0.1:8124/'); +console.log('Server running at http://127.0.0.1:8124/'); +``` To run the server, put the code into a file called `example.js` and execute it with the node program - > node example.js - Server running at http://127.0.0.1:8124/ +``` +> node example.js +Server running at http://127.0.0.1:8124/ +``` All of the examples in the documentation can be run similarly. diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown index d128d08099..41e7eb6707 100644 --- a/doc/api/tls.markdown +++ b/doc/api/tls.markdown @@ -10,30 +10,40 @@ Secure Socket Layer: encrypted stream communication. TLS/SSL is a public/private key infrastructure. Each client and each server must have a private key. A private key is created like this: - openssl genrsa -out ryans-key.pem 2048 +``` +openssl genrsa -out ryans-key.pem 2048 +``` All servers and some clients need to have a certificate. Certificates are public keys signed by a Certificate Authority or self-signed. The first step to getting a certificate is to create a "Certificate Signing Request" (CSR) file. This is done with: - openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem +``` +openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem +``` To create a self-signed certificate with the CSR, do this: - openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem +``` +openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem +``` Alternatively you can send the CSR to a Certificate Authority for signing. For Perfect Forward Secrecy, it is required to generate Diffie-Hellman parameters: - openssl dhparam -outform PEM -out dhparam.pem 2048 +``` +openssl dhparam -outform PEM -out dhparam.pem 2048 +``` To create .pfx or .p12, do this: - openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \ - -certfile ca-cert.pem -out agent5.pfx +``` +openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \ + -certfile ca-cert.pem -out agent5.pfx +``` - `in`: certificate - `inkey`: private key @@ -81,33 +91,37 @@ times. Node.js is built with a default suite of enabled and disabled TLS ciphers. Currently, the default cipher suite is: - ECDHE-RSA-AES128-GCM-SHA256: - ECDHE-ECDSA-AES128-GCM-SHA256: - ECDHE-RSA-AES256-GCM-SHA384: - ECDHE-ECDSA-AES256-GCM-SHA384: - DHE-RSA-AES128-GCM-SHA256: - ECDHE-RSA-AES128-SHA256: - DHE-RSA-AES128-SHA256: - ECDHE-RSA-AES256-SHA384: - DHE-RSA-AES256-SHA384: - ECDHE-RSA-AES256-SHA256: - DHE-RSA-AES256-SHA256: - HIGH: - !aNULL: - !eNULL: - !EXPORT: - !DES: - !RC4: - !MD5: - !PSK: - !SRP: - !CAMELLIA +``` +ECDHE-RSA-AES128-GCM-SHA256: +ECDHE-ECDSA-AES128-GCM-SHA256: +ECDHE-RSA-AES256-GCM-SHA384: +ECDHE-ECDSA-AES256-GCM-SHA384: +DHE-RSA-AES128-GCM-SHA256: +ECDHE-RSA-AES128-SHA256: +DHE-RSA-AES128-SHA256: +ECDHE-RSA-AES256-SHA384: +DHE-RSA-AES256-SHA384: +ECDHE-RSA-AES256-SHA256: +DHE-RSA-AES256-SHA256: +HIGH: +!aNULL: +!eNULL: +!EXPORT: +!DES: +!RC4: +!MD5: +!PSK: +!SRP: +!CAMELLIA +``` This default can be overriden entirely using the `--tls-cipher-list` command line switch. For instance, the following makes `ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default TLS cipher suite: - node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" +``` +node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" +``` Note that the default cipher suite included within Node.js has been carefully selected to reflect current security best practices and risk mitigation. @@ -242,14 +256,16 @@ established after addition of event listener. Here's an example for using TLS session resumption: - var tlsSessionStore = {}; - server.on('newSession', (id, data, cb) => { - tlsSessionStore[id.toString('hex')] = data; - cb(); - }); - server.on('resumeSession', (id, cb) => { - cb(null, tlsSessionStore[id.toString('hex')] || null); - }); +```js +var tlsSessionStore = {}; +server.on('newSession', (id, data, cb) => { + tlsSessionStore[id.toString('hex')] = data; + cb(); +}); +server.on('resumeSession', (id, cb) => { + cb(null, tlsSessionStore[id.toString('hex')] || null); +}); +``` ### Event: 'secureConnection' @@ -450,27 +466,29 @@ if `false` - only the top certificate without `issuer` property. Example: - { subject: - { C: 'UK', - ST: 'Acknack Ltd', - L: 'Rhys Jones', - O: 'node.js', - OU: 'Test TLS Certificate', - CN: 'localhost' }, - issuerInfo: - { C: 'UK', - ST: 'Acknack Ltd', - L: 'Rhys Jones', - O: 'node.js', - OU: 'Test TLS Certificate', - CN: 'localhost' }, - issuer: - { ... another certificate ... }, - raw: < RAW DER buffer >, - valid_from: 'Nov 11 09:52:22 2009 GMT', - valid_to: 'Nov 6 09:52:22 2029 GMT', - fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF', - serialNumber: 'B9B0D332A1AA5635' } +``` +{ subject: + { C: 'UK', + ST: 'Acknack Ltd', + L: 'Rhys Jones', + O: 'node.js', + OU: 'Test TLS Certificate', + CN: 'localhost' }, + issuerInfo: + { C: 'UK', + ST: 'Acknack Ltd', + L: 'Rhys Jones', + O: 'node.js', + OU: 'Test TLS Certificate', + CN: 'localhost' }, + issuer: + { ... another certificate ... }, + raw: < RAW DER buffer >, + valid_from: 'Nov 11 09:52:22 2009 GMT', + valid_to: 'Nov 6 09:52:22 2029 GMT', + fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF', + serialNumber: 'B9B0D332A1AA5635' } +``` If the peer does not provide a certificate, it returns `null` or an empty object. @@ -615,54 +633,58 @@ The `callback` parameter will be added as a listener for the Here is an example of a client of echo server as described previously: - const tls = require('tls'); - const fs = require('fs'); - - const options = { - // These are necessary only if using the client certificate authentication - key: fs.readFileSync('client-key.pem'), - cert: fs.readFileSync('client-cert.pem'), - - // This is necessary only if the server uses the self-signed certificate - ca: [ fs.readFileSync('server-cert.pem') ] - }; - - var socket = tls.connect(8000, options, () => { - console.log('client connected', - socket.authorized ? 'authorized' : 'unauthorized'); - process.stdin.pipe(socket); - process.stdin.resume(); - }); - socket.setEncoding('utf8'); - socket.on('data', (data) => { - console.log(data); - }); - socket.on('end', () => { - server.close(); - }); +```js +const tls = require('tls'); +const fs = require('fs'); + +const options = { + // These are necessary only if using the client certificate authentication + key: fs.readFileSync('client-key.pem'), + cert: fs.readFileSync('client-cert.pem'), + + // This is necessary only if the server uses the self-signed certificate + ca: [ fs.readFileSync('server-cert.pem') ] +}; + +var socket = tls.connect(8000, options, () => { + console.log('client connected', + socket.authorized ? 'authorized' : 'unauthorized'); + process.stdin.pipe(socket); + process.stdin.resume(); +}); +socket.setEncoding('utf8'); +socket.on('data', (data) => { + console.log(data); +}); +socket.on('end', () => { + server.close(); +}); +``` Or - const tls = require('tls'); - const fs = require('fs'); - - const options = { - pfx: fs.readFileSync('client.pfx') - }; - - var socket = tls.connect(8000, options, () => { - console.log('client connected', - socket.authorized ? 'authorized' : 'unauthorized'); - process.stdin.pipe(socket); - process.stdin.resume(); - }); - socket.setEncoding('utf8'); - socket.on('data', (data) => { - console.log(data); - }); - socket.on('end', () => { - server.close(); - }); +```js +const tls = require('tls'); +const fs = require('fs'); + +const options = { + pfx: fs.readFileSync('client.pfx') +}; + +var socket = tls.connect(8000, options, () => { + console.log('client connected', + socket.authorized ? 'authorized' : 'unauthorized'); + process.stdin.pipe(socket); + process.stdin.resume(); +}); +socket.setEncoding('utf8'); +socket.on('data', (data) => { + console.log(data); +}); +socket.on('end', () => { + server.close(); +}); +``` ## tls.createSecureContext(details) @@ -751,27 +773,29 @@ automatically set as a listener for the [`'secureConnection'`][] event. The - `ciphers`: A string describing the ciphers to use or exclude, separated by `:`. The default cipher suite is: - ECDHE-RSA-AES128-GCM-SHA256: - ECDHE-ECDSA-AES128-GCM-SHA256: - ECDHE-RSA-AES256-GCM-SHA384: - ECDHE-ECDSA-AES256-GCM-SHA384: - DHE-RSA-AES128-GCM-SHA256: - ECDHE-RSA-AES128-SHA256: - DHE-RSA-AES128-SHA256: - ECDHE-RSA-AES256-SHA384: - DHE-RSA-AES256-SHA384: - ECDHE-RSA-AES256-SHA256: - DHE-RSA-AES256-SHA256: - HIGH: - !aNULL: - !eNULL: - !EXPORT: - !DES: - !RC4: - !MD5: - !PSK: - !SRP: - !CAMELLIA + ```js + ECDHE-RSA-AES128-GCM-SHA256: + ECDHE-ECDSA-AES128-GCM-SHA256: + ECDHE-RSA-AES256-GCM-SHA384: + ECDHE-ECDSA-AES256-GCM-SHA384: + DHE-RSA-AES128-GCM-SHA256: + ECDHE-RSA-AES128-SHA256: + DHE-RSA-AES128-SHA256: + ECDHE-RSA-AES256-SHA384: + DHE-RSA-AES256-SHA384: + ECDHE-RSA-AES256-SHA256: + DHE-RSA-AES256-SHA256: + HIGH: + !aNULL: + !eNULL: + !EXPORT: + !DES: + !RC4: + !MD5: + !PSK: + !SRP: + !CAMELLIA + ``` The default cipher suite prefers GCM ciphers for [Chrome's 'modern cryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect @@ -856,67 +880,75 @@ automatically set as a listener for the [`'secureConnection'`][] event. The Here is a simple example echo server: - const tls = require('tls'); - const fs = require('fs'); - - const options = { - key: fs.readFileSync('server-key.pem'), - cert: fs.readFileSync('server-cert.pem'), - - // This is necessary only if using the client certificate authentication. - requestCert: true, - - // This is necessary only if the client uses the self-signed certificate. - ca: [ fs.readFileSync('client-cert.pem') ] - }; - - var server = tls.createServer(options, (socket) => { - console.log('server connected', - socket.authorized ? 'authorized' : 'unauthorized'); - socket.write('welcome!\n'); - socket.setEncoding('utf8'); - socket.pipe(socket); - }); - server.listen(8000, () => { - console.log('server bound'); - }); +```js +const tls = require('tls'); +const fs = require('fs'); + +const options = { + key: fs.readFileSync('server-key.pem'), + cert: fs.readFileSync('server-cert.pem'), + + // This is necessary only if using the client certificate authentication. + requestCert: true, + + // This is necessary only if the client uses the self-signed certificate. + ca: [ fs.readFileSync('client-cert.pem') ] +}; + +var server = tls.createServer(options, (socket) => { + console.log('server connected', + socket.authorized ? 'authorized' : 'unauthorized'); + socket.write('welcome!\n'); + socket.setEncoding('utf8'); + socket.pipe(socket); +}); +server.listen(8000, () => { + console.log('server bound'); +}); +``` Or - const tls = require('tls'); - const fs = require('fs'); +```js +const tls = require('tls'); +const fs = require('fs'); + +const options = { + pfx: fs.readFileSync('server.pfx'), - const options = { - pfx: fs.readFileSync('server.pfx'), + // This is necessary only if using the client certificate authentication. + requestCert: true, - // This is necessary only if using the client certificate authentication. - requestCert: true, +}; - }; +var server = tls.createServer(options, (socket) => { + console.log('server connected', + socket.authorized ? 'authorized' : 'unauthorized'); + socket.write('welcome!\n'); + socket.setEncoding('utf8'); + socket.pipe(socket); +}); +server.listen(8000, () => { + console.log('server bound'); +}); +``` - var server = tls.createServer(options, (socket) => { - console.log('server connected', - socket.authorized ? 'authorized' : 'unauthorized'); - socket.write('welcome!\n'); - socket.setEncoding('utf8'); - socket.pipe(socket); - }); - server.listen(8000, () => { - console.log('server bound'); - }); You can test this server by connecting to it with `openssl s_client`: +``` +openssl s_client -connect 127.0.0.1:8000 +``` - openssl s_client -connect 127.0.0.1:8000 - ## tls.getCiphers() Returns an array with the names of the supported SSL ciphers. Example: - var ciphers = tls.getCiphers(); - console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...] +```js +var ciphers = tls.getCiphers(); +console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...] +``` [OpenSSL cipher list format documentation]: https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT diff --git a/doc/api/tty.markdown b/doc/api/tty.markdown index 861221db99..770990a8de 100644 --- a/doc/api/tty.markdown +++ b/doc/api/tty.markdown @@ -10,10 +10,12 @@ will be a `tty.ReadStream` instance and `process.stdout` will be a `tty.WriteStream` instance. The preferred way to check if Node.js is being run in a TTY context is to check `process.stdout.isTTY`: - $ node -p -e "Boolean(process.stdout.isTTY)" - true - $ node -p -e "Boolean(process.stdout.isTTY)" | cat - false +``` +$ node -p -e "Boolean(process.stdout.isTTY)" +true +$ node -p -e "Boolean(process.stdout.isTTY)" | cat +false +``` ## Class: ReadStream @@ -45,10 +47,12 @@ ever created (and only when `isatty(1)` is true). Emitted by `refreshSize()` when either of the `columns` or `rows` properties has changed. - process.stdout.on('resize', () => { - console.log('screen size has changed!'); - console.log(`${process.stdout.columns}x${process.stdout.rows}`); - }); +```js +process.stdout.on('resize', () => { + console.log('screen size has changed!'); + console.log(`${process.stdout.columns}x${process.stdout.rows}`); +}); +``` ### ws.columns diff --git a/doc/api/url.markdown b/doc/api/url.markdown index c6a4b2351b..ab29c500d8 100644 --- a/doc/api/url.markdown +++ b/doc/api/url.markdown @@ -71,7 +71,9 @@ string will not be in the parsed object. Examples are shown for the URL Spaces (`' '`) and the following characters will be automatically escaped in the properties of URL objects: - < > " ` \r \n \t { } | \ ^ ' +``` +< > " ` \r \n \t { } | \ ^ ' +``` --- @@ -122,6 +124,8 @@ Pass `true` as the third argument to treat `//foo/bar` as Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. Examples: - url.resolve('/one/two/three', 'four') // '/one/two/four' - url.resolve('http://example.com/', '/one') // 'http://example.com/one' - url.resolve('http://example.com/one', '/two') // 'http://example.com/two' +```js +url.resolve('/one/two/three', 'four') // '/one/two/four' +url.resolve('http://example.com/', '/one') // 'http://example.com/one' +url.resolve('http://example.com/one', '/two') // 'http://example.com/two' +``` diff --git a/doc/api/util.markdown b/doc/api/util.markdown index e076fed01b..6c7a9272f6 100644 --- a/doc/api/util.markdown +++ b/doc/api/util.markdown @@ -31,7 +31,7 @@ returned function is a no-op. For example: -```javascript +```js var debuglog = util.debuglog('foo'); var bar = 123; @@ -41,7 +41,9 @@ debuglog('hello from foo [%d]', bar); If this program is run with `NODE_DEBUG=foo` in the environment, then it will output something like: - FOO 3245: hello from foo [123] +``` +FOO 3245: hello from foo [123] +``` where `3245` is the process id. If it is not run with that environment variable set, then it will not print anything. @@ -53,13 +55,15 @@ comma. For example, `NODE_DEBUG=fs,net,tls`. Marks that a method should not be used any more. - const util = require('util'); +```js +const util = require('util'); - exports.puts = util.deprecate(function() { - for (var i = 0, len = arguments.length; i < len; ++i) { - process.stdout.write(arguments[i] + '\n'); - } - }, 'util.puts: Use console.log instead'); +exports.puts = util.deprecate(function() { + for (var i = 0, len = arguments.length; i < len; ++i) { + process.stdout.write(arguments[i] + '\n'); + } +}, 'util.puts: Use console.log instead'); +``` It returns a modified function which warns once by default. @@ -100,19 +104,25 @@ contains circular references. If the placeholder does not have a corresponding argument, the placeholder is not replaced. - util.format('%s:%s', 'foo'); // 'foo:%s' +```js +util.format('%s:%s', 'foo'); // 'foo:%s' +``` If there are more arguments than placeholders, the extra arguments are coerced to strings (for objects and symbols, `util.inspect()` is used) and then concatenated, delimited by a space. - util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz' +```js +util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz' +``` If the first argument is not a format string then `util.format()` returns a string that is the concatenation of all its arguments separated by spaces. Each argument is converted to a string with `util.inspect()`. - util.format(1, 2, 3); // '1 2 3' +```js +util.format(1, 2, 3); // '1 2 3' +``` ## util.inherits(constructor, superConstructor) @@ -123,28 +133,30 @@ prototype of `constructor` will be set to a new object created from As an additional convenience, `superConstructor` will be accessible through the `constructor.super_` property. - const util = require('util'); - const EventEmitter = require('events'); +```js +const util = require('util'); +const EventEmitter = require('events'); - function MyStream() { - EventEmitter.call(this); - } +function MyStream() { + EventEmitter.call(this); +} - util.inherits(MyStream, EventEmitter); +util.inherits(MyStream, EventEmitter); - MyStream.prototype.write = function(data) { - this.emit('data', data); - } +MyStream.prototype.write = function(data) { + this.emit('data', data); +} - var stream = new MyStream(); +var stream = new MyStream(); - console.log(stream instanceof EventEmitter); // true - console.log(MyStream.super_ === EventEmitter); // true +console.log(stream instanceof EventEmitter); // true +console.log(MyStream.super_ === EventEmitter); // true - stream.on('data', (data) => { - console.log(`Received data: "${data}"`); - }) - stream.write('It works!'); // Received data: "It works!" +stream.on('data', (data) => { + console.log(`Received data: "${data}"`); +}) +stream.write('It works!'); // Received data: "It works!" +``` ## util.inspect(object[, options]) @@ -169,9 +181,11 @@ formatted string: Example of inspecting all properties of the `util` object: - const util = require('util'); +```js +const util = require('util'); - console.log(util.inspect(util, { showHidden: true, depth: null })); +console.log(util.inspect(util, { showHidden: true, depth: null })); +``` Values may supply their own custom `inspect(depth, opts)` functions, when called they receive the current depth in the recursive inspection, as well as @@ -208,27 +222,31 @@ There are also `bold`, `italic`, `underline` and `inverse` codes. Objects also may define their own `inspect(depth)` function which `util.inspect()` will invoke and use the result of when inspecting the object: - const util = require('util'); +```js +const util = require('util'); - var obj = { name: 'nate' }; - obj.inspect = function(depth) { - return `{${this.name}}`; - }; +var obj = { name: 'nate' }; +obj.inspect = function(depth) { + return `{${this.name}}`; +}; - util.inspect(obj); - // "{nate}" +util.inspect(obj); + // "{nate}" +``` You may also return another Object entirely, and the returned String will be formatted according to the returned Object. This is similar to how `JSON.stringify()` works: - var obj = { foo: 'this will not show up in the inspect() output' }; - obj.inspect = function(depth) { - return { bar: 'baz' }; - }; +```js +var obj = { foo: 'this will not show up in the inspect() output' }; +obj.inspect = function(depth) { + return { bar: 'baz' }; +}; - util.inspect(obj); - // "{ bar: 'baz' }" +util.inspect(obj); + // "{ bar: 'baz' }" +``` ## util.isArray(object) @@ -238,14 +256,16 @@ Internal alias for [`Array.isArray`][]. Returns `true` if the given "object" is an `Array`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isArray([]) - // true - util.isArray(new Array) - // true - util.isArray({}) - // false +util.isArray([]) + // true +util.isArray(new Array) + // true +util.isArray({}) + // false +``` ## util.isBoolean(object) @@ -253,14 +273,16 @@ Returns `true` if the given "object" is an `Array`. `false` otherwise. Returns `true` if the given "object" is a `Boolean`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isBoolean(1) - // false - util.isBoolean(0) - // false - util.isBoolean(false) - // true +util.isBoolean(1) + // false +util.isBoolean(0) + // false +util.isBoolean(false) + // true +``` ## util.isBuffer(object) @@ -270,14 +292,16 @@ Use `Buffer.isBuffer()` instead. Returns `true` if the given "object" is a `Buffer`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isBuffer({ length: 0 }) - // false - util.isBuffer([]) - // false - util.isBuffer(new Buffer('hello world')) - // true +util.isBuffer({ length: 0 }) + // false +util.isBuffer([]) + // false +util.isBuffer(new Buffer('hello world')) + // true +``` ## util.isDate(object) @@ -285,14 +309,16 @@ Returns `true` if the given "object" is a `Buffer`. `false` otherwise. Returns `true` if the given "object" is a `Date`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isDate(new Date()) - // true - util.isDate(Date()) - // false (without 'new' returns a String) - util.isDate({}) - // false +util.isDate(new Date()) + // true +util.isDate(Date()) + // false (without 'new' returns a String) +util.isDate({}) + // false +``` ## util.isError(object) @@ -300,14 +326,16 @@ Returns `true` if the given "object" is a `Date`. `false` otherwise. Returns `true` if the given "object" is an [`Error`][]. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isError(new Error()) - // true - util.isError(new TypeError()) - // true - util.isError({ name: 'Error', message: 'an error occurred' }) - // false +util.isError(new Error()) + // true +util.isError(new TypeError()) + // true +util.isError({ name: 'Error', message: 'an error occurred' }) + // false +``` ## util.isFunction(object) @@ -315,17 +343,19 @@ Returns `true` if the given "object" is an [`Error`][]. `false` otherwise. Returns `true` if the given "object" is a `Function`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - function Foo() {} - var Bar = function() {}; +function Foo() {} +var Bar = function() {}; - util.isFunction({}) - // false - util.isFunction(Foo) - // true - util.isFunction(Bar) - // true +util.isFunction({}) + // false +util.isFunction(Foo) + // true +util.isFunction(Bar) + // true +``` ## util.isNull(object) @@ -333,14 +363,16 @@ Returns `true` if the given "object" is a `Function`. `false` otherwise. Returns `true` if the given "object" is strictly `null`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isNull(0) - // false - util.isNull(undefined) - // false - util.isNull(null) - // true +util.isNull(0) + // false +util.isNull(undefined) + // false +util.isNull(null) + // true +``` ## util.isNullOrUndefined(object) @@ -348,14 +380,16 @@ Returns `true` if the given "object" is strictly `null`. `false` otherwise. Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isNullOrUndefined(0) - // false - util.isNullOrUndefined(undefined) - // true - util.isNullOrUndefined(null) - // true +util.isNullOrUndefined(0) + // false +util.isNullOrUndefined(undefined) + // true +util.isNullOrUndefined(null) + // true +``` ## util.isNumber(object) @@ -363,16 +397,18 @@ Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise Returns `true` if the given "object" is a `Number`. `false` otherwise. - const util = require('util'); - - util.isNumber(false) - // false - util.isNumber(Infinity) - // true - util.isNumber(0) - // true - util.isNumber(NaN) - // true +```js +const util = require('util'); + +util.isNumber(false) + // false +util.isNumber(Infinity) + // true +util.isNumber(0) + // true +util.isNumber(NaN) + // true +``` ## util.isObject(object) @@ -381,16 +417,18 @@ Returns `true` if the given "object" is a `Number`. `false` otherwise. Returns `true` if the given "object" is strictly an `Object` __and__ not a `Function`. `false` otherwise. - const util = require('util'); - - util.isObject(5) - // false - util.isObject(null) - // false - util.isObject({}) - // true - util.isObject(function(){}) - // false +```js +const util = require('util'); + +util.isObject(5) + // false +util.isObject(null) + // false +util.isObject({}) + // true +util.isObject(function(){}) + // false +``` ## util.isPrimitive(object) @@ -398,26 +436,28 @@ Returns `true` if the given "object" is strictly an `Object` __and__ not a Returns `true` if the given "object" is a primitive type. `false` otherwise. - const util = require('util'); - - util.isPrimitive(5) - // true - util.isPrimitive('foo') - // true - util.isPrimitive(false) - // true - util.isPrimitive(null) - // true - util.isPrimitive(undefined) - // true - util.isPrimitive({}) - // false - util.isPrimitive(function() {}) - // false - util.isPrimitive(/^$/) - // false - util.isPrimitive(new Date()) - // false +```js +const util = require('util'); + +util.isPrimitive(5) + // true +util.isPrimitive('foo') + // true +util.isPrimitive(false) + // true +util.isPrimitive(null) + // true +util.isPrimitive(undefined) + // true +util.isPrimitive({}) + // false +util.isPrimitive(function() {}) + // false +util.isPrimitive(/^$/) + // false +util.isPrimitive(new Date()) + // false +``` ## util.isRegExp(object) @@ -425,14 +465,16 @@ Returns `true` if the given "object" is a primitive type. `false` otherwise. Returns `true` if the given "object" is a `RegExp`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isRegExp(/some regexp/) - // true - util.isRegExp(new RegExp('another regexp')) - // true - util.isRegExp({}) - // false +util.isRegExp(/some regexp/) + // true +util.isRegExp(new RegExp('another regexp')) + // true +util.isRegExp({}) + // false +``` ## util.isString(object) @@ -440,16 +482,18 @@ Returns `true` if the given "object" is a `RegExp`. `false` otherwise. Returns `true` if the given "object" is a `String`. `false` otherwise. - const util = require('util'); - - util.isString('') - // true - util.isString('foo') - // true - util.isString(String('foo')) - // true - util.isString(5) - // false +```js +const util = require('util'); + +util.isString('') + // true +util.isString('foo') + // true +util.isString(String('foo')) + // true +util.isString(5) + // false +``` ## util.isSymbol(object) @@ -457,14 +501,16 @@ Returns `true` if the given "object" is a `String`. `false` otherwise. Returns `true` if the given "object" is a `Symbol`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - util.isSymbol(5) - // false - util.isSymbol('foo') - // false - util.isSymbol(Symbol('foo')) - // true +util.isSymbol(5) + // false +util.isSymbol('foo') + // false +util.isSymbol(Symbol('foo')) + // true +``` ## util.isUndefined(object) @@ -472,15 +518,17 @@ Returns `true` if the given "object" is a `Symbol`. `false` otherwise. Returns `true` if the given "object" is `undefined`. `false` otherwise. - const util = require('util'); +```js +const util = require('util'); - var foo; - util.isUndefined(5) - // false - util.isUndefined(foo) - // true - util.isUndefined(null) - // false +var foo; +util.isUndefined(5) + // false +util.isUndefined(foo) + // true +util.isUndefined(null) + // false +``` ## util.log(string) diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown index c6d760b0d5..6aa763add1 100644 --- a/doc/api/v8.markdown +++ b/doc/api/v8.markdown @@ -10,7 +10,7 @@ therefore not covered under the stability index. Returns an object with the following properties -``` +```js { total_heap_size: 7326976, total_heap_size_executable: 4194304, @@ -82,7 +82,7 @@ and their effects is available [here][]. Usage: -``` +```js // Print GC events to stdout for one minute. const v8 = require('v8'); v8.setFlagsFromString('--trace_gc'); diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index 07e99ac735..a1f412e6ba 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -6,7 +6,9 @@ You can access this module with: - const vm = require('vm'); +```js +const vm = require('vm'); +``` JavaScript code can be compiled and run immediately or compiled, saved, and run later. @@ -48,24 +50,26 @@ and returns the result. Running code does not have access to local scope. Example: compile code that increments a global variable and sets one, then execute the code multiple times. These globals are contained in the sandbox. - const util = require('util'); - const vm = require('vm'); +```js +const util = require('util'); +const vm = require('vm'); - var sandbox = { - animal: 'cat', - count: 2 - }; +var sandbox = { + animal: 'cat', + count: 2 +}; - var context = new vm.createContext(sandbox); - var script = new vm.Script('count += 1; name = "kitty"'); +var context = new vm.createContext(sandbox); +var script = new vm.Script('count += 1; name = "kitty"'); - for (var i = 0; i < 10; ++i) { - script.runInContext(context); - } +for (var i = 0; i < 10; ++i) { + script.runInContext(context); +} - console.log(util.inspect(sandbox)); +console.log(util.inspect(sandbox)); - // { animal: 'cat', count: 12, name: 'kitty' } +// { animal: 'cat', count: 12, name: 'kitty' } +``` Note that running untrusted code is a tricky business requiring great care. `script.runInContext` is quite useful, but safely running untrusted code @@ -85,20 +89,22 @@ Example: compile code that sets a global variable, then execute the code multiple times in different contexts. These globals are set on and contained in the sandboxes. - const util = require('util'); - const vm = require('vm'); +```js +const util = require('util'); +const vm = require('vm'); - const sandboxes = [{}, {}, {}]; +const sandboxes = [{}, {}, {}]; - const script = new vm.Script('globalVar = "set"'); +const script = new vm.Script('globalVar = "set"'); - sandboxes.forEach((sandbox) => { - script.runInNewContext(sandbox); - }); +sandboxes.forEach((sandbox) => { + script.runInNewContext(sandbox); +}); - console.log(util.inspect(sandboxes)); +console.log(util.inspect(sandboxes)); - // [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] +// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] +``` Note that running untrusted code is a tricky business requiring great care. `script.runInNewContext` is quite useful, but safely running untrusted code @@ -114,19 +120,21 @@ current `global` object. Example of using `script.runInThisContext` to compile code once and run it multiple times: - const vm = require('vm'); +```js +const vm = require('vm'); - global.globalVar = 0; +global.globalVar = 0; - const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); +const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); - for (var i = 0; i < 1000; ++i) { - script.runInThisContext(); - } +for (var i = 0; i < 1000; ++i) { + script.runInThisContext(); +} - console.log(globalVar); +console.log(globalVar); - // 1000 +// 1000 +``` The options for running a script are: @@ -176,18 +184,20 @@ returns the result. Running code does not have access to local scope. The Example: compile and execute different scripts in a single existing context. - const util = require('util'); - const vm = require('vm'); +```js +const util = require('util'); +const vm = require('vm'); - const sandbox = { globalVar: 1 }; - vm.createContext(sandbox); +const sandbox = { globalVar: 1 }; +vm.createContext(sandbox); - for (var i = 0; i < 10; ++i) { - vm.runInContext('globalVar *= 2;', sandbox); - } - console.log(util.inspect(sandbox)); +for (var i = 0; i < 10; ++i) { + vm.runInContext('globalVar *= 2;', sandbox); +} +console.log(util.inspect(sandbox)); - // { globalVar: 1024 } +// { globalVar: 1024 } +``` Note that running untrusted code is a tricky business requiring great care. `vm.runInContext` is quite useful, but safely running untrusted code requires a @@ -198,8 +208,10 @@ separate process. `vm.runInDebugContext` compiles and executes `code` inside the V8 debug context. The primary use case is to get access to the V8 debug object: - const Debug = vm.runInDebugContext('Debug'); - Debug.scripts().forEach(function(script) { console.log(script.name); }); +```js +const Debug = vm.runInDebugContext('Debug'); +Debug.scripts().forEach(function(script) { console.log(script.name); }); +``` Note that the debug context and object are intrinsically tied to V8's debugger implementation and may change (or even get removed) without prior warning. @@ -217,18 +229,20 @@ the sandbox as the global object and returns the result. Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox. - const util = require('util'); - const vm = require('vm'); +```js +const util = require('util'); +const vm = require('vm'); - const sandbox = { - animal: 'cat', - count: 2 - }; +const sandbox = { + animal: 'cat', + count: 2 +}; - vm.runInNewContext('count += 1; name = "kitty"', sandbox); - console.log(util.inspect(sandbox)); +vm.runInNewContext('count += 1; name = "kitty"', sandbox); +console.log(util.inspect(sandbox)); - // { animal: 'cat', count: 3, name: 'kitty' } +// { animal: 'cat', count: 3, name: 'kitty' } +``` Note that running untrusted code is a tricky business requiring great care. `vm.runInNewContext` is quite useful, but safely running untrusted code requires @@ -242,19 +256,21 @@ code does not have access to local scope, but does have access to the current Example of using `vm.runInThisContext` and `eval` to run the same code: - const vm = require('vm'); - var localVar = 'initial value'; +```js +const vm = require('vm'); +var localVar = 'initial value'; - const vmResult = vm.runInThisContext('localVar = "vm";'); - console.log('vmResult: ', vmResult); - console.log('localVar: ', localVar); +const vmResult = vm.runInThisContext('localVar = "vm";'); +console.log('vmResult: ', vmResult); +console.log('localVar: ', localVar); - const evalResult = eval('localVar = "eval";'); - console.log('evalResult: ', evalResult); - console.log('localVar: ', localVar); +const evalResult = eval('localVar = "eval";'); +console.log('evalResult: ', evalResult); +console.log('localVar: ', localVar); - // vmResult: 'vm', localVar: 'initial value' - // evalResult: 'eval', localVar: 'eval' +// vmResult: 'vm', localVar: 'initial value' +// evalResult: 'eval', localVar: 'eval' +``` `vm.runInThisContext` does not have access to the local scope, so `localVar` is unchanged. `eval` does have access to the local scope, so `localVar` is changed. diff --git a/doc/api/zlib.markdown b/doc/api/zlib.markdown index 9e48225530..61a2deb35a 100644 --- a/doc/api/zlib.markdown +++ b/doc/api/zlib.markdown @@ -15,29 +15,33 @@ is a readable/writable Stream. Compressing or decompressing a file can be done by piping an fs.ReadStream into a zlib stream, then into an fs.WriteStream. - const gzip = zlib.createGzip(); - const fs = require('fs'); - const inp = fs.createReadStream('input.txt'); - const out = fs.createWriteStream('input.txt.gz'); +```js +const gzip = zlib.createGzip(); +const fs = require('fs'); +const inp = fs.createReadStream('input.txt'); +const out = fs.createWriteStream('input.txt.gz'); - inp.pipe(gzip).pipe(out); +inp.pipe(gzip).pipe(out); +``` Compressing or decompressing data in one step can be done by using the convenience methods. - const input = '.................................'; - zlib.deflate(input, function(err, buffer) { - if (!err) { - console.log(buffer.toString('base64')); - } - }); - - const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64'); - zlib.unzip(buffer, function(err, buffer) { - if (!err) { - console.log(buffer.toString()); - } - }); +```js +const input = '.................................'; +zlib.deflate(input, function(err, buffer) { + if (!err) { + console.log(buffer.toString('base64')); + } +}); + +const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64'); +zlib.unzip(buffer, function(err, buffer) { + if (!err) { + console.log(buffer.toString()); + } +}); +``` To use this module in an HTTP client or server, use the [accept-encoding][] on requests, and the [content-encoding][] header on responses. @@ -47,57 +51,59 @@ the basic concept.** Zlib encoding can be expensive, and the results ought to be cached. See [Memory Usage Tuning][] for more information on the speed/memory/compression tradeoffs involved in zlib usage. - // client request example - const zlib = require('zlib'); - const http = require('http'); - const fs = require('fs'); - const request = http.get({ host: 'izs.me', - path: '/', - port: 80, - headers: { 'accept-encoding': 'gzip,deflate' } }); - request.on('response', (response) => { - var output = fs.createWriteStream('izs.me_index.html'); - - switch (response.headers['content-encoding']) { - // or, just use zlib.createUnzip() to handle both cases - case 'gzip': - response.pipe(zlib.createGunzip()).pipe(output); - break; - case 'deflate': - response.pipe(zlib.createInflate()).pipe(output); - break; - default: - response.pipe(output); - break; - } - }); - - // server example - // Running a gzip operation on every request is quite expensive. - // It would be much more efficient to cache the compressed buffer. - const zlib = require('zlib'); - const http = require('http'); - const fs = require('fs'); - http.createServer((request, response) => { - var raw = fs.createReadStream('index.html'); - var acceptEncoding = request.headers['accept-encoding']; - if (!acceptEncoding) { - acceptEncoding = ''; - } - - // Note: this is not a conformant accept-encoding parser. - // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 - if (acceptEncoding.match(/\bdeflate\b/)) { - response.writeHead(200, { 'content-encoding': 'deflate' }); - raw.pipe(zlib.createDeflate()).pipe(response); - } else if (acceptEncoding.match(/\bgzip\b/)) { - response.writeHead(200, { 'content-encoding': 'gzip' }); - raw.pipe(zlib.createGzip()).pipe(response); - } else { - response.writeHead(200, {}); - raw.pipe(response); - } - }).listen(1337); +```js +// client request example +const zlib = require('zlib'); +const http = require('http'); +const fs = require('fs'); +const request = http.get({ host: 'izs.me', + path: '/', + port: 80, + headers: { 'accept-encoding': 'gzip,deflate' } }); +request.on('response', (response) => { + var output = fs.createWriteStream('izs.me_index.html'); + + switch (response.headers['content-encoding']) { + // or, just use zlib.createUnzip() to handle both cases + case 'gzip': + response.pipe(zlib.createGunzip()).pipe(output); + break; + case 'deflate': + response.pipe(zlib.createInflate()).pipe(output); + break; + default: + response.pipe(output); + break; + } +}); + +// server example +// Running a gzip operation on every request is quite expensive. +// It would be much more efficient to cache the compressed buffer. +const zlib = require('zlib'); +const http = require('http'); +const fs = require('fs'); +http.createServer((request, response) => { + var raw = fs.createReadStream('index.html'); + var acceptEncoding = request.headers['accept-encoding']; + if (!acceptEncoding) { + acceptEncoding = ''; + } + + // Note: this is not a conformant accept-encoding parser. + // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 + if (acceptEncoding.match(/\bdeflate\b/)) { + response.writeHead(200, { 'content-encoding': 'deflate' }); + raw.pipe(zlib.createDeflate()).pipe(response); + } else if (acceptEncoding.match(/\bgzip\b/)) { + response.writeHead(200, { 'content-encoding': 'gzip' }); + raw.pipe(zlib.createGzip()).pipe(response); + } else { + response.writeHead(200, {}); + raw.pipe(response); + } +}).listen(1337); +``` ## Memory Usage Tuning @@ -107,7 +113,9 @@ From `zlib/zconf.h`, modified to node.js's usage: The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) +``` +(1 << (windowBits+2)) + (1 << (memLevel+9)) +``` that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. @@ -115,13 +123,17 @@ that is: 128K for windowBits=15 + 128K for memLevel = 8 For example, if you want to reduce the default memory requirements from 256K to 128K, set the options to: - { windowBits: 14, memLevel: 7 } +``` +{ windowBits: 14, memLevel: 7 } +``` Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) - 1 << windowBits +``` +1 << windowBits +``` that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects.