二、Node.js---模块化

2023-11-15

目录

模块化的基本概念

Node.js中模块化

Node.js 中模块的分类

加载模块

Node.js 中的模块作用域

模块作用域

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

Node.js 中的模块化规范

npm与包

在项目中安装包

包的语义化版本规范

包管理配置文件

1.如何记录项目中安装了哪些包

2.快速创建 package.json

3.dependencies节点

4.一次性安装所有的包

5.卸载包

6.devDependencies节点

解决下包速度慢的问题

切换npm 的下包镜像源

包的分类

项目包

全局包

i5ting_toc

规范的包结构

开发自己的包并发布

模块的加载机制

优先从缓存中加载

内置模块的加载机制

自定义模块的加载机制

第三方模块的加载机制

目录作为模块


模块化的基本概念

模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。

Node.js中模块化

Node.js 中模块的分类

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

  1. 内置模块(内置模块是由Node.js官方提供的,例如fs、path、http等)

  2. 自定义模块(用户创建的每个.js文件,都是自定义模块)

  3. 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)

加载模块

  //1.加载内置的fs模块
  const fs = require('fs')
  //2.加载用户自定义模块
  const custom = require('./custom.js')
  //3.加载第三方模块
  const moment = require('moment')
  //使用require()方法加载模块时,会执行被加载模块的代码

Node.js 中的模块作用域

模块作用域

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

 

我们在08模块中我们定义了一个username和函数sayHello,在09中加载了08模块,并在终端中执行09,可以看到的是在执行后我们并不能访问到08中的成员,只是给我们打印出一个空对象{},而这个空对象就是自定义模板中的module.exports{}

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

1.module对象

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

 

在module对象中exports的属性值默认为一个空对象

2.module.exports 对象

在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用。

外界用require() 方法导入自定义模块时,得到的就是module.exports所指向的对象。

使用require()方法导入模块时,导入的结果,永远以 module.exports 指向的对象为准

 

Node.js 中的模块化规范

Node.js遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之间如何相互依赖。

CommonJS规定:

​         ①每个模块内部,module 变量代表当前模块。

        ​ ②module 变量是一个对象,它的exports属性(即module.exports)是对外的接口。

​         ③加载某个模块,其实是加载该模块的 module.exports属性。require() 方法用于加载模块。

npm与包

Node.js中的第三方模块又叫做包。

由于Node.js的内置模块仅提供了一些底层的API,导致在基于内置模块进行项目开发的时,效率很低。

包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率。

包和内置模块之间的关系,类似于jQuery和浏览器内置 API 之间的关系。

npm 网站上搜索自己所需要的包

https://registry.npmjs.org/ 服务器上下载自己需要的包

在项目中安装包

  npm install 包的名称
  //简写:   npm i 包的名称

安装格式化时间的包,并调用这个包对时间进行格式化输出

 

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

其中:

node_modules 文件夹用来存放所有已安装到项目中的包。require()导入第三方包时,就是从这个目录中查找并加载包。

package-lock.json 配置文件用来记录 node_modules 目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。

默认情况下,使用npm install 命令安装包的时候,会自动安装最新版本的包。如果需要安装指定版本的包,可以在包名之后,通过 @ 符号指定具体的版本,例如:

  npm i moment@2.22.2

包的语义化版本规范

包的版本号是以“点分十进制”形式进行定义的,总共有三位数字,例如2.24.0

其中每一位数字所代表的的含义如下:

第1位数字:大版本

第2位数字:功能版本

第3位数字:Bug修复版本

版本号提升的规则:只要前面的版本号增长了,则后面的版本号归零。

包管理配置文件

npm规定,在项目根目录中,必须提供一个叫做package.json 的包管理配置文件。用来记录与项目有关的一些配置信息。例如:

  1. 项目的名称、版本号、描述等

  2. 项目中都用到了哪些包

  3. 哪些包只在开发期间会用到

  4. 那些包在开发和部署时都需要用到

当我们多人协作制作项目时,第三方包的体积过大,不方便团队成员之间共享项目源代码,可以在共享时剔除node_modules

1.如何记录项目中安装了哪些包

在项目根目录中,创建一个叫做 package.json 的配置文件,即可用来记录项目中安装了哪些包。从而方便剔除node_modules目录之后,在团队成员之间共享项目的源代码。

2.快速创建 package.json

现在在我们下载包的时候会自动帮我们创建好这个文件,不用手动创建了

npm包管理工具提供了一个快捷命令,可以在执行命令时所处的目录中,快速创建 package.json这个包管理配置文件:

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

​ ①上述命令只能在英文的目录下成功运行!所以,项目文件夹的名称一定要使用英文命名,不要使用中文,不能出现空格。

​ ②运行 npminstall 命令安装包的时候,npm 包管理工具会自动把包的名称和版本号,记录到 package.json 中。

3.dependencies节点

package.json文件中,有一个dependencies节点,专门用来记录您使用npm install 命令安装了哪些包。

4.一次性安装所有的包

当我们拿到一个剔除了 node_modules 的项目之后,需要先把所有的包下载到项目中,才能将项目运行起来。否则报错:

  Error:Cannot find module 'moment'

可以运行 npm install 命令(或 npm i)一次性安装所有的依赖包:

  //执行npm install 命令时,npm包管理工具会先读取package.json中的dependencise节点
  //读取到记录的所有依赖包名称和版本号之后,npm包管理工具会把这些包一次性下载到项目中
  npm install

5.卸载包

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

  // npm uninstall 具体包名
  npm uninstall moment

npm uninstall 命令执行成功后,会把卸载的包,自动从package.json的 dependencies中移除掉

6.devDependencies节点

如果某些包只在项目开发阶段会用到,在项目上线之后不会用到,则建议把这些包记录到 devDependencies节点中。与之对应的,如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到dependencies节点中。

您可以使用如下的命令,将包记录到 devDependencies节点中

  //安装指定的包,并记录到devDependencies节点中
  npm i 包名 -D
  //上面是简写,下面是完整写法
  npm install 包名 --sava-dav

解决下包速度慢的问题

在使用npm下包的时候,默认从国外的https://registry.npmjs.org/服务器进行下载,此时,网络数据的传输需要经过漫长的海底光缆,因此下包速度会很慢。

切换npm 的下包镜像源

  //查看当前下包镜像源(下包的镜像源,指的就是下包的服务器地址)
  npm config get registry
  //查看所有可用的镜像源
  nrm ls
  //将下包镜像源切换为 taobao 镜像
  nrm use taobao

 

包的分类

项目包

那些被安装到项目的 node_modules目录中的包,都是项目包。

项目包又分为两类,分别是:

​ 开发依赖包(被记录到 devDependencies 节点中的包,只在开发期间会用到)

​ 核心依赖包(被记录到 dependencies 节点中的包,在开发期间和项目上线之后都会用到)

  npm i 包名 -D         //开发依赖包(会被记录到 DevDependencies 节点下)
  npm i 包名            //核心依赖包(会被记录到 dependencies 节点下)

全局包

在执行 npm install 命令时,如果提供了 -g 参数,则会把包安装为全局包。

全局包会被安装到 C:\Users\用户目录\AppData\Roaming\npm\node_modules 目录下。

  npm i 包名 -g             //  全局安装指定的包
  npm uninstall 包名 -g      //  卸载全局安装的包

注意:

​ ①只有工具性质的包,才有全局安装的必要性。因为它们提供了好用的终端命令。

​ ②判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明即可。

i5ting_toc

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

  //  将 i5ting_toc 安装为全局包
  npm install -g i5ting_toc
  //  调用 i5ting_toc 实现md转html的功能
  i5ting_toc -f 要转换的md文件路径 -o

规范的包结构

一个规范的包,它的组成结构,必须符合以下3点要求:

​ ①包必须以单独的目录而存在

​ ②包的顶级目录下要必须包含 package.json 这个包管理配置文件

​ ③package.json 中必须包含name,version,main这三个属性,分别代表包的名字、版本号、包的入口。

开发自己的包并发布

黑马node.js公开课有详细说明04.发布包-初始化基础的包结构_哔哩哔哩_bilibili

模块的加载机制

优先从缓存中加载

模块在第一次加载后会被缓存。 这也意味着多次调用 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: Cannotfind module 'xxx'

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二、Node.js---模块化 的相关文章

  • Firebase 模拟器无法促进/运行新功能

    我有三个云功能 其中两个已部署到我的 firebase 项目中 其中一个是我刚刚添加的 我希望在部署之前在本地测试新的功能 但是当我尝试使用它时却无法使用 并且只有两个已部署的功能可用 Firebase 模拟器在端口上运行良好5001 像往
  • JavaScript 中的可选参数

    如果缺少剩余参数 为什么该函数不会抛出错误 showStatistics Mark Teixeira New York Yankees 1st Base 这是定义的函数 function showStatistics name team p
  • 谷歌应用程序引擎nodejs本地开发

    有没有办法在本地运行我的nodejs应用程序 以便我可以模拟在生产App Engine中运行的应用程序而无需部署它 由于某种原因 我的应用程序在 Google App Engine 中的行为与我的本地主机不同 我厌倦了每次为了查看是否存在错
  • ELEMENT.style.color 在 IE 中不起作用

    在一个小型 Web 应用程序中 我使用 JavaScript 在文本框中设置一些文本及其颜色 在下面的片段中 el 是我的对象 这段代码在 Firefox Opera 和 Safari 下产生了正确的效果 但在 IE 下却没有这样的运气 我
  • 匹配 JavaScript RegEx 中的不可见字符

    我有一些包含不可见字符的字符串 但它们位于可预测的位置 通常 围绕我想要提取的文本片段 然后在第二次出现之后我想保留文本的其余部分 我似乎不知道如何关闭隐形字符 and将它们从我的结果中排除 为了匹配隐形 我一直在使用这个正则表达式 xA0
  • 如何设置黄瓜环境变量

    我有以下 package json name newcucumber version 1 0 0 main index js scripts test node modules bin cucumber js firefox node mo
  • 传单圆圈绘制/编辑问题

    我第一次制作传单 并面临绘制圆圈和编辑 更改圆圈位置 的问题 我面临的问题是 编辑 移动 圆从一个位置到另一位置会改变其半径 Note 请尝试在给定的小提琴中在地图顶部创建圆圈 然后通过单击编辑按钮将其移动到底部 如果我在地图的顶部创建圆圈
  • 递归链接 Promise

    我正在开发一个简单的 Windows 8 应用程序 我需要在其中从网站获取一组数据 我正在使用 WinJS xhr 来检索此数据 它返回一个 Promise 然后 我将回调传递到此 Promise 的 then 方法中 该方法为我的回调提供
  • Node.js 循环发送 http 请求

    我实际上遇到了使用 node js 执行的 javascript 代码的问题 我需要循环发送http请求到远程服务器 我在代码中设置了www google ca 这是我的代码 var http require http var option
  • JavaScript - 类根据条件扩展

    事情是这样的 我有一个名为 A 的主课 我希望这个班级能够扩展 B 级 class A extends B 但事实上 我希望 B 类在特定条件下扩展 C D 或 E class B extends B1 or class B extends
  • 如何比较两个对象数组并更改两个数组中找到的对象的值?

    假设我有两个对象数组 let array1 id 1 name snow id 4 name jo id 8 name bran id 12 name gondo id 13 name peter
  • 在express中root后通过可选参数传递路由控制?

    我正在开发一个简单的网址缩短应用程序 并有以下快速路线 app get function req res res render index link null app post function req res function makeR
  • 字符串化 JavaScript 对象

    我正在寻找字符串化一个对象 我想要这样的输出 1 valeur dalebrun usager experttasp date 2013 08 20 16 41 50 2 valeur test usager experttasp date
  • 有没有办法显示嵌套在 Grid 组件内的 Material-UI 抽屉?

    我正在使用 Material UI 创建一个 Web 应用程序 主页分为 3 个网格 每个网格有一个height of 500px 我想在中间网格内显示一个带有一些操作选项的抽屉 那可能吗 到目前为止 我只能在整个屏幕上显示它 这是我的主要
  • 使用 jquery 时出现控制台错误 - Uncaught TypeError: Object # has no method

    我尝试使用以下 js 添加类或 css 样式 但出现控制台错误 var i 0 question i addClass show 收到以下控制台日志错误 Uncaught TypeError Object has no method add
  • 通过ajax POST提交两次表单

    插入到mysql using php通过文件调用AJAX 前insert语句php代码执行select查询到查找重复记录并继续insert statement Issue 从ajax调用php文件时 它执行了两次并得到作为重复记录的响应 好
  • 谷歌浏览器不显示一个网站的alert()弹出窗口

    我正在开发一个 javascript 循环 该循环会随着循环的进行而提醒每个键值 为了加快速度 我选中了 阻止此页面创建其他对话框 框 通常这只会抑制一个例程的弹出窗口 但它们还没有回来 在 Google Chrome 中 alert 消息
  • 关于 Node.js Promise then 和 return?

    我对承诺感到困惑 I use 那么就答应没有返回像这样 new Promise resolve reject gt resolve 1 then v1 gt console log v1 new Promise resolve reject
  • 当 mp4 是唯一来源时,自定义 HTML5 视频控件不起作用

    问题 我只有一个视频源 mp4 因为我正在尝试向 tumblr 视频添加自定义控件 如果只有mp4作为源video duration返回为NaN 作为使用 3 个源 mp4 webm ogg 时的测试 它可以工作 所以video durat
  • angularjs 将 ngModel 从包装器指令传递到包装器指令

    我是 Angular 的新手 但仍然痛苦地纠结于自定义指令 我想重用这段 HTML

随机推荐

  • mysql中geometry类型的简单使用(搜索附近的人)

    mysql中geometry类型的简单使用 编写本文的目的 让和两天前的我一样的初学者 能够更快的使用geometry类型存储空间点数据 也是为了自己加深印象 更熟练的使用geometry类型 建表脚本 CREATE TABLE z gis
  • 微信小程序云开发教程一

    微信小程序云开发 初学者入门教程一 云开发环境搭建 本教程适合刚刚入门的小白 云开发为开发者提供完整的云端支持 弱化后端和运维概念 无需搭建服务器 使用平台提供的 API 进行核心业务开发 即可实现快速上线和迭代 同时这一能力 同开发者已经
  • Pandas数据分析初学--开始了解数据

    探索Chipotle快餐数据 作为一个Pandas初学者 今天用这道题目练手 分享出来 首先 impotr pandas as pd 1 将数据集存入一个名为chipo的数据框内 iris filename chipotle csv chi
  • SkyWalking链路追踪中Trace概念以及Trace与span的关系

    基本概念 在SkyWalking链路追踪中 Trace 追踪 是指一个请求或者一个操作从开始到结束的完整路径 它涵盖了分布式系统中所有相关组件的调用关系和性能信息 具体来说 Trace包含了一系列的span 跨度 每个span代表了一个组件
  • kibana使用_从kibana迁移到grafana作为elasticsearch的展现

    今天说说 我们为什么会选择从kibana迁移到grafana 并选用grafana作为elasticsearch的图表展现工具 文章中关于kinaba和grafana的对比会有些片面 勿喷 最一开始使用kibana ElasticSearc
  • java 正则表达式_a-z_0-9 validation,掌握Java-Bean Validation

    数据校验虽然简单 但是却是一个繁琐的事 我在无数的代码看到if判断参数 然后错了打日志抛异常 一片一片的这种代码 如果有点重复了 再弄出N个xxUtil来归纳代码 虽然这种做法可以达到效果 但是代码散乱 一个是编写麻烦 一个是不易阅读 Ja
  • Pyqt5设计打开电脑摄像头+拍照(转载)

    本片为利用Pyqt5设计一个可以打开摄像头进行拍照的Demo 我感觉以后可能会有用 记录一下 Demo运行视频 哈哈感觉很好玩 用到的模块安装 库 安装 作用 PyQt5 pip install PyQt5 界面设计 opencv pyth
  • [网络安全自学篇] 三十五.恶意代码攻击检测及恶意样本分析

    本文主要结合作者的 系统安全前沿 作业 论文及绿盟李东宏老师的博客 从产业界和学术界分别详细讲解恶意代码攻击溯源的相关知识 在学术界方面 用类似于综述来介绍攻击追踪溯源的不同方法 在产业界方面 主要参考李东宏老师从企业恶意样本分析的角度介绍
  • 单调递增队列(全过程图文实现 另附习题)

    什么是单调队列 有什么用 不妨用一个问题来说明单调队列的作用和操作 不断地向缓存数组里读入元素 也不时地去掉最老的元素 不定期的询问当前缓存数组里的最小的元素 最直接的方法 普通队列实现缓存数组 进队出队都是O 1 一次查询需要遍历当前队列
  • 手把手教你如何 远程控制另一台电脑 保姆教程

    现在win10可以实现两台电脑之间的远程控制 下面我就分享一下如何利用快速助手进行远程控制另一台电脑 每一步都有截图 实验环境 两台win10系统的电脑 一 打开电脑后 需要设置允许电脑进行远程控制 进入 控制面板 系统和安全 系统 远程控
  • python文件操作图形化——python实战项目:单词练习系统

    python 文件操作与图形化编程 目录 python 文件操作与图形化编程 文件基本操作 图形化界面tkinter 单词练习系统 文件基本操作 D Python example txt 文件路径 D Python 文件名 example
  • 并行计算出现 pickle.PicklingError

    from multiprocessing import Pool def my function x return x x if name main inputs 1 2 3 4 5 with Pool 2 as p results p m
  • Unity面试题

    Unity基础面试题 1 什么是协同程序 2 Unity3D中碰撞器和触发器的区别 3 物体发生碰撞的必要条件 4 ArrayList和list的区别 5 如何安全的在不同工程间迁移Asset 6 OnEnable Awake Start的
  • Dubbo高级应用-服务治理

    目录 1 dubbo admin 2 7 x版本安装部署 1 1 下载源码 1 2 部署访问 2 路由规则 2 1 Dubbo API配置 2 2 管理控制台配置 3 规则动态配置 3 1 应用粒度 3 2 服务粒度 4 服务降级 5 集群
  • 集成 CUDA 实现 GPU 加速 OpenCV 计算机视觉

    特点 详细概述了将 OpenCV 与 CUDA 集成以用于实际应用 理解GPU与CUDA编程 通过一些实际示例 探索使用GPU和CUDA的OpenCV加速 熟悉在 NVIDIA Jetson TX1 上部署 OpenCV 应用程序 介绍了
  • python 类装饰器和函数装饰器区别_Python各种类型装饰器详解说明

    装饰器说明 Python中的装饰器是一种可以装饰其它对象的工具 该工具本质上是一个可调用的对象 callable 所以装饰器一般可以由函数 类来实现 装饰器本身需要接受一个被装饰的对象作为参数 该参数通常为函数 方法 类等对象 装饰器需要返
  • -day15--内置模块与开发规范

    day15 内置模块和开发规范 目标 掌握常见的内置模块的使用及了解软件开发的规范 今日概要 内置模块 json time datetime re 开发规范 主文件 配置文件 数据 附件 业务代码 1 内置模块 1 1 json json模
  • Win10+mingw64条件下编译和使用TBB(环境变量太神奇了!)

    Win10 mingw64 VSCode条件下编译和使用TBB Win10 mingw64条件下编译和使用TBB 编译TBB 环境变量的设置 TBB使用示例 总结与展望 Win10 mingw64条件下编译和使用TBB 本文记录在Win10
  • java中.xlsx或者.xls格式的Excel导入(servlet中处理的)

    1 第一步 在pom xml文件中添加maven依赖
  • 二、Node.js---模块化

    目录 模块化的基本概念 Node js中模块化 Node js 中模块的分类 加载模块 Node js 中的模块作用域 模块作用域 向外共享模块作用域中的成员 Node js 中的模块化规范 npm与包 在项目中安装包 包的语义化版本规范