目录
Node.js简介
Node.js 是一个开放源代码、跨平台的 JavaScript 运行环境,开发者能够使用 JavaScript 编写服务器端的代码。通俗点说:就是一款应用程序,一款软件,构建于Google Chrome的V8 JavaScript引擎之上,提供高效的JavaScript解释和执行能力。采用了事件驱动、非阻塞I/O模型,适合构建高并发、实时应用。
网站
历史版本:https://registry.npmmirror.com/binary.html?path=node
下载长期支持版本,安装后,在命令提示符输入node -v,如果出现版本信息则代表安装成功。
运行:node 文件
注意事项
Node.js中不能使用BOM和DOM的API,可以使用console和定时器API。Node.js中的顶级对象为global。
例如,你可以在 global 对象上添加一个变量:
global.myVar = 'Hello, world!';
然后,在任何 Node.js 文件的任何地方,你都可以访问这个变量。
console.log(myVar)
// 输出: Hello, world!
但是,需要注意的是,过度使用 global 对象可能会导致代码难以理解和维护,因为全局变量可能会导致意外的副作用和命名冲突。因此,尽量避免使用全局变量,而是考虑使用模块作用域(通过 module.exports 和 require)或闭包来组织你的代码。
Buffer
简介
Buffer中文译为缓冲区,是一个类似于Array的对象,用于表示固定长度的字节序列。换句话说,Buffer就是一段固定长度的内存空间,用于处理二进制数据。
特点:大小固定且无法调整、性能较好,可以直接对计算机内存进行操作、每个元素的大小为1字节。
创建
方式一
let buf = Buffer.alloc(2)
console.log(buf)
//输出<Buffer 00 00>
方式二
let buf = Buffer.allocUnsafe(3)
console.log(buf)
//输出<Buffer 00 00 00>
方式三
let buf = Buffer.from('buffer')
console.log(buf)
//输出<Buffer 62 75 66 66 65 72>
输出是数字,在Node.js中,Buffer
类是用来处理二进制数据的, Buffer.from('buffer')
创建一个 Buffer 对象时,实际上是将字符串 'buffer' 转换为字节形式存储。在计算机内部,所有数据最终都是以二进制形式存在的,包括字符也是按照特定字符编码转换成字节序列。(16)
62 对应于字母 'b'
75 对应于字母 'u'
66 对应于字母 'f'
66 对应于字母 'f'
65 对应于字母 'e'
72 对应于字母 'r'
//使用 .toString() 方法
//例buf.toString('utf-8'),这样会得到原始的字符串 "buffer"
console.log(buf.toString())
//buffer
除了将字符串转换为Buffer,还可以将数组转换为Buffer。
数组 [13, 14]
表示两个字节的数据,其中:
- 数组的第一个元素
13
十进制转换为十六进制即为0D
- 数组的第二个元素
14
十进制转换为十六进制即为0E
这里的 0d
和 0e
是按照字节的二进制格式进行十六进制表示的结果。在不同的上下文中,这两个字节可能对应不同的字符或其他类型的数据,具体含义取决于使用的编码或数据协议。
let buf = Buffer.from([13,14])
console.log(buf)
//输出<Buffer 0d 0e>
buffer操作
buffer与字符串转换
let buf = Buffer.from([105,108,111,118,101,121,111,117])
console.log(buf.toString())
//输出iloveyou
buffer元素读取
let buf = Buffer.from('hello')
console.log(buf[2].toString())
//输出108
在 UTF-8 编码下,字符串 'hello'
对应的字节序列为:
- 'h' 对应字节
0x68
- 'e' 对应字节
0x65
- 'l' 对应字节
0x6c
- 'l' 对应字节
0x6c
- 'o' 对应字节
0x6f
访问 buf[2]
时,获取的是该缓冲区第三个字节,也就是字符 'l'
对应的字节值,在十进制下等于 108,
若想将此字节还原为其代表的字符,可以使用 buf[2].toString('utf8')
,这样会输出 'l'
。
中文
let buf = Buffer.from('缓冲区')
console.log(buf)
//输出<Buffer e7 bc 93 e5 86 b2 e5 8c ba>
占用九个字节,一个utf-8的中文占用三个字节。
fs模块
可以实现与硬盘的交互,例如文件删除、重命名、移动、创建、文件内容的读写、以及文件夹的相关操作。
writeFile
应用场景:下载文件、安装软件、保存程序日志如Git、编辑器保存文件、视频录制
fs异步写入
//导入fs模块
const fs = require('fs');
//参数:路径、写入内容、(可选)、回调
fs.writeFile('./text', 'fs写入', err => {
// err 写入失败: 错误对象 写入成功: null
if(err){
console.log('写入失败');
return;
}
console.log('写入成功');
});
fs同步写入
//同步写入
fs.writeFileSync('./text', '同步写入');
fs追加写入
异步追加写入
//引入 fs 模块
const fs = require('fs');
//调用 appendFile
fs.appendFile('./text', ',异步追加写入', err => {
//判断
if(err){
console.log('追加写入失败');
return;
}
console.log('追加写入成功');
});
同步追加写入
fs.appendFileSync('./text', '\r\n同步追加写入')
writefile追加写入,如果不写可选参数{flag:'a'},会将原来的写入内容清空
fs流式写入
const fs = require('fs');
// 创建写入流对象
const ws = fs.createWriteStream('./text');
// write
ws.write('问渠那得清如许\r\n');
ws.write('为有源头活水来\r\n');
// 关闭通道
ws.close();
readFile
应用场景:电脑开机、程序运行、编辑器打开文件、查看照片、播放视频、播放音乐、Git查看日志、上传文件、查看聊天记录
fs异步读取
fs.readFile('./text', (err, data) => {
if(err) {
console.log('读取失败');
return;
}
console.log('读取成功')
console.log(data.toString());
});
/**读取成功
问渠那得清如许
为有源头活水来
*/
fs同步读取
let data = fs.readFileSync('./text');
console.log(data.toString());
fs流式读取
const fs = require('fs');
//创建读取流对象
const rs = fs.createReadStream('./text');
// 绑定 data 事件
rs.on('data', chunk => {
console.log(chunk.toString());
});
// end 可选
rs.on('end', () => {
console.log('读取完成');
});
复制
//复制
const fs = require('fs');
const process = require('process');
const rs = fs.createReadStream('./text');
const ws = fs.createWriteStream('./text1');
rs.pipe(ws);
重命名
// 导入 fs 模块
const fs = require('fs');
// 调用 rename 方法
fs.rename('./text1', './text2', err => {
if(err) {
console.log('重命名失败');
return;
}
console.log('重命名成功');
});
移动
// 导入 fs 模块
const fs = require('fs');
//文件的移动
fs.rename('./text2', './code/text2', err => {
if(err) {
console.log('移动失败');
return;
}
console.log('移动成功');
})
删除
// 导入 fs 模块
const fs = require('fs');
// 调用 unlink
fs.unlink('./text', err => {
if(err) {
console.log('删除失败');
return;
}
console.log('删除成功');
});
// 导入 fs 模块
const fs = require('fs');
// 调用 rm 方法
fs.rm('./text', err => {
if (err) {
console.log('删除失败');
return;
}
console.log('删除成功');
})
文件夹操作
创建
// 创建文件夹
fs.mkdir('./file', err => {
if(err) {
console.log('创建失败');
return;
}
console.log('创建成功');
});
// 递归创建
fs.mkdir('./a/b/c', {recursive: true},err => {
if(err) {
console.log('创建失败');
return;
}
console.log('创建成功');
});
读取
// 读取文件夹
fs.readdir('./file', (err, data) => {
if(err){
console.log('读取失败');
return;
}
console.log('读取成功');
});
删除
// 删除文件夹
fs.rmdir('./file', err => {
if(err){
console.log('删除失败');
return;
}
console.log('删除成功');
});
//递归删除
fs.rmdir('./a', {recursive: true},err => {
if(err){
console.log(err);
return;
}
console.log('删除成功');
});
//rm
fs.rm('./a', {recursive: true},err => {
if(err){
console.log(err);
return;
}
console.log('删除成功');
});
查看
// 导入 fs 模块
const fs = require('fs');
// stat
fs.stat('../a/file', (err, data) => {
if(err){
console.log('操作失败');
return;
}
// isFile
console.log(data.isFile());
// isDirectory
console.log(data.isDirectory());
});
Path模块
//resolve 拼接得到完整路径
fs.writeFileSync(__dirname + '/text', 'love');
console.log(path.resolve(__dirname + '/text'))
// sep 分隔符
console.log(path.sep);
// windows \ Linux /
let str = 'E:\\NodeJS\\path\\path.js';
// basename 返回路径字符串中的最后一部分,即文件名:path.js
console.log(path.basename(str));
// dirname 返回路径字符串中除了最后一个部分(文件名)之外的部分,即目录路径;E:\\NodeJS\\path\\path
console.log(path.dirname(str));
// extname 返回路径中的文件扩展名部分,不包括点,即'js'
console.log(path.extname(str));
IP
标识网络中的设备,实现设备间通信
端口
网络通信中的逻辑通道标识符,每个IP地址后面跟着一个端口号,共同确定了网络中特定的服务或进程。
Http
是互联网上数据通信的基础协议,主要用于在万维网上发送和接收信息。它定义了消息的格式化方式以及传输方式,并规定了Web服务器和浏览器在接收到不同命令时应采取何种响应动作。
请求报文
HTTP请求报文是客户端(如Web浏览器)向服务器发送请求时采用的数据格式,以优快云为例:
请求行
方法(Method):描述了要执行的操作,如GET(获取数据)、POST(新增数据)、PUT(更新)、PATCH(更新)、DELETE(删除)等。
请求URI(Request-URI):指定了要访问的资源位置,可以是绝对URI或者相对URI。
HTTP版本(HTTP-Version):表明使用的HTTP协议版本,例如HTTP/1.1。
请求头
包含一系列键值对,用来传递额外的请求信息,比如:
Host:指定服务器的域名和端口号。
Accept:指定客户端能够处理的媒体类型。
Content-Type:当发送请求体时,指示其内容的MIME类型。
Authorization:携带认证信息。
Cookie:传送客户端的cookie信息。
其他很多不同的头字段,用于缓存控制、代理转发、客户端能力声明等。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers
空行
请求头和请求体之间的一个空行,用于区分这两部分。
请求体
可选部分,不是所有请求都有请求体。在POST、PUT等方法中,通常会携带请求数据,例如表单数据、JSON对象、文件上传等。
响应报文
HTTP响应报文是服务器对客户端请求的回应,其格式同样具有固定的结构,以优快云为例:
状态行
HTTP版本:表明服务器使用的HTTP协议版本,如HTTP/1.1。
状态码(Status Code):三位数字代码,如200、404、500等,分别代表成功、客户端错误和服务器错误。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
状态消息(Reason-Phrase):对状态码的文字描述,如OK、Not Found、Internal Server Error等。
响应头
同请求头一样,也是一系列键值对,包含服务器返回的各种附加信息,例如:
Content-Type:告知客户端响应体的内容类型。
Content-Length:响应体的大小(字节数)。
Set-Cookie:服务器向客户端设置cookie。
Location:重定向新的URL地址。
其他如缓存控制、服务器信息、实体标签等相关的头部信息。
空行
响应头和响应体之间的一个空行,用于区分这两部分。
响应体
包含了请求资源的实际内容,可能是HTML文档、JSON数据、图片、视频等各种类型的数据。
创建Http服务
// 导入 http 模块
const http = require('http')
// 创建服务对象
const server = http.createServer((request,response)=>{
response.setHeader('content-type', 'text/html;charset=utf-8');
response.end('你好,http');
})
// 监听端口, 启动服务
server.listen(4000,()=>{
console.log('服务器启动中.....')
})
提取报文
// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
//获取请求方法
// console.log(request.method);
//获取url
console.log(request.url); // 只包含 url 中的路径与查询字符串
//获取 HTTP 协议的版本号
// console.log(request.httpVersion);
//获取 HTTP 的请求头
// console.log(request.headers.host);
response.end('http');
});
// 监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
提取报文的请求体
// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
let body = '';
// 绑定 data 事件
request.on('data', chunk => {
body += chunk;
})
// 绑定 end 事件
request.on('end', () => {
console.log(body);
response.end('Hello HTTP');
});
});
// 监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://127.0.0.1:9000" method="post" >
<input type="text" name="username">
<input type="text" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
username=hello&password=123456
提取URL路径和字符串
//导入 http 模块
const http = require('http');
// 导入 url 模块
const url = require('url');
//创建服务对象
const server = http.createServer((request, response) => {
// 解析 request.url
//浏览器输入http://127.0.0.1:9000/search?keyword=h5&a=4
console.log(request.url);
// /search?keyword=h5
//parse用于解析URL并且返回一个URL对象
let res = url.parse(request.url, true);
//路径
let pathname = res.pathname;
console.log(pathname)
//search
//查询字符串
let keyword = res.query.keyword;
console.log(keyword)
//h5
response.end('url');
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
let res1 = url.parse(request.url, true);
console.log(res1)
//输出如下
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?keyword=h5',
query: [Object: null prototype] { keyword: 'h5' },
pathname: '/search',
path: '/search?keyword=h5',
href: '/search?keyword=h5'
}
提取URL路径和字符串2.0
//导入 http 模块
const http = require('http');
//创建服务对象
const server = http.createServer((request, response) => {
//实例化 URL 的对象
// let url = new URL('/search?a=100&b=200', 'http://127.0.0.1:9000');
let url = new URL(request.url, 'http://127.0.0.1');
//输出路径 /search
console.log(url.pathname);
//输出 keyword 查询字符串 h5
console.log(url.searchParams.get('keyword'));
response.end('url new');
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
HTTP请求练习
const http = require('http')
const server = http.createServer((request,response)=>{
let {method} = request
let {pathname} = new URL(request.url,'http://127.0.0.1')
if(method === 'GET' && pathname ==='/login')
{
response.end('login page')
}
else if(method === 'GET' && pathname ==='/reg')
{
response.end('reg')
}
else{
response.statusCode = 404
response.end('Not Fond')
}
})
server.listen(9000,()=>{
console.log('启动中...')
})
HTTP设置响应
// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
// 设置响应状态码
// response.statusCode = 404;
// 响应状态的描述
// response.statusMessage = 'hello';
// 响应头
// response.setHeader('content-type', 'text/html;charset=utf-8');
// 设置重名响应头
// response.setHeader('res', ['a','b','c']);
// 响应体的设置
response.write('hahah');
response.end('你好');
});
// 监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
HTTP响应练习
//导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
response.end(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
td{
padding: 20px 40px;
}
table tr:nth-child(odd){
background: #aef;
}
table tr:nth-child(even){
background: #fcb;
}
table, td{
border-collapse: collapse;
}
</style>
</head>
<body>
<table border="1">
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
</table>
<script>
//获取所有的 td
let tds = document.querySelectorAll('td');
//遍历
tds.forEach(item => {
item.onclick = function(){
this.style.background = '#222';
}
})
</script>
</body>
</html>
`);
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
优化,将end()中的代码单独放在一个HTML文件
//导入 http 模块
const http = require('http');
const fs = require('fs');
//创建服务对象
const server = http.createServer((request, response) => {
//读取文件内容
let html = fs.readFileSync(__dirname + 'table.html');
response.end(html); //设置响应体
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
响应练习拓展
在上一个练习基础上,分别创建Css、JS、Html文件后,根据路径读取
//导入 http 模块
const http = require('http');
const fs = require('fs');
//创建服务对象
const server = http.createServer((request, response) => {
//获取请求url的路径
let {pathname} = new URL(request.url, 'http://127.0.0.1');
if(pathname === '/'){
//读取文件内容
let html = fs.readFileSync(__dirname + '/10_table.html');
response.end(html); //设置响应体
}else if(pathname === '/index.css'){
//读取文件内容
let css = fs.readFileSync(__dirname + '/index.css');
response.end(css); //设置响应体
}else if(pathname === '/index.js'){
//读取文件内容
let js = fs.readFileSync(__dirname + '/index.js');
response.end(js); //设置响应体
}else{
response.statusCode = 404;
response.end('<h1>404 Not Found</h1>')
}
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
静态资源和动态资源
静态资源是指长时间不发生改变的资源,例如图片、视频、CSS文件、JS文件、HTML文件、字体文件等;动态资源是指内容经常更新的资源,例如百度首页、京东搜索列表页面等
/**
* 创建一个 HTTP 服务,端口为 9000,满足如下需求
* GET /index.html 响应 page/index.html 的文件内容
* GET /css/app.css 响应 page/css/app.css 的文件内容
* GET /images/logo.png 响应 page/images/logo.png 的文件内容
*/
//导入 http 模块
const http = require('http');
const fs = require('fs');
const path = require('path');
//声明一个变量
let mimes = {
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'
}
//创建服务对象
const server = http.createServer((request, response) => {
if(request.method !== 'GET'){
response.statusCode = 405;
response.end('<h1>405 Method Not Allowed</h1>');
return;
}
//获取请求url的路径
let {pathname} = new URL(request.url, 'http://127.0.0.1');
//声明一个变量
let root = __dirname + '/page';
// let root = __dirname + '/../';
//拼接文件路径
let filePath = root + pathname;
//读取文件 fs 异步 API
fs.readFile(filePath, (err, data) => {
if(err){
console.log(err);
//设置字符集
response.setHeader('content-type','text/html;charset=utf-8');
//判断错误的代号
switch(err.code){
case 'ENOENT':
response.statusCode = 404;
response.end('<h1>404 Not Found</h1>');
case 'EPERM':
response.statusCode = 403;
response.end('<h1>403 Forbidden</h1>');
default:
response.statusCode = 500;
response.end('<h1>Internal Server Error</h1>');
}
return;
}
//获取文件的后缀名
let ext = path.extname(filePath).slice(1);
//获取对应的类型
let type = mimes[ext];
if(type){
//匹配到了 text/html;charset=utf-8
if(ext === 'html'){
response.setHeader('content-type', type + ';charset=utf-8');
}else{
response.setHeader('content-type', type);
}
}else{
//没有匹配到
response.setHeader('content-type', 'application/octet-stream');
}
//响应文件内容
response.end(data);
})
});
//监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动....')
});
这个实例中,如果在JS下面创建一个abc.js,那么可以直接通过127.0.0.1:9000/js/abc.js读取内容。
网站根目录或静态资源目录
HTTP服务在哪个文件夹中寻找静态资源那个文件夹就是静态资源目录,也称之为网站根目录,上面实例的网站根目录就是page.
URL
统一资源定位符,是一种互联网上的标准资源地址格式,用于指向互联网上某一资源的地址。URL在网络世界中就像现实世界中的地址一样,帮助用户和应用程序找到并访问特定的网络资源。
网站中的URL
网站中的URL主要分为:相对路径、绝对路径
绝对路径
绝对路径可靠,相对容易理解
http://aaa.com/file | 直接向目标资源发送请求,易理解,网站外链 |
//aaa.com/file | 与页面URL的协议拼接成完整URL后发送请求,大型网站 |
/file | 与页面URL的协议、主机名、端口拼接成完整URL发送请求,中小网站 |
相对路径
相对路径在发送请求时,需要与当前页面的URL路径进行计算,得到完整URL后发请求,多用于学习阶段,例如当前网站URL:http://www.aa.com/file/a.html
./css/a.css | http://www.aa.com/file/css/a.css |
a/a.js | http://www.aa.com/file/a/a.js |
../img/a.png | http://www.aa.com/img/a.png |
../../mp3/b.mp3 | http://www.aa.com/mp3/b.mp3 |
网页中使用URL的场景
a标签href
link标签href
script标签src
img标签src
video audio 标签src
from中的action
AJAX请求中的URL
设置资源类型(mime)
媒体类型是一种标准,用来表示文档,文件或字节流的性质和格式,mime 类型结构:[type]/[subType]
例:text/html text/css image/jpeg
HTTP服务可以设置响应头Context-Type来表明响应体的MIME类型,浏览器会根据该类型决定如何处理。常见文件对应的mime类型:
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'
对于未知的资源类型,可以选择application/octet-stream类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是常见的下载效果
GET和POST请求
GET
在地址栏直接输入url访问
点击a链接
link标签引入css
script标签引入js
video与audio引入多媒体
img引入图片
from中的method为get
ajax中的get请求
POST
from中的method为post
ajax中的post请求
区别
1.作用:GET主要获取数据,POST主要提交数据’
2.参数位置:GET带参数请求是将参数放到URL之后,POST带参数请求是将参数放到请求体中
3.安全性:POST比GET相对安全一些,因为浏览器中参数会暴露在地址栏
4.GET请求大小有限制,一般为2K,而POST请求则没有大小限制
模块化
将一个复杂的程序文件依据一定的规范拆分为多个文件的过程,其中拆分出的每个文件就是一个模块,模块的内部数据是私有的,可以通过暴露内部数据以便其他模块使用。
模块化项目
编码时按照模块一个一个编码的,整个项目就是一个模块化项目。
好处
1.防止命名冲突
2.高复用性
3.高可靠性
暴露数据
模块暴露数据的方式有两种:
1. module.export = value
2.exports.name = value
module.exports可以暴露任意数据,不能使用exports = value的形式暴露数据,模块内部module与exports的隐式关系:exports = module.exports = {}
function Ha(){
console.log('汉诺塔');
}
function Max(){
console.log('求最大....');
}
//暴露数据
module.exports = {
Ha,Max
}
// exports 暴露数据
exports.Ha = Ha;
exports.Max = Max;
// module.exports 可以暴露`任意`数据
module.exports = 'hello';
module.exports = 520;
// 不能使用 `exports = value`的形式暴露数据
exports = 'iloveyou' // 不允许 X
exports = module.exports = {}
console.log(module.exports === exports); //true
exports = module.exports = {Ha:Ha}
exports.Max = Max;
exports = 'iloveyou' // 不允许 X
导入模块
在模块中使用require传入文件路径即可引入文件:const mk = require('./mk')
require注意事项
1.对于自己创建的模块,导入路径建议写相对路径,且不要省略./和../
2.js和json文件导入时可以不写后缀。C/C++编写的node拓展文件也可以不写后缀
3.如果导入其他类型的文件,会议js文件进行处理
4. 如果导入的路径是个文件夹,则会首先检查该文件夹下package.json文件中main属性对应的文件,如果main属性不存在,或者package.json不存在,则检查文件夹下的idnex.js和index.json,如果依旧找不到,就报错
5. 导入Node.js内置模块时,直接require模块的名字即可
//导入模块
// const Ha = require('./me.js');
//省略后缀 JS
// const tiemo = require('./me');
//导入 JSON 文件
// const duanzi = require('./duanzi');
// console.log(duanzi);//对象
//如果后缀不一样,前面一样,先导入js
//导入其他类型的文件
const test = require('./test');
console.log(test);
// 调用函数
// Ha();
CommonJs模块化规范
module.exports、exports以及require这些都是CommonJs模块化规范中的内容,而Node.js是实现了CommonJs模块化规范,二者的关系有点像JavaScript与ECMAScript。