I won’t go into the installation process. If successful, you can use the node command. Debugging node.js is very convenient. Each backend language has a pragmatic command that outputs to that dark console group. node.js follows the FF set of things, that is, the console object and its methods. We first create an example.js file with the following content, and then open it in the console.
console.log("hello node.js")
for(var i in console){
console.log(i " " console[i])
}
node example.js.
You must not use alert for debugging in node.js. It is a global method provided by the browser. It would be strange if it does not report an error.
The output result is as follows:
var log = function ( ) {
process.stdout.write(format.apply(this, arguments) 'n');
}
var info = function () {
process.stdout.write(format.apply (this, arguments) 'n');
}
var warn = function () {
writeError(format.apply(this, arguments) 'n');
}
var error = function () {
writeError(format.apply(this, arguments) 'n');
}
var dir = function (object) {
var util = require('util' );
process.stdout.write(util.inspect(object) 'n');
}
var time = function (label) {
times[label] = Date.now() ;
}
var timeEnd = function (label) {
var duration = Date.now() - times[label];
exports.log('undefined: NaNms', label, duration) ;
}
var trace = function (label) {
// TODO probably can to do this better with V8's debug object once that is
// exposed.
var err = new Error ;
err.name = 'Trace';
err.message = label || '';
Error.captureStackTrace(err, arguments.callee);
console.error(err.stack) ;
}
var assert = function (expression) {
if (!expression) {
var arr = Array.prototype.slice.call(arguments, 1);
require(' assert').ok(false, format.apply(this, arr));
}
}
Through these functions, we roughly understand that node.js is in the global scope What has been added, such as require and process. But it cannot be said arbitrarily, because they may be private objects of a certain scope. However, understanding these global objects and starting from these objects to understand other objects is very helpful for us to understand the ecological structure of node.js. On the front end, whenever the browser is upgraded, I will traverse the window object and its element nodes to see what methods and attributes it has added, and then check the documentation. It is impossible for those change logs to tell you all the details. You must go through it yourself, so that you know more than others. Okay, let's find the global object of node.js.
The documentation of node.js tells us that there are the following global objects:
global, process, require,__filename,__dirname, module
But why can we use console.log directly? Experience tells us that console must be a member of a global object, just as we can alert or window.alert. Okay, let’s traverse the name global to get a very domineering object
for(var i in global){
console.log("var " i " = " global[i])
}
The result is as follows:
var global = [object global]
var process = [object EventEmitter ]
var GLOBAL = [object global]
var root = [object global]
var Buffer = function Buffer(subject, encoding, offset) {
//Too long, omit
}
var setTimeout = function () {
var t = NativeModule.require('timers');
return t.setTimeout.apply(this, arguments);
}
var setInterval = function () {
var t = NativeModule.require('timers');
return t.setInterval.apply(this, arguments);
}
var clearTimeout = function () {
var t = NativeModule.require('timers');
return t.clearTimeout.apply(this, arguments);
}
var clearInterval = function () {
var t = NativeModule .require('timers');
return t.clearInterval.apply(this, arguments);
}
var console = [object Object]
It is found that global, like the browser window, has a member with the same name pointing to itself. window === window.window, global === global.global. However, node.js was not designed well in the early days and created another redundant GLOBAL member.
console.log(global === global.global)//true
console.log(global === global.GLOBAL)//true
We then traverse the module object:
for(var i in module){
console.log("var " i " = " module[i])
}
The result is as follows:
var id = .
var exports = [object Object]
var parent = null
var filename = /home/cheng19840218/node/example. js
var loaded = false
var exited = false
var children =
var paths = /home/cheng19840218/node/node_modules,/home/cheng19840218/node_modules,/home/node_modules,/node_modules
var load = function (filename) {
//Too long, omit
}
var _compile = function (content, filename) {
//Too long, omit
}
It turns out that the famous exports are provided here, and __filename is probably a reference to filename. Just go through it and you'll find a lot of interesting things. But don’t think that the secret will be exposed right under your nose. There are still many non-traversable attributes. For example, I traversed the global object above, and only a few members can be counted. We can use the new method of ecma262v5 to check:
console.log(Object.getOwnPropertyNames(global))
The results are as follows:
[ 'clearInterval',
'TypeError',
'decodeURI',
'Buffer',
'parseFloat',
'Number',
'URIError',
'encodeURIComponent',
'RangeError',
'ReferenceError',
'RegExp',
'Array',
'isNaN',
'setTimeout',
'console',
'Date',
' Infinity',
'Boolean',
'Error',
'root',
'NaN',
'String',
'Function',
'Math ',
'undefined',
'encodeURI',
'escape',
'unescape',
'process',
'decodeURIComponent',
'EvalError' ,
'clearTimeout',
'GLOBAL',
'setInterval',
'SyntaxError',
'Object',
'eval',
'global',
'parseInt',
'JSON',
'isFinite' ]
Many people learn node.js and immediately read its documentation. Little do they know that node.js itself depends on The V8 engine has a lot to learn, including the new methods and objects brought by ecma262v5, as well as some syntax that imitates firefox:
__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
set
get
__proto__
However, I don’t recommend using anything starting with "__". The latest browsers like set and get now support it, such as IE9. You can try it under its developer tools. Script below:
var a = {
get latest () {
if (this.log.length > 0) {
return this.log[this.log.length - 1];
}
else {
return null ;
}
},
log: []
}
a.log[0] = "a";
a.log[1] = "b";
console.log(a.latest)
There are basically no compatibility issues in node.js (if you are not playing from the early node.js), and so many native objects have been added Extensions, coupled with the libraries that come with node.js, each module provides a variety of APIs. If that is not enough, there are thousands of plug-ins on github. This is very tempting for JSers who want to try back-end programming. Some people may say, doesn’t the backend involve database operations? This is nothing compared to the front-end DOM compatibility. As for other folder and file operations, just treat them as a special array operation. So you can be aggrieved!
Okay, let’s get down to the real stuff. Node.js is originally an http server. It interacts with the front end, so two objects are indispensable: request and response. Requests and responses are obviously asynchronous, because we don't know when the front-end will send the request, and the response cannot be sent to the front-end immediately. We also have to do logs, read and write databases and other operations. So for javascript, this is best achieved with callback functions. So who will accept this callback? A server object!
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain "});
response.write("Hello node.js");
response.end();
}).listen(8888);
node. js has a special require, which is used to synchronously load objects from other modules, which is similar to require and import in other languages. It's good if it can be synchronized, unlike the front-end, which is layer-by-layer. Then use a function to instantiate a server object, and then listen to port 8888. This is the original example on the node.js official website, and everyone wrote it badly. But such a program is useless in reality. When we enter the URL in the address bar, you must at least return a complete page to me!
For this, we need to modularize first. Modularization is based on files. Rename example.js to server.js, and then change the content inside to a module. For a node.js file, the content inside it is actually executed in a closed environment. If you want to share it with other modules, it must be bound to the exports object.
var http = require("http");
exports.start = function(){
http.createServer(function(request, response) {
console.log("Request received...");
response.writeHead(200, {" Content-Type": "text/plain"});
response.write("Hello node.js");
response.end();
}).listen(8888);
console.log("server start...");
}
Then we build another index.js as the entrance (index.js and server.js are placed in the same directory) .
var server = require("./server");
server.start();
Then create an index.html page.
index
< h2>This is the homepage
Now when we want to request it, read the content of this page Come out and return it to the user. At this time we will use the fs module method.
var http = require("http");
var fs = require('fs');
exports.start = function(){
http.createServer(function(request, response) {
fs.readFile('./index.html' , 'utf-8',function (err, data) {//Read content
if (err) throw err;
response.writeHead(200, {"Content-Type": "text/html" }); //Note here
response.write(data);
response.end();
});
}).listen(8888);
console.log( "server start...");
}
Okay, now we restart and enter the address again, and we will see a complete page.
But in addition to the HTML structure layer, a page also has javascript and css. Then, we create a folder javascripts in the current directory, and create index.js in it. The content is as follows:
window.onload = function(){
var p = document.createElement("p");
p.innerHTML = "This is added dynamically"
document .body.appendChild(p);
}
Create another styles directory and create index.css in it. The content is as follows:
html,body{
background: #3671A5;
height: 100%
}
Then introduce these two files in index.html:
index
< link type="text/css" rel="stylesheet" href="styles/index.css"/>
This is the homepage
Reopened and found that there was no change. Google said that it needs to process requests for js and css files. There is no way to get the request.url attribute, then determine the suffix name, read the file and set the header for it.
var http = require("http");
var fs = require('fs');
var url = require('url');
exports.start = function(){
http.createServer(function(request, response) {
var pathname = url.parse(request.url).pathname;
var ext = pathname.match(/(.[^.] |)$/)[0];//Get the suffix name
switch(ext){
case ".css":
case ".js":
fs.readFile("." request.url, 'utf-8',function (err, data) { //Read content
if (err) throw err;
response.writeHead(200, {
"Content-Type": {
".css":"text/css",
".js":"application/javascript",
}[ext]
});
response.write(data);
response.end();
}) ;
break;
default:
fs.readFile('./index.html', 'utf-8',function (err, data) {//Read content
if (err ) throw err;
response.writeHead(200, {
"Content-Type": "text/html"
});
response.write(data);
response.end ();
});
}
}).listen(8888);
console.log("server start...");
}
At this point, the purpose of this article has been achieved. Three node.js files, an ordinary js file, a css file, and an html file. The next purpose is multiple pages. A website is composed of multiple purposes. It includes the following content, which can handle ajax requests, upload files, Session and Cookie support, logs, MIME recognition, routing dispatch, caching system... There are so many things to do, so some people start the framework as soon as they come up, and It’s like learning JS and using jQuery before you’re even familiar with the API. What a shame! Looking back at the middle part of our server.js above, we actually need to separate MIME and routing. But the most important thing is, how to deal with this infinite function nesting? I think this is no different from my module loading system, so I'll start here next time.