JavaScript已经成为了一种全栈开发语言,NodeJS的出现让JavaScript覆盖了从前端,到后端的开发。尤其在物联网逐渐升温之际,让NodeJS具有更加广阔的应用前景。是任何开发人员不能忽视的一支技术力量。就从现在开始你的NodeJS开发旅程吧。
NodeJS发展历史
2009年,NodeJS创建
2011年,NPM 创建
2014年,NodeJS分支io.js
2015年,NodeJS和io.js共同加入NodeJS基金会
NodeJS基金会成员有:IBM,微软,PayPal,Groupon,Joyent
2015年9月 NodeJS和io.js合并发布为Node.js4.0(支持ES6)
当前稳定版本为10.14.2
写一个Hello world
到网站https://nodejs.org/en/ 下载安装
打开命令行输入
node -v
测试是否安装成功。
用任意的编辑器编写代码
console.log("Hello world");
保存为global.js(文件名称任意)
在命令行运行
node global //运行的时候可以带.js后缀,也可以不带.js后缀
这里console是存在于全局变量global中
console.log("Hello world");
使用require引入模块,
var path = require("path");
console.log(`Hello world from ${path.basename(__filename)}`);
上面的代码打印文件名称。
全局对象
可以到官方网站查看所有全局对象
全局对象意味着在所有的Node应用程序中都可以使用的对象,而不需要require进来。比如上面使用的console。
使用process
process也是一个全局对象
1.使用process获取输入参数
console.log(process.argv);
2. 使用process处理输入和输出
var questions = [
"What is your name?",
"What is your fav hobby?",
"What is your preferred programming language?"
];
var answers = [];
function ask(i) {
process.stdout.write(`\n\n\n\n ${questions[i]}`);
process.stdout.write(" > ");
}
process.stdin.on('data', function(data) {
answers.push(data.toString().trim());
if (answers.length < questions.length) {
ask(answers.length);
} else {
process.exit();
}
});
process.on('exit', function() {
process.stdout.write("\n\n\n\n");
process.stdout.write(`Go ${answers[1]} ${answers[0]} you can finish writing ${answers[2]} later`);
process.stdout.write("\n\n\n\n");
});
ask(0);
使用timer
和浏览器中一样,使用setTimeout,setInterval,clearInterval
使用核心模块(core modules)
var path = require('path');
var util = require('util');
var v8 = require('v8');
util.log( path.basename(__filename) );
var dirUploads = path.join(__dirname, 'www', 'files', 'uploads');
util.log(dirUploads);
util.log(v8.getHeapStatistics());
这里使用了模块path,util,v8
使用事件发生器(event emitter)
或者像下面这样写
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Person = function(name) {
this.name = name;
};
util.inherits(Person, EventEmitter);
var ben = new Person("Ben Franklin");
ben.on('speak', function(said) {
console.log(`${this.name}: ${said}`);
});
ben.emit('speak', "You may delay, but time will not.");
这里使用util模块,让Person继承EventEmitter,从而能够自定义事件,和发出事件。
定制自己的模块(module)
更改上面的示例,新建文件夹lib,并在lib文件夹下创建文件Person.js,内容如下
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Person = function(name) {
this.name = name;
};
util.inherits(Person, EventEmitter);
module.exports = Person;
修改BenFranklin.js文件内容如下
var Person = require("./lib/Person");
var ben = new Person("Ben Franklin");
var george = new Person("George Washington");
george.on('speak', function(said) {
console.log(`${this.name} -> ${said}`);
});
ben.on('speak', function(said) {
console.log(`${this.name}: ${said}`);
});
ben.emit('speak', "You may delay, but time will not.");
george.emit('speak', "It is far better to be alone, than to be in bad company.");
我们把Person抽象出来作为一个通用模块,并在后面引入使用该模块,从而达到模块化和重用的目的。
使用exec
使用exec执行git版本查看命令
操作文件
1.异步读取文件夹中的文件
var fs = require("fs");
fs.readdir('./lib', function(err, files) {
if (err) {
throw err;
}
console.log(files);
});
console.log("Reading Files...");
2.读取文件内容
3.写入文件
var fs = require("fs");
var md = `
Sample Markdown Title
=====================
Sample subtitle
----------------
* point
* point
* point
`;
fs.writeFile("sample.md", md.trim(), function(err) {
console.log("File Created");
});
4.创建文件夹
var fs = require("fs");
if (fs.existsSync("lib")) {
console.log("Directory already there");
} else {
fs.mkdir("lib", function(err) {
if (err) {
console.log(err);
} else {
console.log("Directory Created");
}
});
}
5.使用文件流
var fs = require("fs");
var stream = fs.createReadStream("./chat.log", "UTF-8");
var data = "";
//once代表只运行一次
stream.once("data", function() {
console.log("\n\n\n");
console.log("Started Reading File");
console.log("\n\n\n");
});
stream.on("data", function(chunk) {
process.stdout.write(` chunk: ${chunk.length} |`);
data += chunk;
});
stream.on("end", function() {
console.log("\n\n\n");
console.log(`Finished Reading File ${data.length}`);
console.log("\n\n\n");
});
使用http/https请求
请求wiki并下载网页保存到文件。
var https = require("https");
var fs = require("fs");
var options = {
hostname: "en.wikipedia.org",
port: 443,
path: "/wiki/George_Washington",
method: "GET"
};
var req = https.request(options, function(res) {
var responseBody = "";
console.log("Response from server started.");
console.log(`Server Status: ${res.statusCode} `);
console.log("Response Headers: %j", res.headers);
res.setEncoding("UTF-8");
res.once("data", function(chunk) {
console.log(chunk);
});
res.on("data", function(chunk) {
console.log(`--chunk-- ${chunk.length}`);
responseBody += chunk;
});
res.on("end", function() {
fs.writeFile("george-washington.html", responseBody, function(err) {
if (err) {
throw err;
}
console.log("File Downloaded");
});
});
});
req.on("error", function(err) {
console.log(`problem with request: ${err.message}`);
});
req.end();
创建web服务器
1,创建一个简单的web服务器
var http = require("http");
var server = http.createServer(function(req, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(`
<!DOCTYPE html>
<html>
<head>
<title>HTML Response</title>
</head>
<body>
<h1>Serving HTML Text</h1>
<p>${req.url}</p>
<p>${req.method}</p>
</body>
</html>
`);
});
server.listen(3000);
console.log("Server listening on port 3000");
2.WEB文件服务器
在web服务器中使用文件夹public中的index.html文件作为请求的返回,index.html中会引用css文件和图片文件,分别作了处理。
var http = require("http");
var fs = require("fs");
var path = require("path");
http.createServer(function(req, res) {
console.log(`${req.method} request for ${req.url}`);
if (req.url === "/") {
fs.readFile("./public/index.html", "UTF-8", function(err, html) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(html);
});
} else if (req.url.match(/.css$/)) {
var cssPath = path.join(__dirname, 'public', req.url);
var fileStream = fs.createReadStream(cssPath, "UTF-8");
res.writeHead(200, {"Content-Type": "text/css"});
fileStream.pipe(res);
} else if (req.url.match(/.jpg$/)) {
var imgPath = path.join(__dirname, 'public', req.url);
//不传入编码代表是用二进制的方式读取
var imgStream = fs.createReadStream(imgPath);
res.writeHead(200, {"Content-Type": "image/jpeg"});
imgStream.pipe(res);
} else {
res.writeHead(404, {"Content-Type": "text/plain"});
res.end("404 File Not Found");
}
}).listen(3000);
console.log("File server running on port 3000");
总结,我们学习了NodeJS的内置对象,常用模块,文件处理,HTTP请求,以及怎么创建WEB服务器。有了这些基本概念,可以继续深入NodeJS相关的各种工具和生态链。
