初识Node.js

Node.js是一个基于Chrome V8引擎的JavaScript运行环境。
1、浏览器是JavaScript的前端运行环境
2、Node.js是JavaScript的后端运行环境
3、Node.js中无法调用DOM和BOM等浏览器内置的API

区分LTS版本和Current版本的不同

1、LTS作为长期稳定版本,对于追求稳定性的企业级项目来说,应使用LTS版本的Node.js。
2、Current为新特性版本。
使用node -v查看已安装Node.js的版本号

在Node.js环境中执行JavaScript代码


在终端中,使用esc键,能够快速清空当前已输入的命令,输入cls命令,可以清空终端。

fs文件系统模块

fs模块是Node.js官方提供的,用来操作文件的模块,它提供了一系列的方法和属性,用来满足用户对文件的操作需求。
fs.readFile()方法,用来读取指定文件中的内容。
fs.writeFile()方法,用来向指定的文件中写入内容。
如果在JavaScript代码中,使用fs模块来操作文件,则需要使用如下的方式先导入它:const fs = require('fs')

fs.readFile()方法

1、fs.readFile()的语法格式
使用fs.readFile()方法,可以读取指定文件中的内容,语法fs.readFile(path[, options],callback)使用中括号包裹的是可选参数。
参数1:必选参数,字符串,表示文件的路径
参数2:可选参数,表示以什么格式的编码格式来读取文件
参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果
2、fs.readFile()示例代码
以utf8的编码格式,读取指定文件的内容,并打印err和dataStr的值:

//1、导入fs模块
const fs = require('fs')
//2、调用fs.reedFile()方法读取文件
//  参数1:读取文件的存放路径
//  参数2:读取文件时的编码格式,一般指定utf8
//  参数3:回调函数,拿到读取失败和成功的结果, err dataStr
fs.readFile('./files/1.txt','utf8',function (err,dataStr) {//打印失败的结果,如果读取成功,则err的值为nullconsole.log(err)console.log('------')//打印成功的结果console.log(dataStr)})


如果读取错误,err的值为错误对象,dataStr则为undefined

3、判断文件是否读取成功
可以判断err对象是否为null,从而知晓文件读取的效果。通过err能够转为true,如果err为true则err不为null,则文件读取失败,打印失败的结果

//1、导入fs模块
const fs = require('fs')
//2、调用fs.reedFile()方法读取文件
//  参数1:读取文件的存放路径
//  参数2:读取文件时的编码格式,一般指定utf8
//  参数3:回调函数,拿到读取失败和成功的结果, err dataStr
fs.readFile('./files/11.txt','utf8',function (err,dataStr) {if (err){return console.log('读取文件失败' + err.message)}console.log('文件读取成功!' + dataStr)})

fs.writeFile()方法

1、fs.writeFile()的语法格式
使用fs.writeFile()方法,可以向指定的文件中写入内容,语法fs.writeFile(file,data,[, options],callback)使用中括号包裹的是可选参数。
参数1:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径
参数2:必选参数,表示要写入的内容
参数3:可选参数,表示以什么格式的编码格式来写入文件,默认是utf8
参数4:必选参数,文件写入完成后的回调函数

//1、导入fs模块
const fs = require('fs')
//2、调用fs.writeFile()方法,写入文件的内容
//  参数1:表示文件的存放路径
//  参数2:表示要写入的内容
//  参数3:回调函数
fs.writeFile('./files/2.txt','abcd',function(err) {//如果文件写入成功,打印的err为一个null,但是当写入路径错误,打印的就不是null,而是一个真正的错误对象console.log(err)})


2、判断文件是否写入成功
可以判断err对象是否为null,从而知晓文件写入的效果。通过err能够转为true,如果err为true则err不为null,则文件读取失败,打印失败的结果

//1、导入fs模块
const fs = require('fs')
//2、调用fs.reedFile()方法读取文件
//  参数1:读取文件的存放路径
//  参数2:读取文件时的编码格式,一般指定utf8
//  参数3:回调函数,拿到读取失败和成功的结果, err dataStr
fs.writeFile('./files/2.txt','hfhfhfh',function (err) {if (err){return console.log('读取写入失败' + err.message)}console.log('文件写入成功!' )})

练习-考试成绩管理

使用fs文件系统模块,将素材目录下成绩.txt文件中的考试数据,整理到成绩-ok.txt文件中。

核心实现步骤
1、导入需要的fs文件系统模块
2、使用fsreadFile()方法,读取素材目录下的成绩.txt文件
3、判断文件下是否读取失败
4、文件读取成功后,处理成绩数据
5、将处理完的成绩数据,调用fs.writeFile()方法,写入到新文件成绩ok.txt中。

//1、导入fs模块
const fs = require('fs')
//2、调用fs.reedFile()方法读取文件fs.readFile('./files/成绩-ok.txt','utf8',function (err,dataStr) {//3、判断是否读取成功if (err){return console.log('读取写入失败' + err.message)}/* console.log('文件写入成功!' +  dataStr)*///4.1先把成绩的数据,按照空格进行分割const arrOld = dataStr.split(' ')console.log(arrOld)//4、2循环分割后的数据,对每一项数据,进行字符串的替换操作const arrNew = []arrOld.forEach(item => {arrNew.push(item.replace('=',':'))})console.log(arrNew)//4、3把数组中的每一项,进行合并,得到一个新的字符串const newStr = arrNew.join('\r\n')console.log(newStr)//5、调用fs.writeFile()方法,把处理完毕的成绩,写入到新文件中fs.writeFile('./files/成绩-ok.txt',newStr,function (err) {if (err){return console.log('写入文件失败!' + err.message)}console.log('成绩写入成功!')})
})

fs模块-路径动态拼接的问题

在使用fs模块操作文件时,如果提供的操作路径是以/或…/开头的相对路径时,很容易出现路径动态拼接错误的问题。
原因:代码在运行的时候,会以执行node 命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方案:在使用fs模块操作文件时,直接提供完整的路径,不要提供.或…/开头的相对路径,从而防止路径动态拼接的问题。
这里__dirname表示当前文件所处目录,这里可以使用字符串的拼接进行路径的指定。

path路径模块

path模块是Node.js官方提供的,用来处理路径的模块,它提供了一系列的的方法和属性,用来满足用户对路径的处理需求。
path.join()方法,用来将多个路径拼接成一个完整的路径字符串
path.basename()方法,用来从路径字符串中,将文件名字解析出来
如果要在JavaScript代码中,使用path模块来处理路径,则需要使用如下的方式先导入它:const path = require('path')

path.join()

1、path.join()语法格式
使用path.join()方法,可以把多个路径片段拼接为完整的路径字符串,语法格式如下:path.join([...paths])
参数解读:...paths <string>路径片段的序列
返回值:<string>
2、path.join()代码示例

const path = require('path')
const fs = require('fs')//注意: ../会抵消前面一层路径,多个则抵消多层路径
const pathStr = path.join('/a','/b/c','../','./d','e')
console.log(pathStr)//\a\b\d\e//这里写代码的文件为06.path.join这个文件处于day01文件夹下,所以这里的__dirname就是day01
fs.readFile(path.join(__dirname,'/files/1.txt'),'utf8',function (err,dataStr) {if (err){return console.log(err.message)}console.log(dataStr)})

path.basename()

path.basename()方法,可以获取路径中的最后一部分,经常通过这个方法获取路径中的文件名,语法格式如下path.basenem(path[, ext])
参数解读:path<string>必选参数,表示一个路径的字符串
ext<string>可选参数,表示文件扩展名
返回<string>表示路径中的最后一部分

const path = require('path')const fpath = '/a/b/c/index.html'const fullName = path.basename(fpath)
console.log(fullName)//index.htmlconst newfull = path.basename(fpath,'.html')
console.log(newfull)//index

path.extname()

使用 path.extname()方法,可以获取路径中的扩展名部分,语法格式如下:path.extname(path)
参数解读:
path <string>必选参数,表示一个路径字符串
返回:<string>返回得到的扩展名字符串

const path = require('path')const fpath = '/a/b/c/index.html'const fext = path.extname(fpath)
console.log(fext)//.html

综合案例-时钟案例

案例要实现功能
将素材目录下的index.html页面拆成三个文件,分别是index.js index.css index.html并且将拆分出来的3个文件存放到clock目录中。
案例的实现步骤
1、创建两个正则表达式,分别用来匹配

//1.1导入fs文件系统模块
const fs = require('fs')
//1.2导入path路径处理模块
const path = require('path')//1.3匹配<style></style>标签的正则
//      其中\s表示空白字符;\S表示非空白字符;* 表示匹配任意次
const regStyle = /<style>[\s\S]*<\/style>/
//1.4匹配<script></script>标签正则
const regScript = /<script>[\s\S]*<\/script>///2.1读取需要被处理的HTML文件
fs.readFile(path.join(__dirname,'/index.html'),'utf8',(err,dataStr) =>{//2.2读取HTML文件失败if (err) return console.log('读取HTML文件失败!' + err.message)//2.3读取HTML文件成功后,调用对应的方法,拆解出css,js和HTML文件resolveCSS(dataStr)resolveJS(dataStr)resolveHTML(dataStr)
})//3.1处理css样式
function resolveCSS(htmlStr){//3.2使用正则提取页面中的style标签const r1 = regStyle.exec(htmlStr)//3.3将提取出来的样式字典,做进一步处理const newCSS = r1[0].replace('<style>','').replace('</style>','')//3.4将提取出来的css样式,写入到index.css文件中fs.writeFile(path.join(__dirname,'./clock/index.css'),newCSS,err => {if (err)return console.log('写入CSS样式失败!' + err.message)console.log('写入CSS样式成功')})
}//4.1处理JS脚本
function  resolveJS(htmlStr){//4.2使用正则提取页面中的<script>标签const r2 = regScript.exec(htmlStr)//4.3将提取出来的脚本字符串,做进一步处理const newJS = r2[0].replace('<script>','').replace('</script>','')//4.4将提取出来的js脚本,写入到index.js文件中fs.writeFile(path.join(__dirname,'./clock/index.js'),newJS,err => {if (err)return console.log('写入JavaScript脚本失败!' + err.message)console.log('写入JS脚本成功!')})
}//5.1处理html文件
function resolveHTML(htmlStr){//5.1使用字符串的replace方法,把内嵌的<style><script>标签,替换为外联的<link><script>标签const newHTML = htmlStr.replace(regStyle,'<link rel="stylesheet" href="./index.css"/>').replace(regScript,'<script src="./index.js"></script>')//5.2将替换完成的html代码,写入到index.html文件中fs.writeFile(path.join(__dirname,'./clock/index.html'),newHTML,err => {if (err) return console.log('写入HTML文件失败!' + err.message)console.log('写入HTML页面成功!')})
}

fs.writeFile()方法只能用来创建文件,不能用来创建路径。重复调用fs.writeFile()写入同一个文件,新写入的内容会覆盖之前的旧内容

HTTP模块

什么是HTTP模块

在网络节点中,负责消费资源的电脑,叫客户端,负责对外提供网络资源的电脑,叫做服务器

http模块是Node.js官方提供的,用来创建web服务器的模块,通过http模块提供的http.creatServer()方法,就能把一台普通的电脑,变成一台Web服务器,从而对外提供Web资源服务,导入模块const http = require('http')

进一步理解http模块的作用

服务器和普通电脑的区别在于,服务器上安装了web服务器软件,例如:IIS、Apache等。通过安装这些服务器软件,就能把一台普通电脑变成一台web服务器。
在Node.js中,我们不需要使用IIS,Apache等这些第三方web服务器软件,因为我们可以基于Node.js提供的http模块,通过几行简单代码,就能充当服务器。

服务器相关概念

1、IP地址
IP地址就是互联网上每台计算机的唯一地址,因此IP地址具有唯一性。如果把“个人电脑”比作“一台电话”,那么“IP地址”就相当于“电话号码”,只有在知道对方IP地址的前提下,才能与对应的电脑之间进行数据通信。

IP地址的格式:通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是O~255之间的十进制整数。例如:用点分十进表示的IP地址(192.168.1.1)

2、域名和域名服务器

尽管IP地址能够唯一地标记网络上的计算机,但IP地址是一长串数字,不直观,而且不便于记忆,于是人们又发明了另一套字符型的地址方案,即所谓的域名(Domain Name)地址。
IP地址和域名是一一对应的关系,这份对应关系存放在一种叫做域名服务器(DNS,Domain name server)的电脑中。使用者只需通过好记的域名访问对应的服务器即可,对应的转换工作由域名服务器实现。因此,域名服务器就是提供IР地址和域名之间的转换服务的服务器。

单纯使用IP地址,互联网中的电脑也能够正常工作。但是有了域名的加持,能让互联网的世界变得更加方便。
在开发测试期间,127.0.0.1对应的域名是localhost,它们都代表我们自己的这台电脑,在使用效果上没有任何区别。
3、端口号
计算机中的端口号,就好像是现实生活中的门牌号一样。通过门牌号,外卖小哥可以在整栋大楼众多的房间中,准确把外卖送到你的手中。
同样的道理,在一台电脑中,可以运行成百上千个web服务。每个web服务都对应一个唯一的端口号。客户端发送过来的网络请求,通过端口号,可以被准确地交给对应的web 服务进行处理。

创建最基本的web服务器

1、导入HTTP模块const http = require('http')
2、创建web服务器实例const server = http.createServer()
3、为服务器实例绑定request事件,监听客户端发送来的网络请求
4、启动服务器

//1、导入http模块
const  http = require('http')
//2、创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,即可监听客户端发送过来的网络请求
//使用服务器实例的.on()方法,为服务器绑定一个request事件
server.on('request',(req,res)=> {//只要有客户端来请求我们的服务器,就会触发request事件,从而调用这个事件处理函数console.log('Someone visit our web server')
})
//4、调用服务器实例.listen()方法,即可启动当前web服务器
server.listen(80,() =>{console.log('http server running at http://127.0.0.1')
})

req请求对象
只要服务器接收到了客户端的请求,就会调用通过server.on()为服务器绑定的request事件处理函数。如果想在事件处理函数中,访问与客户端相关的数据或属性,可以使用如下方式

//1、导入http模块
const  http = require('http')
//2、创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,即可监听客户端发送过来的网络请求
//使用服务器实例的.on()方法,为服务器绑定一个request事件
server.on('request',(req) => {//这里使用的ES6中的模板字符串为反引号,就是键盘左上角的‘~’按钮const str = `Your request url is ${req.url},and request method is ${req.method}`console.log(str)//Your request url is /,and request method is GET})
server.listen(80,() =>{console.log('server running at http://127.0.0.1')
})

res响应对象
在服务器的request事件处理函数中,如果想访问与服务器相关的数据或属性,可以使用如下方式

//1、导入http模块
const  http = require('http')
//2、创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,即可监听客户端发送过来的网络请求
//使用服务器实例的.on()方法,为服务器绑定一个request事件
server.on('request',(req,res) => {//res是响应对象,它包含了与服务器相关的数据和属性,例如://要发送到客户端的字符串const str = `Your request url is ${req.url},and request method is ${req.method}`//res.end()方法的作用,向客户端发送指定内容,并结束这次请求的处理过程res.end(str)})
server.listen(80,() =>{console.log('server running at http://127.0.0.1')
})


解决中文乱码问题
当调用res.end()方法,向客户端发送中文内容的时候,会出现乱码问题

//1、导入http模块
const  http = require('http')
//2、创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,即可监听客户端发送过来的网络请求
//使用服务器实例的.on()方法,为服务器绑定一个request事件
server.on('request',(req,res) => {const str = `您请求的URL地址是${req.url},请求的method类型是${req.method}`//为了防止中文显示乱码的我呢提,需要设置响应头Content-Type的值为text/html;charest=utf-8res.setHeader('Content-Type','text/html;charset=utf-8')res.end(str)
})
server.listen(80,() =>{console.log('server running at http://127.0.0.1')
})

根据不同的url响应不同的html内容

核心实现步骤
1、获取请求的url地址
2、设置默认的响应内容为404 Not Found
3、判断用户请求的是否为/或/index.html首页
4、判断用户请求的是否为/oabout.html关于页面
5、设置Content-Type响应头,防止中文乱码
6、使用res.end()把内容响应给客户端
动态响应内容

//1、导入http模块
const  http = require('http')
//2、创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,即可监听客户端发送过来的网络请求
//使用服务器实例的.on()方法,为服务器绑定一个request事件
server.on('request',(req,res) => {const url = req.urllet content = '<h1>404 Not found!</h1>'if (url === '/' || url ==='/index.html'){content = '<h1>首页</h1>'}else if (url === '/about.html'){content = '<h1>关于页面</h1>'}res.setHeader('Content-Type','text/html;charset=utf-8')res.end(content)
})
server.listen(80,() =>{console.log('server running at http://127.0.0.1')
})

模块化的基本概念

模块化是指解决一个复杂问题时,自顶向下逐级把系统划分成若干模块的过程,对于整个系统来说,模块是可以组合、分解和更换的单元。
把代码进行模块化拆分的好处:提高代码复用性和可维护性,实现按需加载。使用模块化规范应考虑使用什么样的语法格式来引用模块,在模块中使用什么样的语法格式向外暴露成员。

Node.js中模块化

Node.js中模块的分类

Node.js中根据模块来源的不同,将模块分为3大类,分别是:
内置模块(内置模块是由Node.js官方提供的,例如fs、path、http等)
自定义模块(用户创建的每个.js文件,都是自定义模块)
第三方模块(由第三方模块开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要下载)

加载模块

使用强大的require()方法,可以加载需要的内置模块,用户自定义模块,第三方模块进行使用。使用require调用其他模块时,可以不用写文件后缀名,他自己会找。例如:

//1、导入http模块
const  http = require('http')
//2、加载用户的自定义模块
const custom = require('./custom.js')
//3、加载第三方模块
const moment = require('moment')

使用require()方法加载其他模块时,会执行被加载模块中的代码

Node.js中的模块作用域

和函数作用域类似,在自定义模块中定义的变量,方法等成员,只能在当前模块中被访问,这种模块级别的访问限制,叫做模块作用域。
我们导入的custom是一个空对象,这样防止了全局变量污染的问题。

向外共享模块作用域中的成员

1、module对象
在每个.js自定义模块中都有一个module对象,它里面存储了和当前模块有关的信息

2、module.exports对象
在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用。外界用require()方法导入自定义模块时,得到的就是module.exports所指向的对象。
3、共享成员时的注意点
使用require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准。

exports对象

由于module.exports单词写起来复杂,为了简化向外共享成员的代码,Node提供了exports对象。默认情况下,exports和module.exports指向同一个对象,还是以module.exports指向的对象为准。

exports和module.exports使用误区
简单来说,只要不是指向对象形式,就是添加属性。所以在同一个模块中不建议同时使用exports和module.exports

Node.js中的模块化规范

Node.js遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之间如何相互依赖。
CommonJS规定:
1、每个模块内部,module变量代表当前模块
2、module变量是一个对象,它的exports属性(即module.exports)是对外的接口
3、加载某个模块,其实是加载该模块的module.exports属性,require()方法用于加载模块。

npm与包

Node.js中的第三方模块又叫包。不同于Node.js中的内置模块与自定义模块,包是由第三方个人或团队开发出来的,免费供所有人使用。
由于Node.js的内置模块仅提供了一些底层的API,导致在基于内置模块进行项目开发的时,效率很低。包是基于内置模块封装出来的,提供了更高级、更方便的API,极大的提高了开发效率。
包和内置模块之间的关系,类似于jQuery和浏览器内置API之间的关系。

从https://www.npmjs.com/网站上搜索自己所需要的包从https://registry.npmjs.org/服务器上下载自己需要的包

下载包

这个包管理工具的名字叫做Node Package Manager(简称npm包管理工具),这个包管理工具随着Node,js的安装包一起被安装到了用户的电脑上。
使用时在官网搜索moment,进入后Documentation上右键在新标签页中打开则可显示具体使用方法。

npm入门

在项目中安装包的命令
npm install 包的完整名称,也可简化为 npm i 包的完整名称
格式化时间的高级做法
1、使用npm包管理工具,在项目中按安装格式化时间的包moment
2、使用require()导入格式化时间的包
3、参考moment的官方API文档对事件进行格式化

//1、导入需要的包
//注意导入的名称,就是装包的名称
const moment = require('moment')
//
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt)//2022-08-22 17:07:41

初次装包后多了哪些文件

初次装包完成后,在项目文件夹下多一个叫做node_modules 的文件夹和package-lock.json的配置文件。

node modules文件夹用来存放所有已安装到项目中的包。require()导入第三方包时,就是从这个目录中查找并加载包。package-lock.json配置文件用来记录node_modules 目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。

包的语义化版本规范
包的版本号是以“点分十进制”形式进行定义的,总共有三位数字,例如2.24.0其中每一位数字所代表的的含义如下:
第1位数字:大版本
第2位数字:功能版本
第3位数字:Bug修复版本
版本号提升的规则:只要前面的版本号增长了,则后面的版本号归零。

包管理配置文件

npm规定,在项目根目录中,必须提供一个叫做package.json的包管理配置文件。用来记录与项目有关的一些配置信息。例如:
项目的名称、版本号、描述等
项目中都用到了哪些包
哪些包只在开发期间会用到
那些包在开发和部署时都需要用到

在团队共享开发中,需要同时剔除node_modules,所以在协同开发时,需要将其添加到.gitignore忽略文件中。
快速创建package.json
npm包管理工具提供了一个快捷命令,可以在执行命令时所处的目录中,快速创建package.json这个包管理。

//作用:在执行命令所处的目录中,快速创建package.json文件
npm init -y

上述命令只能在英文的目录下成功运行!所以,项目文件夹的名称一定要使用英文命名,不要使用中文,不能出现空格。运行 npm install命令安装包的时候,npm包管理工具会自动把包的名称和版本号,记录到package.json中。

Dependencies节点为package.json中记录使用npm install命令安装了那些包

一次性安装所有的包
当我们拿到一个剔除了node_modules的项目之后,需要先把所有的包下载到项目中,才能将项目运行起来。不然会报错,入没有moment包Error: Cannot find module ' moment'
所以,我们需要一次性安装所有的包,也同Java更新依赖一样。执行npm install命令时,npm包管理工具会先读取 package.json 中的 dependencies 节点,读取到记录的所有依赖包名称和版本号之后,npm包管理工具会把这些包一次性下载到项目中
卸载包
可以运行npm uninstall命令,来卸载指定的包npm uninstall moment
devDependencies节点
如果某些包只在项目开发阶段会用到,在项目上线之后不会用到,则建议把这些包记录到devDependencies节点中。与之对应的,如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到dependencies节点中。

//安装指定的包,并记录到devDependencies节点中
npm i 包名 -D
//注意:上述命令是简写形式,等价于下面完整写法
npm install 包名 --save-dev

解决下包速度慢的问题

切换npm的下包资源

nrm

为了更方便的切换下包镜像资源,安装nrm小工具,利用nrm提供的终端命令,可以快速查看和切换下包的镜像源,这里的taobao改名为了npmmirror

包的分类
使用npm包管理工具下载的包,共分为两大类,分别为项目包和全局包
1、项目包:那些被安装到项目的node_modules目录中的包,都是项目包。
项目包又分为两类,分别是:
开发依赖包(被记录到devDependencies节点中的包,只在开发期间会用到)
核心依赖包(被记录到dependencies节点中的包,在开发期间和项目上线之后都会用到)
2、全局包:在执行npm install命令时,如果提供了-g参数,则会把包安装为全局包。
全局包会被安装到C:\Users\用户目录\AppData\Roaming\npm\node_modules目录下。
只有工具性质的包,才有全局安装的必要性。因为它们提供了好用的终端命令。判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明即可。

3、i5ting_toc
i5ting_toc 是一个可以把 md 文档转为 html 页面的小工具,使用步骤如下:


规范的包结构
一个规范的包,它的组成结构,必须符合以下 3 点要求:
① 包必须以单独的目录而存在
② 包的顶级目录下要必须包含 package.json 这个包管理配置文件
③ package.json 中必须包含 name,version,main 这三个属性,分别代表包的名字、版本号、包的入口。

模块的加载机制

优先从缓存中加载

模块在第一次加载后会被缓存。 这也意味着多次调用 require() 不会导致模块的代码被执行多次。
注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。

内置模块的加载机制

内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高。
例如,require(‘fs’) 始终返回内置的 fs 模块,即使在 node_modules 目录下有名字相同的包也叫做 fs。

自定义模块的加载机制

使用 require() 加载自定义模块时,必须指定以 ./ 或 …/ 开头的路径标识符。在加载自定义模块时,如果没有指定 ./ 或 …/
这样的路径标识符,则 node 会把它当作内置模块或第三方模块进行加载。
同时,在使用 require() 导入自定义模块时,如果省略了文件的扩展名,则 Node.js 会按顺序分别尝试加载以下的文件:
① 按照确切的文件名进行加载
② 补全 .js 扩展名进行加载
③ 补全 .json 扩展名进行加载
④ 补全 .node 扩展名进行加载
⑤ 加载失败,终端报错

第三方模块的加载机制

如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘…/’ 开头,则 Node.js 会从当前模块的父
目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。
例如,假设在 ‘C:\Users\itheima\project\foo.js’ 文件里调用了 require(‘tools’),则 Node.js 会按以下顺序查找:
① C:\Users\itheima\project\node_modules\tools
② C:\Users\itheima\node_modules\tools
③ C:\Users\node_modules\tools
④ C:\node_modules\tools

目录作为模块

当把目录作为模块标识符,传递给 require() 进行加载的时候,有三种加载方式:
① 在被加载的目录下查找一个叫做 package.json 的文件,并寻找 main 属性,作为 require() 加载的入口
② 如果目录里没有 package.json 文件,或者 main 入口不存在或无法解析,则 Node.js 将会试图加载目录下的 index.js 文件。
③ 如果以上两步都失败了,则 Node.js 会在终端打印错误消息,报告模块的缺失:Error: Cannot find module ‘xxx’

Node.js的入门及模块化相关推荐

  1. 54 Node.js快速入门

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.Node开发概述 1.1 为什么要学习服务器端开发基础 能够与后端程序员更加紧密的配合 ...

  2. Node.js核心入门(二)

    目录: Node.js核心入门(一) 全局对象 常用工具 事件机制 Node.js核心入门(二) 文件系统访问 HTTP服务器与客户端 文件系统 fs fs 模块是文件操作的封装,它提供了文件的读取. ...

  3. Node.js:入门资料

    <快速搭建 Node.js 开发环境以及加速 npm> http://fengmk2.com/blog/2014/03/node-env-and-faster-npm.html <N ...

  4. 万字长文--详解Node.js(快速入门)

    Node.js基础与扩展 Node.js 1.初识Node.js与内置模块 1.1 Node.js初识 1.2 fs文件系统模块 1.3 path路径模块 1.4 http模块 2.模块化 2.1 模 ...

  5. node.js学习总结:node.js的内置模块,模块化,npm与包 express,前后端身份认证 JWT认证机制

    node.js学习总结 什么是node.js node.js的内置模块 fs系统模块 path路径模块 http模块 模块化 npm与包 express express路由 express+mysql ...

  6. Node.js开发入门—使用jade模板引擎

    在"Node.js开发入门--Express安装与使用"里,我们曾经使用express generator创建了一个HelloExpress网站,express工具为我们生成了基本 ...

  7. Node.js开发入门—Express安装与使用

    之前我们在安装完Node.js后直接写了个HelloWorld网站,这次呢,我们使用Node.js的Web框架Express来重写一下HelloWorld,看看有什么不同.同时我们还会重写之前的文件服 ...

  8. Node.js开发入门—语音合成示例

    出于项目需要,搞了一个语音合成(TTS)的小示例,使用的是OKVoice. 我想在PC上测试,OKVoice的快速接入API可以实现我的目的,文档在这里:http://dev.okvoice.com/ ...

  9. Node.js 新手入门

    Node.js 新手入门 Node.js是运行在服务端的JavaScript运行环境(runtime).实际上它是对Google V8引擎进行了封装.V8引 擎执行Javascript的速度非常快,性 ...

最新文章

  1. 常见Java面试题 BIO、NIO、AIO 有什么区别?
  2. laravel 控制器 中间件 传递数据_Laravel5 自定义路由中间件的使用步骤,太好用,珍藏了!...
  3. const in c and cpp
  4. java学习(94):cpu随机调用线程测试
  5. CentOS6.8 下MySQL5.6.29主从复制架构配置
  6. amos调节变量怎么画_AMOS 中验证性因素分析(CFA)
  7. 光环PMP ITTO
  8. MyBatis官方文档-简介
  9. SPI通信协议以及概念
  10. 从软件的价值体系开始向技术的反向分析
  11. HTTP知识点总结 - 转载
  12. QQ网页微信二维码登陆原理分析
  13. 拯救者Y7000电脑一直呼呼呼 声音很大的解决办法
  14. 华为云账号登录流程和方法
  15. 服务器中的固态硬盘优缺点,「服务器」固态硬盘的优缺点有哪些
  16. cdp备份和oracle备份,CDP与快照:两种不同数据保护方法
  17. 一个简单的自定义alert方法
  18. 新粉色苹果CMS10视频站源码模板 仿APP内附教程
  19. 如何使得自己说话有底气?
  20. 什么是大数据?大数据的5V特点是什么?

热门文章

  1. Checkbox 样式
  2. matlab实验大纲,matlab实验教学大纲.doc
  3. mysql可以做决策树吗_决策树 - stream886 - 博客园
  4. PB的DataWindow的38个技巧
  5. 每日一个代码-第一天
  6. Verilog自制NIOS2外设,Avalon总线上的HelloWorld
  7. python微软雅黑字体_Matplotlib中文字体显示
  8. 第7章面向对象编程_基础部分
  9. 【科技与文艺】从星球大战日谈科幻文艺
  10. java使用aes加密文件内容