Node.js的入门及模块化
初识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的入门及模块化相关推荐
- 54 Node.js快速入门
技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.Node开发概述 1.1 为什么要学习服务器端开发基础 能够与后端程序员更加紧密的配合 ...
- Node.js核心入门(二)
目录: Node.js核心入门(一) 全局对象 常用工具 事件机制 Node.js核心入门(二) 文件系统访问 HTTP服务器与客户端 文件系统 fs fs 模块是文件操作的封装,它提供了文件的读取. ...
- Node.js:入门资料
<快速搭建 Node.js 开发环境以及加速 npm> http://fengmk2.com/blog/2014/03/node-env-and-faster-npm.html <N ...
- 万字长文--详解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 模 ...
- node.js学习总结:node.js的内置模块,模块化,npm与包 express,前后端身份认证 JWT认证机制
node.js学习总结 什么是node.js node.js的内置模块 fs系统模块 path路径模块 http模块 模块化 npm与包 express express路由 express+mysql ...
- Node.js开发入门—使用jade模板引擎
在"Node.js开发入门--Express安装与使用"里,我们曾经使用express generator创建了一个HelloExpress网站,express工具为我们生成了基本 ...
- Node.js开发入门—Express安装与使用
之前我们在安装完Node.js后直接写了个HelloWorld网站,这次呢,我们使用Node.js的Web框架Express来重写一下HelloWorld,看看有什么不同.同时我们还会重写之前的文件服 ...
- Node.js开发入门—语音合成示例
出于项目需要,搞了一个语音合成(TTS)的小示例,使用的是OKVoice. 我想在PC上测试,OKVoice的快速接入API可以实现我的目的,文档在这里:http://dev.okvoice.com/ ...
- Node.js 新手入门
Node.js 新手入门 Node.js是运行在服务端的JavaScript运行环境(runtime).实际上它是对Google V8引擎进行了封装.V8引 擎执行Javascript的速度非常快,性 ...
最新文章
- 常见Java面试题 BIO、NIO、AIO 有什么区别?
- laravel 控制器 中间件 传递数据_Laravel5 自定义路由中间件的使用步骤,太好用,珍藏了!...
- const in c and cpp
- java学习(94):cpu随机调用线程测试
- CentOS6.8 下MySQL5.6.29主从复制架构配置
- amos调节变量怎么画_AMOS 中验证性因素分析(CFA)
- 光环PMP ITTO
- MyBatis官方文档-简介
- SPI通信协议以及概念
- 从软件的价值体系开始向技术的反向分析
- HTTP知识点总结 - 转载
- QQ网页微信二维码登陆原理分析
- 拯救者Y7000电脑一直呼呼呼 声音很大的解决办法
- 华为云账号登录流程和方法
- 服务器中的固态硬盘优缺点,「服务器」固态硬盘的优缺点有哪些
- cdp备份和oracle备份,CDP与快照:两种不同数据保护方法
- 一个简单的自定义alert方法
- 新粉色苹果CMS10视频站源码模板 仿APP内附教程
- 如何使得自己说话有底气?
- 什么是大数据?大数据的5V特点是什么?