## page was renamed from NodeJS = NodeJS = Node.js is a platform built on Chrome's [[Javascript]] runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices. [[http://www.nodejs.org/]] http://blog.4psa.com/the-callback-syndrome-in-node-js/ == SlackBuild Slackware64 14.0 == {{{#!highlight sh su cd /tmp wget http://slackbuilds.org/slackbuilds/14.0/network/node.tar.gz tar xvzf node.tar.gz cd node wget http://nodejs.org/dist/v0.10.12/node-v0.10.12.tar.gz ./node.SlackBuild installpkg /tmp/node-0.10.12-x86_64-1_SBo.tgz }}} Package 64 bit: [[attachment:node-0.10.12-x86_64-1_SBo.tgz]] == Sample app == === main.js === {{{#!highlight javascript var assert = require('assert'); // TDD var fs = require('fs'); // file system var util = require('util'); //-------------------- var Dummy = require('./dummy.js'); var Local = require('./local.js'); var conf=require('./config.js') // Configuration console.log( conf.configX['foo'] ); console.log( conf.configX['bar'] ); var d1 = new Dummy(12345); var d2 = new Dummy(67890); var d3 = new Dummy(112233); assert.equal(d1.methodA.call(d2),67890,''); assert.equal(d1.methodA.call(d3),112233,''); assert.equal(d3.methodA.call(d1),12345,''); var l1 = new Local('local1',10,11); var l2 = new Local('local2',20,21); var l3 = new Local('local3',30,31); assert.equal(l1.getPoint().getX(),10,''); assert.equal(l2.getPoint().getX(),20,''); assert.equal(l3.getPoint().getX(),30,''); // async readdir fs.readdir('/tmp', cbReaddir); function cbReaddir(err,files){ for(var i=0; i< files.length;i++){ console.log(files[i]); } } //async append file fs.appendFile('/tmp/test.txt', 'data to append\r\n', cbAppendFile); function cbAppendFile(err) { if (!err) { console.log('The "data to append" was appended to file!'); } } function hexcounter(value,callback){ console.log('HC:',value); if(value<15){ setImmediate(function(){callback(value+1,callback);}); } else{ setImmediate(function(){callback(0,callback);}); } } function octalcounter(){ var timeout=500; if(arguments.length===1){ console.log('OC:',arguments[0]); setTimeout(octalcounter,timeout,1,2) } if(arguments.length===2){ var a0=Number(arguments[0]); var a1=Number(arguments[1]); console.log(util.format('%s %d %d','OC:',a0,a1)); setTimeout(octalcounter,timeout,a0+1,a1+1); } } hexcounter(2,hexcounter); octalcounter(12300); process.on('SIGHUP', onSIGHUP); function onSIGHUP() { console.log('SIGHUP received',arguments.length); } process.on('SIGTERM', onSIGTERM); function onSIGTERM() { console.log('SIGTERM received',arguments.length); } }}} config.js {{{#!highlight javascript exports.configX= { "foo":"fooValue", "bar":123 } }}} === dummy.js === {{{#!highlight javascript function Dummy(value1) { var self = this; self._value1 = value1; } Dummy.prototype.methodA = function() { var self = this; return self._value1; }; module.exports = Dummy; }}} point.js {{{#!highlight javascript function Point(x,y){ this.x=x; this.y=y; } Point.prototype.getX=function(){ return this.x; }; Point.prototype.getY=function(){ return this.y; }; module.exports = Point; }}} local.js {{{#!highlight javascript var Point = require('./point.js'); function Local(name,x,y){ this.name = name; this.point = new Point(x,y); } Local.prototype.getName=function(){ return this.name; }; Local.prototype.getPoint=function(){ return this.point; }; module.exports = Local; }}} == node-gyp == node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. https://github.com/TooTallNate/node-gyp === Install with npm === {{{#!highlight sh su npm install -g node-gyp node-gyp }}} === Hello world gyp === Based on https://github.com/joyent/node/tree/master/test/addons/hello-world {{{#!highlight sh cd /tmp/ nano test.js nano binding.cc nano binding.gyp node-gyp configure #The configure step looks for the binding.gyp file in the current directory node-gyp build # gave an error building ! }}} Based on https://github.com/rvagg/node-addon-examples === binding.gyp === {{{ { "targets": [ { "target_name": "hello", "sources": [ "hello.cc" ] } ] } }}} === hello.cc === {{{#!highlight cpp #include #include using namespace v8; Handle Method(const Arguments& args) { HandleScope scope; return scope.Close(String::New("world")); } void init(Handle exports) { exports->Set(String::NewSymbol("hello"), FunctionTemplate::New(Method)->GetFunction()); } NODE_MODULE(hello, init) }}} * nano hello.js {{{#!highlight javascript var addon = require('./build/Release/hello'); console.log(addon.hello()); // 'world' }}} {{{#!highlight sh node hello.js }}} === build.sh === {{{#!highlight sh #!/bin/sh GYP=/usr/local/lib/node_modules/npm/bin/node-gyp-bin/node-gyp $GYP clean $GYP configure $GYP build }}} == Read text file example == {{{#!highlight javascript var fs = require('fs'); // file system function cbReadFile(err, data) { if (err) { throw err; } var ds = data.toString(); // data is of type Buffer var buffer = ''; for ( var idx = 0; idx < ds.length; idx++) { if (ds[idx] != '\n') { buffer = buffer + ds[idx]; } else { console.log(buffer); buffer = ''; } } } fs.readFile('/etc/passwd', cbReadFile); }}} == Context with this and bind == https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. {{{#!highlight javascript /*Constructor function*/ function Counter(){ this.counter=0; } Counter.prototype.run=function(){ console.log('counter:',this.counter); this.counter++; //recall run setTimeout(this.run.bind(this),1000); }; var c = new Counter(); setTimeout( c.run.bind(c) ,1000); // apply context of c to this }}} == Install from source Node 4.6.0 == {{{#!highlight sh wget https://nodejs.org/dist/v4.6.0/node-v4.6.0.tar.gz cp node-v4.6.0.tar.gz /tmp cd /tmp tar xvif node-v4.6.0.tar.gz cd node-4.6.0 ./configure make clean make make install }}} == Install node 6.9.1 on Slackware64 14.2 == {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/development/nodejs.tar.gz tar xvzf nodejs.tar.gz cd nodejs wget https://nodejs.org/dist/v6.9.1/node-v6.9.1.tar.xz ./nodejs.SlackBuild installpkg /tmp/nodejs-6.9.1-x86_64-1_SBo.tgz }}} == testApp with mongoose for AWS ElasticBeanstalk == === Install Node 6.x in Ubuntu (vagrant on Windows) === {{{#!highlight bash sudo bash apt-get purge nodejs npm curl -sL https://deb.nodesource.com/setup_6.x | bash - apt-get install -y nodejs exit npm config set bin-links false # /vagrant folder in reality hosted in windows npm install }}} === Structure === {{{ . ├── app.js ├── config.js ├── index.html ├── package.json └── utils.js }}} === app.js === {{{#!highlight javascript /** * npm install * npm start * MONGOURL=mongodb://127.0.0.1/testdb npm start * mongo * use testdb * show collections * dummies * db.dummies.find() * * zip ../testAppNodeJS.zip app.js config.js index.html package.json utils.js * * Deploying an Artifact Instead of the Project Folder * You can tell the EB CLI to deploy a ZIP or WAR file that you generate as part of a separate * build process by adding the following lines to .elasticbeanstalk/config.yml in your project * folder. * deploy: * artifact: path/to/buildartifact.zip */ var mongoose = require('mongoose'); var http = require('http'); var ut = require('./utils') var cfg = require('./config') var dummyModel = mongoose.model('Dummy', mongoose.Schema( { foo: String }) ); mongoose.connect( cfg.getMongoURL() ); mongoose.connection.once('open', function(){ ut.log('Connected to ' + cfg.getMongoURL() ); var dummy = new dummyModel({ foo: 'Connected to MongoDB ' + new Date().toISOString() }); dummy.save(); }); function requestListener(req, res) { if (req.method === ut.HTTP_METHOD_POST) { var body = ''; req.on('data', function(chunk) { body += chunk; }); req.on('end', function() { ut.log('Received URL ' + req.url ); if (req.url === '/') { ut.log('Received message: ' + body); } else if (req.url === '/scheduled') { ut.log('Received task ' + req.headers['x-aws-sqsd-taskname'] + ' scheduled at ' + req.headers['x-aws-sqsd-scheduled-at']); } else if (req.url === '/addDummy') { var dummy = req.headers['dummy']; ut.log('Received dummy ' + dummy ); dummyModel.create({ foo: dummy }); } res.writeHead(ut.HTTP_200_OK, 'OK', ut.getTextPlain() ); res.end(); }); } else { res.writeHead(ut.HTTP_200_OK); res.write( ut.getIndex() ); res.end(); } } var server = http.createServer(requestListener); // Listen on port 3000, IP defaults to 127.0.0.1 server.listen( cfg.getPort() ); // Put a friendly message on the terminal ut.log('Server running at http://127.0.0.1:' + cfg.getPort() + '/'); ut.showEnvironmentVars(); }}} === config.js === {{{#!highlight javascript // Constructor function function Config(){ }; //Static Config.getPort = function() { return process.env.PORT || 8081; }; Config.getTestVar = function() { return process.env.TESTVAR || '????'; }; Config.getMongoURL = function() { return process.env.MONGOURL || '????'; }; module.exports = Config }}} === utils.js === {{{#!highlight javascript var fs = require('fs'); // Constructor function function Utils() { }; // Constants Utils.HTTP_METHOD_POST='POST'; Utils.HTTP_METHOD_GET='GET'; Utils.HTTP_200_OK=200; // Static Utils.showEnvironmentVars= function() { Utils.log('## Environment variables ##'); for(var key in process.env){ Utils.log('Environment variable ' + key + '==' + process.env[key] ); } }; Utils.log = function(entry) { var msg = new Date().toISOString() + ' - ' + entry + '\n'; fs.appendFileSync('/tmp/sample-app.log', msg); console.log(entry); }; Utils.getIndex = function() { return fs.readFileSync('index.html'); }; Utils.getTextPlain = function() { return {'Content-Type': 'text/plain'}; }; module.exports = Utils }}} === package.json === {{{#!highlight javascript { "name": "Elastic-Beanstalk-Sample-App", "version": "0.0.1", "private": true, "dependencies": { "mongoose":"latest" }, "scripts": { "start": "node app.js", "package": "CURRDATE=$(date -u \"+%Y%m%dT%H%m%S%Z\"); rm testAppNodeJS*.zip; zip -r testAppNodeJS-$CURRDATE.zip app.js config.js index.html package.json utils.js node_modules" } } }}} === index.html === {{{#!highlight html Elastic Beanstalk VB test

Congratulations

Your first AWS Elastic Beanstalk Node.js application is now running on your own dedicated environment in the AWS Cloud

What's Next?

}}} {{{#!highlight sh npm install MONGOURL=mongodb://aaaaaa npm start MONGOURL=mongodb://aaaaaa npm run-script start curl -k -X POST http://127.0.0.1:8081/addDummy --header "dummy:valueLocal" }}} == Install from source node 10.16.1 == {{{#!highlight sh cd /tmp wget https://nodejs.org/dist/v10.16.1/node-v10.16.1.tar.gz ./configure make clean make make install }}} == Usage of encodeURIComponent and decodeURIComponent == {{{#!highlight sh $node Welcome to Node.js v12.20.0. Type ".help" for more information. > encodeURIComponent("aa:%bb") 'aa%3A%25bb' > decodeURIComponent("aa%3A%25bb") 'aa:%bb' > .exit }}} == Install Node 12 on raspberry pi/Raspbian == {{{#!highlight sh curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - sudo apt install nodejs npm node -v npm -v }}}