Node
js模块化
Commonjs
module.exports导出
module.exports={ }
将要导出的module.exports赋值为自定义对象
可以简写成exports.default={…} exports.name=name等
注:
不可以exports={ }
因为commonjs中默认module.exports=exports
重新赋值相当于取消了module.exports暴露功能
require(“路径”)导入
const obj=require("路径")
通过require方法得到其他js文件导出的自定义对象,路径不能省略./或…/否则默认调用内置模块
通过内容对象访问具体成员,解构对象选择性获得成员,实现js模块化
ES Module
export导出
export const a = 123;
导出单个成员 可以多次导出
export default
使用export default导出的为完整的模块而非成员
export default后不能接关键字let const
import导入
import {a} from './路径.js'
导入的为export导出模块成员 ,导出多个时则于对象解构同理 需解构获取(不能任意命名)
路径需要加js 引入时为对应路径下的文件 否则解析为路由
如果是使用export default导出的完整模块,则import不用加{ } ,可以任意命名, 且只会引入export default 后的代码
as
通过as关键字可以对引入的模块进行重命名
import {a as ccc} from './路径.js'
在其他js文件引用时(继承,调用)会自动导入模块
script标签导入
<script scr="路径" type="module"></script>
需要添加type类型
commonjs与es module的区别
require()是函数,在运行时执行require函数完成导入(运行时导入)
import是命令 在编译时导入
js预编译时为所有成员(变量,函数,类(本质上是函数))提前分配好内存
node的浏览器调试
在代码行设置断点debugger
node --inspect --inspect-brk xxx.js
浏览器打开 chrome://inspect调试
占用端口
lsof -i :端口号 查看端口是否被占用
kill -x xxxxx 停止占用进程
buffer
nodejs中的一种数据流,以16进制的数字描述数据
http(s)包
创建本地服务器
const http = require('http');
// 创建本地服务器来从其接收数据
const server = http.createServer(
(request, response) => { //request=>IncomingMessage response=>ServerResponse
//编译
response.writeHead(200, { 'Content-Type': 'application/json' });
//通过响应对象response返回数据
response.end( );
}
);
//让该server应用程序/进程监听在本机的8000端口(不要使用0~1024,这一段都是系统预留端口)
server.listen(8000);
request.method
获取请求方法
request.url
获取请求路径
request.headers
获取请求头
get
const https = require('https');
// 创建本地服务器来接收数据并返回
https.get('https://www.baidu.com',(res) => {
let str=''
res.on('data',(chunk)=>{ //接受到的数据流
str+=chunk
})
res.on('end',()=>{
response.writeHead(200,{
'content-type':'application/json;charset=utf-8'
})
response.write(JSON.stringify(querystring.parse(data)))
response.end()
})
response.write()
可以结合HTML标签显示,但是不能输入非字符串
如果要使用response.write()最后必须要有response.end(),否则浏览器处于请求状态
多条语句输出使用的是response.write(),并且也结合HTML标签进行使用
response.setHeader
response.setHeader(“响应头键”,“响应头值”) 设置响应头,可以调用多次设置多个,设置的响应头会与response.writeHead()设置的响应头合并,且response.writeHead()的优先
response.writeHead
response.writeHead(“状态码”,“statusMessage[可选]”,“响应头”) 只能调用一次,且必须在response.end()被调用前调用
post
const options={
protocol: 'http:',
hostname: 'www.baidu.com',
method: 'POST',
port: '443',
path: '/ad/index.html?id=8&name=mouse',
Headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length':Buffer.byteLength(postData)
}
}
const http = require('http')
const server = http.createServer((req, res) => {
const request = http.request(options, (result) => {
})
request.write(postData)
request.end()
res.end()
})
server.listen(8080, () => {
console.log('localhost:8080');
})
//本地服务器的server的响应即发送一次请求,将请求体作为数据提交给后端服务器
//请求结束 然后server响应结束
fs包
fs包中的回调均以error优先
文件夹操作
const fs = require('fs')
fs.mkdir('./logs', function (err) {})
// 创建文件夹
fs.rename('./logs', './log', function (err) {})
// 文件夹重命名
fs.rmdir('./log', function (err) {})
// 文件夹删除
fs.readdir('./logs', function (err,result) {
console.log(result)// 读取文件夹
})
文件操作
const fs = require('fs')
------读取文件(异步)----
// 因为是异步读取,所以要在回调函数里面获取结果
fs.readFile('./text.txt', 'utf8', function (err, data) {
// err 表示读取的时候出现的错误
// data 表示读取到的内容,如果出现错误,那么是 data 是没有内容的
//读取出来的数据为buffer数据流,需要添加字符集utf8或 data.toString()
})
------读取文件(同步)-----
// 因为是同步读取,所以直接以返回值的形式接收读取的内容就可以
const res = fs.readFileSync('./text.txt', 'utf8')
// 同步读取的时候,如果出错会直接在控制台报错,并中断程序继续执行
// 如果没有错误,res 就会得到文件中的内容
------写入文件(异步)-----
// 写入内容的时候,一般不会出现错误
// 因为如果没有这个文件的话,会创建一个这个文件在向里面写入内容
// 所以回调函数一般没什么用处,只不过是在写入文件结束后做些事情而已
// 虽然没有用处,但是必须要写
fs.writeFile('./text.txt', '写入的内容', function () {
console.log('写入完成')
})
------写入文件(同步)-----
// 因为是写入文件
// 没有返回值,因为一般都会写入成功
fs.writeFileSync('./text.txt', '我是要写入的内容')
------文件追加内容-----
fs.appendFile('./text.txt', '写入的内容', function () {
console.log('写入完成')
})
------删除文件-----
fs.unlink('./text.txt', function () {
console.log('写入完成')
})
fs 中的 Promise
const fsPromise = require('fs').promises
;(async() => {
const result = await fsPromise.readFile('./text.txt')
console.log(result.toString());
})()
Process包
进程管理包,不需要require引进
打印参数
function main(argv){
console.log(argv)
}
main(process.argv.slice(2)) //数组的第三位开始才是实参
//第一位 第二位分别是 node 和 当前目录下这个js 的路径
//运行
node 当前目录下这个js argv1 argv2
打印环境变量
console.log(process.env.npm_package_config_env)
axios包
创建本地服务,返回的是一个Promise对象
const axios=require('axios')
axios.get('http:www.baidu.com')
.then((result)=>{
console.log(result.data)
}).catch((err)=>{})
url包
对url进行编码解码等操作
1.parse 解码
const url = require('url')
const urlString = 'http://www.baidu.com:443/ad/index.html?id=8&name=mouse#tag=10'
const parseStr = url.parse(urlString)
console.log(parseStr);
Url {
protocol: 'http:',
slashes: true,
auth: null,
host: 'www.baidu.com:443',
port: '443',
hostname: 'www.baidu.com',
hash: '#tag=10',
search: '?id=8&name=mouse',
query: 'id=8&name=mouse',
pathname: '/ad/index.html',
path: '/ad/index.html?id=8&name=mouse',
href: 'http://www.baidu.com:443/ad/index.html?id=8&name=mouse#tag=10'
}
2.format 编码
与parse相反,将url对象编码为一个完整的url地址
3.reslove
修改url地址栏 reslove(from,to)
const url = require('url')
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
4.URLSearchParams
定义了一些实用的方法来处理 URL 的查询字符串
var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);
for (let p of searchParams) {
console.log(p);
}
searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
querystring包(已弃用)
对http请求所带的数据进行解析
1.parse
将一个字符串反序列化为一个对象
const querystring = require('querystring')
const query = 'id=2&name=tony&from=北京'
console.log(querystring.parse(query));
//[Object: null prototype] { id: '2', name: 'tony', from: '北京' }
const query2 = 'id:2/name:tony/from:北京'
console.log(querystring.parse(query2,'/',':'));
//[Object: null prototype] { id: '2', name: 'tony', from: '北京' }
2.escape编码
const query = 'id=2&name=tony&from=北京'
console.log(querystring.escape(query));
//id%3D2%26name%3Dtony%26from%3D%E5%8C%97%E4%BA%AC
3.unescape 解码
const queryEscape = 'id%3D2%26name%3Dtony%26from%3D%E5%8C%97%E4%BA%AC'
console.log(querystring.unescape(queryEscape));
//id=2&name=tony&from=北京
4.stringify
将一个对象序列化成一个字符串
const queryObj = { id: '2', name: 'tony', from: '北京' }
console.log(querystring.stringify(queryObj,':','/'));
//id/2:name/tony:from/%E5%8C%97%E4%BA%AC
const newQuery=querystring.stringify(queryObj,null,null,{
encodeURIComponent(string){ //encodeURIComponent() 函数可把字符串作为 URI 组件进行编码
return querystring.unescape(string)
}
})
console.log(newQuery); //id=2&name=tony&from=北京
Event包
node中的事件对象
const EventEmitter = require('events') //EventEmitter为class
class MyEventEmitter extends EventEmitter {} //继承EventEmitter,增加子类实现(如需要)
const event = new MyEventEmitter() //创建实例对象
event.on('play', (value) => { //绑定事件play(自定义) value为回调函数
console.log(value);
})
event.once('play2', (value) => { //用once绑定事件则只会触发一次,触发后自动销毁
console.log(value);
})
event.emit('play', 'abc') //调用事件 'abc'为回调函数传参
事件及调用均可以定义多次
事件多次重复相同定义,则一次调用重复事件均会触发
Zlib包
对数据流进行操作
const fs = require('fs')
const zlib = require('zlib')
const gzip = zlib.createGzip() //创建新的Gzip对象
const readstream = fs.createReadStream('./note.txt') //读取文件
const writestream = fs.createWriteStream('./note2.txt') //创建可写流
readstream
.pipe(gzip) //gzip压缩
.pipe(writestream) //读取note.txt文件内容,并将内容写入到note2.txt文件中(原内容会被替换)
writestream.write(readstream) //写入数据到流
Readline包
逐行读写
const readline = require('readline');
const rl = readline.createInterface({ //固定语法
input: process.stdin,
output: process.stdout
});
rl.question('你如何看待node.js中文网', (answer) => { //控制台输出并挂起
console.log(`感谢的宝贵意见:${ answer }`); //输入结束后执行回调
rl.close(); //读写结束
})
Crypto包
字符串加密及解密
const crypto = require('crypto')
const password = '123456' //需要加密的字符串
const hash = crypto
.createHash('md5') //选择加密方式md5
.update(password) //需要加密的字符串
.digest('hex') //加密进制 (hex16位)
console.log(hash);