blog icon indicating copy to clipboard operation
blog copied to clipboard

Node

Open WangShuXian6 opened this issue 6 years ago • 13 comments

node

Install Node.js on Ubuntu 16.04


sudo apt-get update
cd ~
curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt-get install nodejs
sudo apt-get install npm
nodejs -v

centos

curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash -
sudo yum install nodejs

node --version
npm --version

npm 短语 test start stop 不需要加run npm test npm start npm stop

npm run xxxx

npm 前置钩子,后置钩子 'pretest':'echo 111', 'posttest':'echo 222', 'test':'echo 333'

传递参数 --xxxx

配置变量 'config':{ 'xxx':'xxxx' }

使用 linux,mac $npm_package_config_xxx

windows %npm_package_config_xxx

文件操作推荐使用包,防止跨系统区别


npm全称Node Package Manager


Node.js概述:

Node.js官网:www.nodejs.org 1.Node.js是C++编写的基于V8引擎的JS运行时环境。 2.Node.js是一门基于ECMAScript开发的服务器端语言,提供了(全端JS没有的)很多扩展对象。

前端js:

1.ES原生对象:String、Number、Boolean、Math、Date、Error、Function、Object、Array、RegExp... 2.BOM&DOM 3.自定义对象

Node.js:

1.ES原生对象 2.Node.js内置对象 3.大量的第三方对象 4.自定义对象

3.Node.js可以编写独立的服务器应用,无需借助于其他web服务器。
Node.js的意义:

1.执行效率比PHP/JSP/JAVA要快 2.用一种语言统一了前后端开发。

特点: 1.单线程逻辑处理 2.非阻塞 3.异步I/O处理 4.事件驱动编程

2.Node.js的两种运行方式:

1.交互模式——用于测试 读取用户输入、执行运算、输出执行结果、继续下一循环 执行方法:输入一行js语句,回车执行

2.脚本模式——用于开发 把要执行的所有js语句编写在一个独立的js文件中,一次性的提交给nodejs处理。此文件可以没有后缀 执行方法:node d:\xx\xx.js

3.Node.js的基础语法及ES6新特性

1.数据类型: (1)原始类型 string、number、boolean... 原始类型数据直接赋值即可

(2)引用类型 ES原生对象、Node.js对象、自定义对象 引用类型通常需要使用new关键字创建

2.模板字符串 ES6中提供的一种新的字符串形式 (1)使用模板方式定义字符串,数据可以实现换行 (2)可以使用${}拼接变量,并且可以执行运算

3.严格模式 ES5中新增一种比普通模式更为严格的js运行模式。

使用方法: (1)在整个脚本文件中启用严格模式 在脚本文件的开头:"use strict"; 用于新项目 (2)在单个函数内启用严格模式

		function info(){
			"use strict";
			.........
		}

用于老项目维护

规则: -(1)修改常量的值是非法的——将静默失败升级为错误 -(2)不允许对未声明的变量赋值 -(3)匿名函数的this不再指向全局

4.变量的作用域 全局作用域、局部作用域、块级作用域(ES6中专有) 块级作用域:只在当前代码块中使用 代码块:任何一个{}都是一个代码块,if/for/while... 代码块中使用“let”声明块级作用域变量,出了代码块,便不可使用。使用let需要启用严格模式。

5.循环结构 for...of...(ES6) 遍历数组的元素值

6.函数 匿名函数的自调 => 箭头函数

		() => {
	
		}

箭头函数只用于匿名函数 箭头函数中不存在arguments对象

7.对象 创建对象的方式: -(1)对象直接量 -(2)构造函数方式 -(3)原型继承方式 -(4)class方式——ES新增

class 类:是一组相似对象的属性和行为的抽象集合。(描述一类事物统一的属性和功能的程序结构) 事物的属性就是class的属性,事物的功能就是class的方法。 使用class方式创建自定义对象是,必须启用严格模式。

		"use strict";
		//创建自定义对象
		class Emp {
  			constructor(ename){   
				this.ename=ename; 
  			}
  			work(){    
 			 }
		}
		var e1=new Emp("tom");

		// 实现继承:
		class Programmer extends Emp{
  			constructor(ename,salary,skills){
    				super(ename,salary);
    				this.skills=skills;
  			}  
		}
4.全局对象

Node.js中的全局对象是Global. 在交互模式下,声明的全局变量是global的成员。——全局对象的污染 在脚本模式下,声明的全局变量不是global的成员。——避免了全局对象的污染 Global对象的成员属性和成员方法

1.console 用于向stdout(标准输出)和stderr(标准错误)输出信息。

console.log() //向stdout输出日志信息 console.info() //同上 console.error() //向stderr输出错误信息 console.warn() //同上 console.trace() //向stderr输出栈轨迹信息 console.dir() //向stdout输出指定对象的字符串表示 console.assert() //断言,为真的断言,错误信息不会输出;为假的断言,抛出错误对象,输出错误信息,并且终止脚本的运行,可以自定义错误信息。 console.time() console.timeEnd()//测试代码的执时间

注意:console中的成员方法是异步的,输出顺序和书写顺序不一定完全一致。

2.process 进程 process.arch //获取CPU架构类型 process.platform //获取操作系统类型 process.env //获取操作系统环境变量 process.cwd() //获取当前文件所在工作目录 process.execPath //获取Node.js解释器所在目录 process.versions //获取Node.js版本信息 process.uptime() //获取Node.js进程运行时间(s) process.memoryUsage()//获取Node.js进程内存使用信息 process.pid //获取进程ID号 process.kill( pid ) //向指定进程ID号发送退出信号

3.定时器 global.setTimeout() //一次性定时器 global.setInterval() //周期性定时器 global.setImmediate()//在下次事件循环开始之前立即执行的定时器 process.nextTick() //本次事件循环结束之后立即执行的定时器

5.模块系统:

Node.js中使用“Module(模块)”来规划不同的功能对象。 模块的分类: -(1)核心模块——Node.js的内置模块(有些不需引入可直接使用,有些需要引入) -(2)第三方模块 -(3)自定义模块 每一个被加载的js文件对应一个模块对象,包含响应的功能和函数。 模块中声明的变量或函数的作用域叫做“模块作用域”,这些变量和函数都不是global的成员,默认只能在当前的js文件(当前模块)中使用。

Node.js启动时运行的第一个模块叫做“主模块”——main module,也是自身模块。 获取主模块对象: process.mainModule require.main

除主模块之外的其他模块都称为子模块。 默认情况下,某一个模块不能直接使用其他模块中封装的数据,但是每个模块可以导出(exports)自己内部的对象供其他模块使用,也可用引入(require)并使用其他模块导出的对象。

每一个模块内部都可以使用一个变量:module,指向当前模块自己。

	//判断当前模块是否主模块
	console.log(require.main===module);

模块的引入:require() (在交互模式下,Node.js自带的模块无需引入,直接使用)


WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

Node.js核心模块

1.console

global.console 用于向stdout和stderr输出日志信息 Console class console模块中的Console构造函数,用于向任意指定的输出流(文件)中输入信息。

2.Query String模块

提供了处理URL中“查询字符串”部分的相关操作 parse() //从查询字符串中解析出数据对象,参数为一个查询字符串 stringify() //将一个数据对象反向解析为一个查询字符串格式, 参数1,为一个数据对象; 可选参数2,指定键值对之间的分隔符; 可选参数3,指定键和值之间的分隔符。

3.URL模块

提供了处理url中不同部分的相关操作 parse() //解析出url的各个组成部分,参数1,要解析的url字符串; 可选参数2,若为true,可以将查询字符串部分解析为对象

format() //将对象反向格式化为url格式,参数为一个对象 resolve() //根据基地址和相对地址解析出目标地址,参数1,基地址;参数2,相对地址

4.Path模块

提供了对文件路径进行操作的相关方法 parse() //解析一个路径,参数为路径字符串 format() //将路径对象格式化为路径字符串,参数为对象 join() //用于连接路径,会正确使用当前系统的路径分隔符 resolve() //根据基础路径,解析出目标路径的绝对路径 relative() //根据基础路径,获取目标路径与其的相对关系

5.DNS模块

提供了域名和IP地址的双向解析功能。 lookup() //把一个域名解析成一个IP地址,从操作系统中查询(缓存) resolve() //把一个域名解析为一个DNS的记录解析数组,从DNS服务器中查询 reverse() //把一个IP地址反向解析为一组域名

6.Util 工具模块

format() //使用带占位符的方式格式化字符串 inspect() //返回一个对象的字符串表示 inherits() //实现构造方法之间的继承

7.Buffer

缓冲区,一块专用于存储数据的内存区域,与string类型相对应,用于存储二进制数据。 Buffer对象的实例,可以通过读取文件获得,也可以手动创 建。 Buffer是Global对象的成员,无需require引入。

8.fs模块——文件系统模块

fs模块提供了文件的读写、更名、删除、遍历目录等操作。 fs模块中大多数方法都带有同步和异步两种 所有的异步方法都有一个回调函数,此回调函数的第一个参数都是一个错误对象。 异步方法中如果有错误的话,会静默失败,不会自己抛出error,通常情况下都需要手动处理。

常用Class: fs.Stats //文件或目录的统计信息描述对象 fs.ReadStream //stream.Readable接口的实现对象 fs.WriteStream //streamWriteable接口的实现对象 fs.FSWatcher //可用于监视文件修改的文件监视器对象

常用的方法: fs.stat() //用于返回一个文件或目录的统计信息对象(fs.Stats对象) fs.mkdir() //创建目录 fs.rmdir() //删除目录 fs.readdir()//读取目录下的内容 fs.readFile() //读取文件内容 fs.writeFile() //向文件中写入内容 fs.appendFile() //向文件末尾追加内容 fs.unlink() //删除文件 fs.rename //重命名文件

fs.stat() & fs.statSync() //用于返回一个文件或目录的统计信息对象(fs.Stats对象) fs.Stats对象的方法: stats.isFile() //是否为文件 stats.isDirectory() //是否为目录

操作目录: fs.mkdir() & fs.mkdirSync() //创建目录 fs.rmdir() & fs.rmdirSync() //删除目录 fs.readdir()& fs.readdirSync() //读取目录下的内容

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

fs模块——文件系统模块

fs模块提供了文件的读写、更名、删除、遍历目录等操作。 fs模块中大多数方法都带有同步和异步两种 所有的异步方法都有一个回调函数,此回调函数的第一个参数都是一个错误对象。 异步方法中如果有错误的话,会静默失败,不会自己抛出error,通常情况下都需要手动处理。 常用Class: fs.Stats //文件或目录的统计信息描述对象 fs.ReadStream //stream.Readable接口的实现对象 fs.WriteStream //streamWriteable接口的实现对象 fs.FSWatcher //可用于监视文件修改的文件监视器对象

常用的方法: fs.stat() //用于返回一个文件或目录的统计信息对象(fs.Stats对象) fs.mkdir() //创建目录 fs.rmdir() //删除目录 fs.readdir()//读取目录下的内容 fs.readFile() //读取文件内容 fs.writeFile() //向文件中写入内容 fs.appendFile() //向文件末尾追加内容 fs.unlink() //删除文件 fs.rename //重命名文件

fs.stat() & fs.statSync() //用于返回一个文件或目录的统计信息对象(fs.Stats对象) fs.Stats对象的方法: stats.isFile() //是否为文件 stats.isDirectory() //是否为目录

操作目录: fs.mkdir() & fs.mkdirSync() //创建目录 fs.rmdir() & fs.rmdirSync() //删除目录 fs.readdir()& fs.readdirSync() //读取目录下的内容

操作文件: fs.readFile() & fs.readFileSync //读取文件内容 fs.writeFile() & fs.writeFileSync //向文件中写入内容 当使用writeFile()方法向文件写入内容是,若文件不存在,会自动创建指定文件;如果存在,则会替换原本的内容 fs.appendFile() & fs.appendFileSync //向文件末尾追加内容 当使用appendFile()方法向文件写入内容是,若文件不存在,会自动创建指定文件;如果存在,会在文件末尾追加内容 fs.unlink() & fs.unlinkSync() //删除文件 fs.rename & fs.renameSync() //重命名文件

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

HTTP模块

用于构建使用HTTP协议的客户端应用或服务器端应用 创建并发起请求消息,等待并解析响应消息——实现web客户端 接收并解析请求消息,构建并发送响应消息——实现web服务器

常用对象:

	http.ClientRequest
	http.Server
	http.ServerResponse
	http.IncomingMessage

常用方法:

	http.createServer
	http.get()
	http.request()

1.http.request

http.request是一个HTTP客户端工具 用于向web服务器发起一个http请求,并获取响应数据 有两个主要方法:

	http.get()
	http.request()

该方法返回一个http.ClientRequest对象,用来描述请求信息,回调函数的参数是一个http.IncomingMessage,封装着响应信息。

http.ClientRequest对象常用方法:

	write():向服务器追加请求主体数据
	end():提交请求消息主体结束
	setTimeout():设置请求消息超时时间
	abort():终止请求

http.ClientRequest对象常用事件:

	response:接收到响应消息
	abort:请求终止事件
	error:请求发生错误

注意:使用get()方法不需要手动调用end()方法,使用request()的时候,必须手动调用end()方法。

2.http.server

http.server是一个基于事件的http服务器。 用于创建web服务器,接收客户端请求,返回响应消息。所有的请求都被封装到独立的事件当中,我们只需对它的事件编写响应的处理程序,就可用实现http服务器的所有功能。

方法:http.createServer()

用于创建web服务器应用,可以接收客户端请求,并返回响应消息。 该方法的返回值是一个http.Server对象

http.Server对象的常用方法:

	listen():启动服务器,监听指定的服务端口
	close():停止服务器的运行
	setTimeout():设置服务器的响应消息超时时间

http.Server对象的常用事件:

	connection:出现客户端连接
	request:接收到请求消息
	close:服务器停止事件
	error:响应发生错误

http.Server对象的request事件回调函数中有两个参数

	第一个参数,是一个http.IncomingMessage对象,封装着客户端提交的请求消息数据。
	第二个参数:是一个http.ServerResponse对象,用于构建向客户端输出的响应消息数据。

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

MySQL模块

方法:

createConnection() //创建一个mysql服务器的连接 该方法返回一个连接对象,该对象有以下常用方法:

	connect()	//连接数据库
	query()	//提交SQL语句给MySQL服务器执行
	end()	//断开与MySQL服务器的连接

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

express模块

可以方便的实现服务器的路由、发送和接收http请求,返回响应、发送和接收cookie以及实现模板引擎功能。

app.method(path,[middleware,]function(req,res){})

中间件

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

Node.js的基础语法

type.js

//原始类型
var price=9.9;
var name="可口可乐";
var isOnsale=false;
var exDate=null;
var area=undefined;
//引用类型
var empName=new String('Tom');
var age=new Number(20);
var age=new Buffer(10);
var myObj=new Object();
function Myobj(name,age){
this.name=name;
this.age=age;
}
var han=new Myobj('hanxl',20);
console.log(han.name);
console.log(han.age);

template.js

//模板字符串
var info=`
用户名:唐牧
密码:123
`;
console.log(info);
var price=9.9,count=3;
var info2=`
单价:${price},
数量:${count},
小计:${price*count},
超过预算:${price*count>20?'是':'否'}
`;
console.log(info2);

strict.js

//"use strict";
const PI=3.14;
//PI=2;
console.log(PI);




function f1(){
//"use strict"
var name="tecu.cn";
loc="北京市";
console.log(name);
console.log(loc);
}
f1();

(function(){
'use strict';
console.log(this);
})();

let.js

"use strict";
/*var count=20;
if(count>10){
//var cur=count;
let cur=count;
}
console.log(cur);*/

for(let i=0;i<5;i++){}
console.log(i);

for-of.js

//for...in....遍历对象的成员名
var obj={
name:"tom",
age:20
};
for(var i in obj){
console.log(i+':'+obj[i]);
}
//for...in...遍历数组的下标
var arr=[10,20,30];
for(var i in arr){
console.log(i);
}
//for...of...遍历数组的元素值
for(var i of arr){
console.log(i);
}

global.js

var age=20;
console.log(age);
//console.log(global.age);


//process.kill(pid)向指定进程id发送退出信号
process.kill(3456);

window.html

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
var age=20;
console.log(age);
console.log(window.age);
</script>
</body>
</html>

箭头函数 =>

/*
(function(i){
console.log(i)
})(111);
+function(){
console.log(222);
}();
(function(num){
if(num>0){
arguments.callee(num-1);
console.log(num);
}
})(5);
*/
//箭头函数 =>
(() => {
    console.log(111)
})();


((n1, n2) => {
    console.log(n1 + n2);
})(10, 20)


var f1 = (n1, n2) => {
    console.log(n1 + n2);
};

f1(1, 2)


    /*((num)=>{
    if(num>0){
    arguments.callee(num-1);
    console.log(num);
    }
    })(5); 错误!*/

闭包 closure.js

//一个简单的一次性定时器
var i = 1;
setTimeout(() => {
    console.log(i)
}, 1000)
//一秒之后,输出0,1,2

for (var i = 0; i < 3; i++) {
    setTimeout(outer(i), 1000)
}

function outer(num) {
    return function inner() {
        console.log(num)
    }
}

//改写为箭头函数
for (var i = 0; i < 3; i++) {
    setTimeout((num => {
        return () => { console.log(num) }
    })(i), 1000)
}

创建自定义对象class

"use strict";

//创建自定义对象
class Emp {
    constructor(ename, salary) {//声明一个构造函数
        this.ename = ename
        this.salary = salary
    }
    work() {
        return `${this.ename} is working.`
    }
    sal() {
        return `${this.ename}'s salary is ${this.salary}.`
    }
}

var e1 = new Emp("tom", 8000)
console.log(e1.ename)
console.log(e1.work())
console.log(e1.sal())

var e2 = new Emp("Mary", 9000)
console.log(e2.ename)


//实现继承
class Programmer extends Emp {
    constructor(ename, salary, skills) {
        super(ename, salary)
        this.skills = skills
    }
    work() {
        return super.work() + 'skills are' + this.skills
    }
}

var p1 = new Programmer("Jack", 8800, "PHP&MYSQL")
console.log(p1.ename)
console.log(p1.work())

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

console

//console.log
console.log("msg1")
console.log("msg1", "msg2", 123, true, new Date())

var user = { name: "tom", age: 20 }
console.log(`姓名:${user.name},年龄:${user.age}`)
//百分号占位符,每一个占位符一一对应后面的参数值,%s表示string类型,%d表示number类型
console.log('姓名:%s,年龄:%d', user.name, user.age)
//console.error
console.error(`姓名:${user.name},年龄:${user.age}`)

//console.trace
function outer() {
    function inner() {
        console.trace("stack trace")
    }
    inner()
}
outer()

//console.dir
console.dir(user)
var arr = [20, 30, "tom"]
console.dir(arr)
//console.log和console.dir的区别,dir()可以带一些参数
console.log(Buffer)
console.dir(Buffer, { colors: true })

//console.assert
function add(n1, n2) {
    return n1 + n2
}
var sum = 20;
console.assert(add(10, 20) == sum, "add函数执行结果不符合要求")


//console.time() console.timeEnd()
console.time("mycode") //开始计时
var sum = 0
for (var i = 0; i < 1000000; i++) {
    sum += i
}
console.timeEnd("mycode") //结束计时


定时器

//一个简单的一次性定时器
var counter = 0
var timer = setTimeout(function () {
    counter++
    console.log('%d hello', counter);
    clearTimeout(timer)
}, 1000)
//周期性定时器,输出1,2,3,4,5
var counter2 = 0
var timer2 = setInterval(function () {
    counter2++
    console.log(counter2)
    if (counter2 >= 5) {
        clearInterval(timer2)
    }
}, 1000)
//练习:使用一次性定时器模拟上面周期性定时器的效果,输出1,2,3,4,5
var counter3 = 0
var timer3 = setTimeout(function () {
    counter3++
    if (counter3 <= 5) {
        console.log(counter3)
        setTimeout(arguments.callee, 1000)
    } else {
        clearTimeout(timer3)
    }
}, 1000)
//setImmediate() process.nextTick
setImmediate(function () {
    console.log("setImmediate1...")
})
process.nextTick(function () {
    console.log("nextTick1...")
})
setTimeout(function () {
    console.log("setTimeout...")
}, 100)
setImmediate(function () {
    console.log("setImmediate2...")
})
process.nextTick(function () {
    console.log("nextTick2...")
})
console.log("end...")

模块module

//获取主模块对象
console.log(process.mainModule)
console.log(require.main)
//获取当前模块自己
console.log(module)
//判断当前模块是否主模块
console.log(require.main === module)


//引入其他模块
var fs = require("fs");//引入文件系统模块
fs.readFile('./10-window.html', (err, data) => {
    if (err) {
        console.log("文件读取失败")
        console.log(err)
    } else {
        console.log("文件读取成功")
        console.log(data)
    }
});

02.js

var c=require('./02-circle.js');
console.log(c.s(5));
console.log(c.p(5).toFixed(2));

02-circle.js

//求圆的面积和周长
const PI = 3.14
var size = function (r) {
    return PI * r * r
}
var perimeter = function (r) {
    return 2 * PI * r
};
exports.s = size
exports.p = perimeter

03.js

var c=require("./03-circle.js");
var circle=new c(5);
console.log(circle.size());
console.log(circle.perimeter());

03-circle.js

//求圆的面积和周长
const PI = 3.14
function Circle(r) {
    this.size = function () {
        return PI * r * r
    };
    this.perimeter = function () {
        return 2 * PI * r
    };
}
module.exports = Circle

04.js

var m1 = require('./04-m1')
console.log(m1.data)
var m2 = require('./04-m2.js')
console.log(m2.data)
var m3 = require('./04-m3.json')
console.log(m3.data)
//引入目录模块
var m4 = require("./04-m4")
console.log(m4.data)
var m5 = require("./04-m5")
console.log(m5.data)
var m6 = require("04-m6")
console.log(m6.data)

04-m1.js

exports.data="m1";

04-m2.js

exports.data="m2";

04-m3.json

{
    "data": "m3"
}

hello.js

exports.data="m4";

package.json

{
    "main": "hello.js"
}

index.js

exports.data="m5";

index.json

{
    "data": "m6"
}

\node_modules\mypackage\index.js

var p=require("./lib/const.js");
exports.size=function(r){
return p.PI*r*r;
};

\node_modules\mypackage\lib\const.js

exports.PI=3.14;

\node_modules\mypackage\package.json

{
    "name": "mypackage",
    "main": "index.js",
    "description": "This is mypackage.",
    "version": "1.0.0",
    "keywords": [
        "circle",
        "hanxl"
    ],
    "maintainers": [
        {
            "name": "hanxl",
            "email": "[email protected]"
        }
    ]
}

NPM

\index.js

var p=require("./lib/const.js");
exports.size=function(r){
return p.PI*r*r;
};

\node_modules\unit_0119\lib\const.js

exports.PI=3.14;

\node_modules\unit_0119\package.json

{
    "name": "unit_0119",
    "version": "2.0.0",
    "description": "unit_0119",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [
        "circle"
    ],
    "author": "",
    "license": "ISC"
}

Console

//向任意输出流中执行输入
var fs = require("fs")// 引入fs模块
var out = fs.createWriteStream("./log/out.log")// 创建文件
var err = fs.createWriteStream("./log/err.log")
var c = require("console") // 引入console模块
var loger = new c.Console(out, err) // 实例化Console构造函数
loger.log("log...")
loger.error("err...")

querystring

var qs = require("querystring")
var str = "name=tom&age=20"
console.log(qs.parse(str))
var obj = { name: 'tom', age: '20' }
console.log(qs.stringify(obj))
console.log(qs.stringify(obj, ","))
console.log(qs.stringify(obj, ",", "-"))

url

var url = require("url")
var str = "http://tom:[email protected]:8080/news/index.html?pid=20#section"
console.log(url.parse(str)) // 解析出url的各个组成部分
console.log(url.parse(str, true)) // 第二个参数,把查询字符串部分解析为对象

var obj = {
    protocol: "http:",
    host: "tedu.cn",
    pathname: "course_list/index.html",
    query: { cid: 30 }
};
console.log(url.format(obj))

var url1 = "project/static/base.html"
var url2 = "../img/1.jpg"
console.log(url.resolve(url1, url2))

path

var path = require("path")
var str = "E:/hanxl/nodejs/day02/01-module.js"
console.log(path.parse(str))

var obj = {
    dir: "e:/hanxl/day01",
    base: "01.js"
};
console.log(path.format(obj))
console.log(path.join('d:', 'hanxl', 'nodejs', '01.js'))

var path1 = "e:/htdocs/01/login"
console.log(path.resolve(path1, '../img/2.jpg'))
console.log(path.relative(path1, 'e:/htdocs/img/3.jpg'))




// { root: 'E:/',
//   dir: 'E:/hanxl/nodejs/day02',
//   base: '01-module.js',
//   ext: '.js',
//   name: '01-module' }

// e:/hanxl/day01\01.js
// d:\hanxl\nodejs\01.js
// e:\htdocs\01\img\2.jpg
// ..\..\img\3.jpg

DNS

var dns = require("dns")
//把一个域名解析为一个IP地址,参数1,错误对象;参数2,IP地址;参数3,IPV4 OR IPV6
dns.lookup('www.baidu.com', function (err, address, family) {
    if (err) {
        cosole.log(err)
    } else {
        console.log("lookup():")
        console.log(address)
        console.log(family)
    }
})
//把一个域名解析为一个DNS记录解析数组
dns.resolve('www.baidu.com', function (err, address) {
    if (err) {
        cosole.log(err)
    } else {
        console.log("resolve():")
        console.log(address)
    }
})
//把一个IP地址反向解析为一组域名
dns.reverse('60.221.254.230', function (err, hostnames) {
    if (err) {
        console.log(err)
    } else {
        console.log(hostnames)
    }
})

util

var util = require("util")
var obj = { name: "Cola", price: 3.9, isOnsale: false }
var s1 = util.format('产品名称:%s,价格:%d,是否促销商品:%s,%j', obj.name, obj.price, obj.isOnsale, obj)
console.log(s1)
console.log(util.inspect(obj))

//实现构造方法之间的继承
function Base() {
    this.name = "base"
}
Base.prototype.age = 20
function Sub() {
    this.name = "sub"
}
util.inherits(Sub, Base)
var user = new Sub()
console.log(user.name)
console.log(user.age)

Buffer

// 创建一个长度为32字节的缓冲区
var buf1 = new Buffer(32)
console.log(buf1)

// 创建一个长度为3字节的缓冲区
var buf2 = new Buffer([65, 66, 67]) // 存入十进制
console.log(buf2)
console.log(buf2.toString()) // 将buffer转换为字符串表示

// 创建一个长度为4字节的缓冲区,直接存入英文字符串
var buf3 = new Buffer("ABCD")
console.log(buf3)
console.log(buf3.length)

// 创建一个缓冲器,存入字符串(英文+中文),指定编码方式
var buf4 = new Buffer("AB一二", "utf8")
console.log(buf4) // 一个汉字占3个字节
console.log(buf4.length)

Fs

var fs = require("fs")
var path1 = "./log"
var path2 = "./log/out.log"
var stats1 = fs.statSync(path1)//同步读取目录
//console.log(stats1)
var stats2 = fs.statSync(path2)//同步读取文件
//console.log(stats2)
//异步读取文件或目录
fs.stat(path1, (err, stats) => {
    if (err) {
        console.log("文件或目录读取失败!")
    } else {
        console.log("文件读取成功!")
    }
})
console.log(stats2.isFile())//判断是否为文件
console.log(stats2.isDirectory())//判断是否为目录
var fs = require("fs")
var path = './test'
//读取一个目录,如果此目录不存在,则创建,如果存在,则删除
fs.stat(path, (err, stats) => {
    if (err) {
        fs.mkdir(path)//创建指定目录
    } else {
        fs.rmdir(path)//删除指定目录
    }
})

//判断一个目录是否存在,若存在,读取目录下的内容
var path2 = './node_modules'
fs.stat(path2, (err, stats) => {
    if (err) {
        console.log("当前目录不存在")
    } else {
        fs.readdir(path2, (err, list) => {//读取目录下的内容
            console.log(list)
        })
    }
})
var fs = require("fs")//引入fs模块
//读取文件
fs.readFile('../day02/02.js', (err, data) => {
    if (err) {
        console.log("文件读取失败")
    } else {
        console.log("文件读取成功")
        console.log(data.toString())
    }
})
//写入内容
var file1 = './log/out.log'
var data1 = "out.log test file"
fs.writeFile(file1, data1, (err) => {
    if (err) {
        console.log("文件写入失败")
        console.log(err)
    }
})
//向文件中追加内容
var file2 = './log/out2.log'
var data2 = "This is test2"
fs.appendFile(file2, data2, (err) => {
    if (err) {
        console.log("文件写入失败")
        console.log(err)
    }
})
//删除文件
fs.unlink('./log/test.txt', (err) => {
    if (err) {
        console.log("删除文件失败")
    }
})
//重命名文件
var pathOld = "./log/index.html"
var pathNew = "./log/login.html"
fs.rename(pathOld, pathNew, (err) => {
    if (err) {
        console.log("重命名失败")
    }
})

WangShuXian6 avatar Jun 17 '18 09:06 WangShuXian6

使用get()方法发送请求

//使用get()方法发送请求
var http = require("http")
var options = {
    hostname: "www.tmooc.cn",
    port: "80",
    path: "/web/index_new.html"
}
var req = http.get(options, (res) => {
    console.log("接收到响应消息...")
    //console.log(res)
    console.log(`响应状态码:${res.statusCode}`)
    console.log(`响应头:${JSON.stringify(res.headers)}`)
    res.on("data", (chunk) => {
        console.log(chunk.toString())
    })
})
req.setTimeout(2000, () => {
    req.abort()
    console.log("请求超时,已终止请求。")
})
req.on("error", (err) => {
    console.log(`请求发生错误:${err}`)
})

使用request()方法发送请求

//使用request()方法发送请求
var http = require("http")
var options = {
    hostname: "www.tmooc.cn",
    port: "80",
    path: "/web/index_new.html"
}
var req = http.request(options, (res) => {
    console.log("接收到响应消息...")
    //console.log(res)
    console.log(`响应状态码:${res.statusCode}`)
    console.log(`响应头:${JSON.stringify(res.headers)}`)
    res.on("data", (chunk) => {
        console.log(chunk.toString())
    })
})
req.setTimeout(2000, () => {
    req.abort()
    console.log("请求超时,已终止请求。")
})
req.on("error", (err) => {
    console.log(`请求发生错误:${err}`)
})
req.end()

创建一个简单的web服务器

//创建一个简单的web服务器——没有给客户端响应
//引入http模块
var http = require("http")
//使用http模块,创建web服务器
var server = http.createServer()
//为服务器的request事件绑定处理函数
server.on("request", (req, res) => {
    console.log("web服务器接收到一个请求...")
    console.log(`请求方法:${req.method}`)
    console.log(`请求URL:${req.url}`)
    console.log(`请求版本:${req.httpVersion}`)
    console.log(`请求头:`)
    console.log(req.headers)
})
//启动web服务器,监听指定端口
server.listen(8000, '127.0.0.1', (err) => {
    if (err) {
        console.log("web服务器启动失败,错误消息为:")
        console.log(err)
    } else {
        console.log("web服务器启动成功,正在监听8000端口...")
    }
})

创建web服务器——给客户端一个固定响应

/*创建web服务器——给客户端一个固定响应*/
//引入http模块
var http = require("http")
//创建web服务器
var server = http.createServer()
//为http.Server的request事件绑定处理函数
server.on("request", (req, res) => {
    console.log("接收到一个客户端请求...")
    res.statusCode = 200//设置响应状态码
    res.setHeader("Content-Type", "text/html;charset=UTF-8")//设置响应消息头部
    res.write("<html>")//向客户端输出的响应主体内容
    res.write("<head></head>")
    res.write("<body>")
    res.write("<h1>欢迎访问我的页面</h1>")
    res.write("</body>")
    res.write("</html>")
    res.end()//响应主体内容完毕,向客户端发送响应
})
//启动web服务器,监听指定端口
server.listen(8000, "127.0.0.1", (err) => {
    if (err) {
        console.log("服务器启动失败")
    } else {
        console.log("服务器启动成功,正在监听8000端口")
    }
})

创建一个web服务器——根据客户端请求响应对应的内容

/*创建一个web服务器——根据客户端请求响应对应的内容*/
//引入模块
var http = require("http")
var url = require("url")
var fs = require("fs")
//创建web服务器
var server = http.createServer()
//为server的request事件绑定处理函数
server.on("request", (req, res) => {
    //1.解析出客户端请求的url,req.url
    var urlInfo = url.parse(req.url)
    var path = '.' + urlInfo.pathname
    //2.读取客户端请求的文件内容,fs.readFile()
    fs.readFile(path, (err, data) => {
        if (err) {
            console.log("文件读取失败")
        } else {
            //3.向客户端输出响应内容,res.write()
            res.statusCode = 200
            res.setHeader('Content-Type', 'text/html;charset=UTF-8')
            res.write(data)
            res.end()
        }
    })
})
//启动web服务器,监听指定端口
server.listen(8000, "127.0.0.1", (err) => {
    if (err) {
        console.log("服务器启动失败")
    } else {
        console.log("服务器启动成功,正在监听8000端口...")
    }
})

查询mysql数据库中的数据

/*查询mysql数据库中的数据*/
//引入mysql模块
var mysql = require("mysql")
//连接到mysql服务器
var options = {
    host: "127.0.0.1",
    user: "root",
    password: "",
    database: "user_0120"
}
var conn = mysql.createConnection(options)
conn.connect()//可以省略
//提交SQL语句给mysql服务器执行
var sql = 'SELECT * FROM user'
conn.query(sql, (err, rows) => {
    if (err) {
        console.log("数据查询失败")
    } else {
        console.log("查询完成")
        //console.log(rows)
        for (var i = 0;i<rows.length;i++) {
            console.log(`用户名:${rows[i].uname},密码:${rows[i].upwd}`)
        }
    }
})
//断开与mysql服务器的连接
conn.end()

向mysql数据库中插入数据

/*向mysql数据库中插入数据*/
//引入mysql模块
var mysql = require("mysql")
//创建连接
var options = {
    host: "127.0.0.1",
    user: "root",
    password: "",
    database: "user_0120"
}
var conn = mysql.createConnection(options)
//提交SQL语句
var sql = 'INSERT INTO user VALUES(NULL,"Jack","111")'
conn.query(sql, (err, data) => {
    if (err) {
        console.log("写入数据失败")
    } else {
        console.log("写入数据成功")
        console.log(`SQL语句影响的行数:${data.affectedRows}`)//获得影响的行数
        console.log(`INSERT产生的自增编号:${data.insertId}`)//获得自增主键
    }
})
//断开连接
conn.end()

实现动态web服务器

/*实现动态web服务器*/
//引入相关模块
var http = require("http")
var url = require("url")
var fs = require("fs")
var mysql = require("mysql")
var path = require("path")
//创建web服务器
var server = http.createServer()
//为request事件绑定处理函数
server.on("request", doRequest)
//启动服务器,监听指定端口
server.listen(8001, "127.0.0.1", (err) => {
    if (err) {
        console.log("服务器启动失败")
        console.log(err)
    } else {
        console.log("服务器启动成功,正在监听8001端口")
    }
})
var urlInfo
//处理客户端的http请求
function doRequest(req, res) {
    console.log("请求的url为:" + req.url)
    urlInfo = url.parse(req.url, true)//解析请求的url
    //得到请求的url的文件名后缀
    var urlSuffix = path.parse(urlInfo.pathname).ext
    //console.log(urlSuffix)
    if (urlSuffix == ".do") {//以.do结尾的动态请求
        doDynamic(req, res)//处理动态请求
    } else {//其他结尾的静态请求
        doStatic(req, res)//处理静态请求
    }
}
//处理静态请求,直接读取指定的文件发送给客户端即可
function doStatic(req, res) {
    var path = '.' + urlInfo.pathname
    fs.readFile(path, (err, data) => {
        if (err) {
            console.log("文件读取失败")
        } else {
            //3.向客户端输出响应内容,res.write()
            res.statusCode = 200
            res.setHeader('Content-Type', 'text/htmlcharset=UTF-8')
            res.write(data)
            res.end()
        }
    })
}
//处理动态请求
function doDynamic(req, res) {
    var base = path.parse(urlInfo.pathname).base
    if (base == "login.do") {//处理登录
        console.log(urlInfo.query)
    } else if (base == "register.do") {//处理注册
    }
}

index.html

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title>首页</title>
    <style>
        a {
            display: inline-block;
            width: 100px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            background: #00aa22;
            color: #fff;
        }

        a:hover {
            color: #fff;
            background: #009900;
        }
    </style>
</head>

<body>
    <h1>欢迎来到我的主页</h1>
    <a href="login.html">登录</a>
    <a href="register.html">注册</a>
</body>

</html>

login.html

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>

<body>
    <h1>欢迎登录</h1>
    <form action="login.do">
        <p>用户名:
            <input type="text" name="uname" />
        </p>
        <p>密码:
            <input type="password" name="upwd" />
        </p>
        <button type="submit">登录</button>
    </form>
</body>

</html>

register.html

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>

<body>
    <h1>欢迎注册</h1>
    <form action="register.do">
        <p>用户名:
            <input type="text" name="uname" />
        </p>
        <p>密码:
            <input type="password" name="upwd" />
        </p>
        <button type="submit">注册</button>
    </form>
</body>

</html>

使用express搭建服务器

/*使用express搭建服务器*/
//引入express模块
var express = require("express")
//创建express类的实例,作为http服务器
var app = express()
//启动express服务器,监听8002端口
app.listen(8002)
//访问根目录
app.get("/", (req, res) => {
    res.send("您访问的是根目录")
})
//访问具体目录
app.get("/html/index.html", (req, res) => {
    res.send("您访问的是html目录")
})
//使用正则匹配
app.get(/\/log/, (req, res) => {
    res.send("您访问的是log目录")
})
/*使用express搭建服务器*/
//引入express模块
var express = require("express")
//创建express类的实例,作为http服务器
var app = express()
//启动express服务器,监听8002端口
app.listen(8003)

//访问静态资源
app.use(express.static(__dirname))
//app.use("/h",express.static("html"))
app.get('/html/login.do', (req, res) => {
})
app.get('/html/register.do', (req, res) => {
})

WangShuXian6 avatar Jun 18 '18 07:06 WangShuXian6

node process env

export NODE_ENV=production && node xxx.js 这样在当前命令行下后续的命令中读取 NODE_ENV,都会得到 production 值;

如果直接使用 NODE_ENV=production node xxx.js,则 NODE_ENV 的有效性仅限当前命令,不会对后续命令有影响 bash

“dev-mac”: " export NODE_ENV=development&& nodemon --harmony --use_strict index.js  -w ",
“dev-win”: " set NODE_ENV=development&& nodemon --harmony --use_strict index.js  -w ",

bash

export NODE_ENV=production && node xxx.js
NODE_ENV=production node xxx.js

bash cross-env

cross-env NODE_ENV=production wepy build --no-cache

/node1/process.js

console.log(process.env.NODE_ENV)

bash

NODE_ENV=1 node node1/process
// 1

WangShuXian6 avatar Jun 20 '18 01:06 WangShuXian6

npm

npm-check 依赖更新 https://segmentfault.com/a/1190000011085967 npm install -g npm-check //全局安装。项目下安装可自行选择 npm install npm-check --save-dev //项目下安装,项目根目录执行 npm install --save-dev cross-env package.json

"scripts": {
    "start": "webpack-dev-server",
    "nc-u":"cross-env NPM_CHECK_INSTALLER=cnpm npm-check -u"
  },
  "devDependencies": {
    "cross-env": "^5.0.5"
  }

npm-check指令列表

-u, --update       显示一个交互式UI,用于选择要更新的模块,并自动更新"package.json"内包版本号信息
-g, --global       检查全局下的包
-s, --skip-unused  忽略对未使用包的更新检查
-p, --production   忽略对"devDependencies"下的包的检查
-d, --dev-only     忽略对"dependencies"下的包的检查
-i, --ignore       忽略对指定包的检查.
-E, --save-exact   将确切的包版本存至"package.json"(注意,此命令将存储'x.y.z'而不是'^x.y.z')

WangShuXian6 avatar Jul 13 '18 03:07 WangShuXian6

官方解决所有 npm 全局安装权限问题

https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally If you see an EACCES error when you try to install a package globally, you can either:

  • Reinstall npm with a node version manager (recommended), or
  • Manually change npm’s default directory

// 当前用户根目录下

rm -rf .node-gyp
// 重装nodejs
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
NPM_CONFIG_PREFIX=~/.npm-global

bash 添加环境变量

cd ~
vi .bashrc
// 输入
export PATH=~/.npm-global/bin:$PATH
// 保存退出

// 加载新配置
source ./.bashrc
echo "[ -r ~/.bashrc ] && source ~/.bashrc" >> .bash_profile

zsh 添加环境变量

cd ~
vi .zshrc
// 输入
export PATH=~/.npm-global/bin:$PATH
// 保存退出

// 重启 zsh 终端

禁用 package-lock.json

*nix users may use:

echo 'package-lock=false' >> .npmrc
echo 'package-lock.json' >> .gitignore

Disabling package-lock.json Globally

npm config set package-lock false

Installing without creating the lock (one time)

rm -f package-lock.json && \
npm install lodash --save && \
rm -f package-lock.json

修复权限

sudo chown -R $USER:$GROUP ~/.npm
sudo chown -R $USER:$GROUP ~/.config
sudo npm install --unsafe-perm --verbose -g sails

WangShuXian6 avatar Feb 22 '19 02:02 WangShuXian6

child_process

spawn
const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');
const {spawn} = require('child_process');

// 开启子进程,执行 ls -l 命令以查询当前文件夹下的文件列表
const process = spawn('ls', ['-l'])

const {stdin, stdout} = process;

// 监控上一个子进程的执行输出,获取输出值,并打印
stdout.on('data', (data) => {
    console.log(`stdout: ${data}`);
});

exec
const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');
const process = require('child_process');
const lscmd = process.exec('ls -l', function (e, stdout, stderr) {
    if (!e) {
        console.log('stdout:', stdout)
        console.log('stderr:', stderr)
        return
    }
    console.log('e:', e)
})

lscmd.on('exit', status => {
    if (status) {
        throw new Error(`process ended with status: ${status}`);
    }
    console.log('process finish')
});

WangShuXian6 avatar Apr 28 '19 05:04 WangShuXian6