node基础及模块化

目录

前言:

命令行

进程和线程

node简介

运行node.js

Node.js 从命令行接收参数

exports

npm 

 fs文件系统模块

http模块

IP 地址

域名和域名服务器

创建 web 服务器的基本步骤

模块化

加载模块

 自定义模块的加载机制:

第三方模块的加载机制:

 模块作用域

向外共享模块作用域中的成员:module 对象/module.exports 对象

  CommonJS 模块化规范


前言:

命令行

命令行窗口(cmd窗口、终端、shell)

win+r 运行cmd回车进入命令行窗口。

常用指令:

  • dir 列出当前目录下的所有文件,
  • cd 目录名 进入到指定目录( 目录 . 代表当前目录 .. 代表上一级目录)
  • md 目录名 创建目录
  • rd 目录名  删除目录
  • cd 退回到根目录
  • del  删除文件
  • exit   退出dos 命令行

当在命令行窗口打开一个文件,或一个程序时,系统会首先在当前目录下寻找文件程序,找到了直接打开没找到则到环境变量path的路径中寻找,直到找到为止。(因此可以将常用的程序或者文件路径添加到path中,方便后续使用)

进程和线程

进程负责为程序的运行提供必备的环境,线程是计算机的最小计算单位,线程负责执行进程中的程序;

node简介

Node.js 是一个开源和跨平台的 JavaScript 运行时环境。Node.js 应用程序在单个进程中运行,无需为每个请求创建新的线程。在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准。

node是一个可以在服务器端运行JavaScript的开发源代码、跨平台JavaScript运行环境。

运行node.js

node 命令是用来运行 Node.js 脚本的命令

运行 Node.js 程序的常用方法是:运行全局可用的命令  node + 要执行的文件的名称。

例如:node app.js (当运行命令时,请确保您位于包含 app.js 文件的同一目录中。)

按下 tab 键,则 REPL 会尝试自动补全所写的内容,以匹配已定义或预定义的变量。

试输入 JavaScript 类的名称,例如 Number,添加一个点号并按下 tab。REPL 会打印可以在该类上访问的所有属性和方法。

输入 global. 并按下 tab,可以检查可以访问的全局变量。

当在控制台中运行程序时,可以用 ctrl-C 关闭它,以编程方式退出可以使用:process.exit()

可以传入一个整数,向操作系统发出退出代码的信号:process.exit(1)   默认的退出码为 0,表示成功。也可以设置 process.exitCode 属性:process.exitCode = 1  当程序结束时,Node.js 将返回该退出代码。

还有一些点命令:

  • .help: 显示点命令的帮助。
  • .editor: 启用编辑器模式,可以轻松地编写多行 JavaScript 代码。当处于此模式时,按下 ctrl-D 可以运行编写的代码。
  • .break: 当输入多行的表达式时,输入 .break 命令可以中止进一步的输入。相当于按下 ctrl-C。
  • .clear: 将 REPL 上下文重置为空对象,并清除当前正在输入的任何多行的表达式。
  • .load: 加载 JavaScript 文件(相对于当前工作目录)。
  • .save: 将在 REPL 会话中输入的所有内容保存到文件(需指定文件名)。
  • .exit: 退出 REPL(相当于按下两次 ctrl-C)。

Node.js 从命令行接收参数

参数可以是独立的,也可以具有键和值。

node app.js joe

// 或

node app.js name=joe

获取参数值的方法是使用 Node.js 中内置的 process 对象。它公开了 argv 属性,该属性是一个包含所有命令行调用参数的数组。

  • 第一个参数是 node 命令的完整路径。
  • 第二个参数是正被执行的文件的完整路径。
  • 所有其他的参数从第三个位置开始。
 // 使用循环迭代所有的参数(包括 node 路径和文件路径):

process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`)
})

 // 也可以通过创建一个排除了前两个参数的新数组来仅获取其他的参数:

const args = process.argv.slice(2)

 // 如果参数没有索引名称,例如:

node app.js joe

// 则可以这样访问:

const args = process.argv.slice(2)
args[0]

exports

Node.js 具有内置的模块系统。

Node.js 文件可以导入其他 Node.js 文件公开的功能。

// 当想要导入某些东西时,使用

const library = require('./library')

// 可以导入存在于当前文件夹中的 library.js 文件中公开的功能。

在这之前必须先公开功能,然后其他文件才能将其导入。这就是module 系统提供的 module.exports API 可以做的事。

//第一种方式是将对象赋值给 module.exports(这是模块系统提供的对象),这会使文件只导出该对象:

// JS
const car = {
  brand: 'Ford',
  model: 'Fiesta'
}

module.exports = car

//在另一个文件中

const car = require('./car')

//第二种方式是将要导出的对象添加为 exports 的属性。这种方式可以导出多个对象、函数或数据:

// JS
const car = {
  brand: 'Ford',
  model: 'Fiesta'
}

exports.car = car

// 或直接

// JS
exports.car = {
  brand: 'Ford',
  model: 'Fiesta'
}
// 在另一个文件中,则通过引用导入的属性来使用它:

// JS
const items = require('./items')
items.car

// 或

// JS
const car = require('./items').car

module.exports公开了它指向的对象; export 公开了它指向的对象的属性。

npm 

npm 是 Node.js 标准的软件包管理器。npm 可以管理项目依赖的下载。

安装所有依赖:npm install

安装单个软件包:npm install <package-name>

卸载包:运行 npm uninstall 命令,来卸载指定的包

可以指定包安装的位置:

  • 核心依赖包:--save 安装并添加条目到 package.json 文件的 dependencies。(在开发和项目上线之后都需要用到)
  • 开发依赖包:--save-dev 安装并添加条目到 package.json 文件的 devDependencies。(只在项目开发阶段会用到,在项目上线之后不会用到)简写: -D
  • -g 全局包,只有工具性质的包,才有全局安装的必要性。

更新软件包:npm update 会检查所有软件包是否有满足版本限制的更新版本。

列举当前目录下的安装包: npm list

获取最新版本的包:npm info 包名(详细信息)

检查包是否过时: npm outdated

全局安装:npm install 包名 -g

告知其在计算机上的确切位置: npm root -g 命令

在代码中使用它,则只需使用 require 将其导入到程序中

package.json 文件可以记录下载包的信息。

  • version 表明了当前的版本。
  • name 设置了应用程序/软件包的名称。
  • description 是应用程序/软件包的简短描述。
  • main 设置了应用程序的入口点。
  • private 如果设置为 true,则可以防止应用程序/软件包被意外地发布到 npm
  • scripts 定义了一组可以运行的 node 脚本。
  • dependencies 设置了作为依赖安装的 npm 软件包的列表。
  • devDependencies 设置了作为开发依赖安装的 npm 软件包的列表。
  • engines 设置了此软件包/应用程序在哪个版本的 Node.js 上运行。
  • browserslist 用于告知要支持哪些浏览器(及其版本)。

package.json 指南 (nodejs.cn)

 

 i5ting_toc 是一个可以把 md 文档转为 html 页面的小工具 :

 fs文件系统模块

fs.readFile()方法,用来读取指定文件中的内容。

//向其传入文件路径、编码(可选参数)、以及会带上文件数据(以及错误)进行调用的回调函数:

const fs = require('fs')

fs.readFile('/Users/joe/test.txt', 'utf8' , (err, data) => {
  if (err) {
// 读取成功err的值为null 读取失败err的值为错误对象,成功的数据为undefined
    console.error(err)
    return
  }
  console.log(data)
})

fs.writeFile()方法,用来向指定的文件中写入内容。

const fs = require('fs')

const content = '一些内容'

// 参数四个一个可选:一个文件路径的字符串,表示存放文件的路径;写入的内容;可选写入文件内容格式;文件写入完成后的回调函数。

fs.writeFile('/Users/joe/test.txt', content, err => {
  if (err) {
    console.error(err)
    return
  }
  //文件写入成功。
})

 fs.writeFile() 方法只能用来创建文件,不能用来创建路径

如果重复调用 fs.writeFile() 写入同一个文件,新写入的内容会覆盖之前的旧内容。

在使用fs模块之前需要先导入:require(导入的模块名)

const fs =require('fs')

文件路径中 __dirname表示当前文件所处的目录。

path模块是用来处理路径的模块,提供了一系列的方法和属性来满足对路径的处理需求。

如:path.join() 用来拼接一个完整的路径字符串。

使用前也需要先使用require导入。

../ 会抵消上一层的路径

路径拼接。 

获取路径中的文件名:

path.basename() 方法。可以获取路径中的最后一部分。

path.basename(path[,ext])
// path文件路径
// ext表示文件扩展名,返回时会删除文件扩展名
// 返回路径的最后一部分

 获取路径中的文件扩展名

path.extname(path) 传入一个路径的字符串,会返回一个扩展名字符串。

http模块

http 模块是用来创建 web 服务器的模块。
通过 http 模块提供的 http.createServer() 方法,就能方便的把一台普通的电脑,变成一台 Web 服务器,从而对外提供 Web 资源服务。(服务器和普通电脑的区别在于,服务器上安装了 web 服务器软件。)
使用http模块创建web服务器,也需要先导入const http =require('http')

IP 地址

IP 地址就是互联网上每台计算机的唯一地址,因此 IP 地址具有唯一性。
IP 地址的格式:通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d 都是 0~255 之间的十进制整数。例如:用点分十进表示的 IP地址(192.168.1.1)
注意:
① 互联网中每台 Web 服务器,都有自己的 IP 地址,例如:大家可以在 Windows 的终端中运行 ping www.baidu.com 命令,即可查看到百度服务器的 IP 地址。
② 在开发期间,自己的电脑既是一台服务器,也是一个客户端,为了方便测试,可以在自己的浏览器中输入 127.0.0.1 这个 IP 地址,就能把自己的电脑当做一台服务器进行访问了

域名和域名服务器

IP地址和域名是一一对应的关系,这份对应关系存放在一种叫做域名服务器(DNS,Domain name server)的电脑中。域名服务器就是提供 IP 地址和域名之间的转换服务的服务器。
注意:
① 单纯使用 IP 地址,互联网中的电脑也能够正常工作,但是有了域名更加方便。
② 在开发测试期间, 127.0.0.1 对应的域名是 localhost,代表我们自己的这台电脑。
每个web服务都有唯一的对应的端口号,默认是80端口,(可以省略)。每个端口号不能同时被多个web服务占用。

创建 web 服务器的基本步骤

① 导入 http 模块
const http =require('http')
② 调用 http.createServer() 方法,创建 web 服务器实例,使用server 接收创建的web服务器实例对象。
const server =http.createServer()
③ 为服务器实例绑定 request 事件,监听客户端的请求
// 使用服务器实例的.on方法,为服务器绑定一个request事件
server.on('request',(req,res) => {
    // 只要有客户端请求我们自己的服务器,就会触发request事件,从而调用这个事件处理函数
    console.log('Someone visit our web server.')
})

req 请求对象:在事件处理函数中,访问与客户端相关的数据或属性,可以:

server.on('request',(req) => {
// req是请求对象,包含了与客户端相关的数据和属性,url是客户端请求路径,method是客户端的请求类型。
    const str = `${req.url},${req.method}`
    console.log(str)
})
res 响应对象 :在服务器的 request 事件处理函数中,如果想访问与服务器相关的数据或属性,可以调用res.end()方法向客户端发送指定的内容。
server.on('request',(req,res) => {
// res是响应对象,包含了与服务器相关的数据和属性。
    const str = `${req.url},${req.method}`
// res.end()方法的作用就是向客户端发送指定的内容,并结束这次请求的处理过程。
    res.end(str)
})

④调用服务器实例的 .listen() 方法, 启动服务器,启动成功后就会调用第二个参数的方法。

// 调用server.listen(端口号,cb回调)方法,即可启动web服务器。
server.listen(80,()=>{
    console.log('http server running at http://127.0.0.1')
})

使用res.end()方法向客户端发送内容时会出现乱码情况,我们需要手动设计内容的编码格式:

 res.setHeader('Content-Type', 'text/html; charset=utf-8')

const http = require('http')
const server = http.createServer()

server.on('request', (req, res) => {
  // 定义一个字符串,包含中文的内容
  const str = `您请求的 URL 地址是 ${req.url},请求的 method 类型为 ${req.method}`
  // 调用 res.setHeader() 方法,设置 Content-Type 响应头,值为:'text/html; charset=utf-8' ,来解决中文乱码的问题
  res.setHeader('Content-Type', 'text/html; charset=utf-8')
  // res.end() 将内容响应给客户端
  res.end(str)
})

server.listen(80, () => {
  console.log('server running at http://127.0.0.1')
})

 动态响应内容

const http = require('http')
const server = http.createServer()

server.on('request', (req, res) => {
  // 1. 获取请求的 url 地址
  const url = req.url
  // 2. 设置默认的响应内容为 404 Not found
  let content = '<h1>404 Not found!</h1>'
  // 3. 判断用户请求的是否为 / 或 /index.html 首页
  // 4. 判断用户请求的是否为 /about.html 关于页面
  if (url === '/' || url === '/index.html') {
    content = '<h1>首页</h1>'
  } else if (url === '/about.html') {
    content = '<h1>关于页面</h1>'
  }
  // 5. 设置 Content-Type 响应头,防止中文乱码
  res.setHeader('Content-Type', 'text/html; charset=utf-8')
  // 6. 使用 res.end() 把内容响应给客户端
  res.end(content)
})

server.listen(80, () => {
  console.log('server running at http://127.0.0.1')
})

模块化

编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。 把代码进行模块化拆分的好处: 提高了代码的复用性 、提高了代码的可维护性 、可以实现按需加载。

模块化规范就是对代码进行模块化的拆分与组合时,需要遵守的那些规则。

模块化规范的好处:大家都遵守同样的模块化规范写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用。

Node.js 中根据模块来源的不同,将模块分为了 3 大类,分别是:  

  • 内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http 等)
  •  自定义模块(用户创建的每个 .js 文件,都是自定义模块)
  •  第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)

加载模块

使用 require() 方法,可以加载需要的内置模块、用户自定义模块、第三方模块进行使用。例如:

// 加载内置http模块
const http =require('http')

// 加载自定义模块
const custom = require('./custom.js')

 自定义模块的加载机制:

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

  • 按照确切的文件名进行加载
  • 补全 .js 扩展名进行加载
  • 补全 .json 扩展名进行加载
  • 补全 .node 扩展名进行加载
  • 加载失败,终端报错 

第三方模块的加载机制:

如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘../’ 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。

如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。

 模块作用域

在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。

模块作用域的好处:防止了全局变量污染的问题

向外共享模块作用域中的成员:module 对象/module.exports 对象

 module 对象,它里面存储了和当前模块有关的信息

在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。 外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。

注意:使用 require() 方法导入模块时,导入的就是 module.exports 指向的对象。(默认情况下,exports 和 module.exports 指向同一个对象。但最终共享的结果,还是以 module.exports 指向的对象为准。)

建议使用时只使用其中一个对象导出,以免混淆。

  CommonJS 模块化规范

CommonJS 规定了模块的特性和各模块之间如何相互依赖:

  1. 每个模块内部,module 变量代表当前模块。
  2. module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
  3. 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。

node入门文档 : Node.js 简介 (nodejs.cn)

学习:02.初识Node-什么是Node.js_哔哩哔哩_bilibili

 在了解node基础、npm与包的概率以及模块化之后我们就可以开发一个属于自己的包了!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白芸哆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值