理解npm中的包和模块

在 npm 的上下文中,包(package) 和 ****模块(module) 经常被交替使用,我们往往把这两者混为一谈用,但实际上它们有一些细微的区别。

本文就来详细的说下 npm 中包和模块的区别,以此来更好的理解 npm 生态。

在官方文档中,对于包的介绍由这样两段话:

公共 npm 注册表是 JavaScript 包的数据库,每个包都由软件和元数据组成。

包是由 package.json 文件描述的文件或目录。包必须包含 package.json 文件才能发布到 npm 注册表。

听起来有点抽象,因为有几个抽象的概念,一是npm 注册表,二是元数据,关于 npm 注册表的理解可以看我之前的文章真正理解 npm:从注册表到 JavaScript 包管理平台,看完就能明白,所谓"公共 npm 注册表是 JavaScript 包的数据库"意思就是,npm 的云端数据库是一个存储JavaScript 包的数据库。

那么问题来了,什么是包?他和我们常说的模块又有什么区别?

在理解包之前,我们需要先对我们平时说的模块有一个清晰的定义和了解:

什么是模块(module)

模块 是指 Node.js 或 JavaScript 中独立的代码单元 , 封装了某些功能或逻辑,可以被引入到其他地方使用, 用来进行代码复用和维护。

模块的特点:

  • 模块通常由一个或多个 JavaScript 文件组成。
  • 模块是用 require(CommonJS)或 import(ES Module)语法引入的。
  • 模块是更底层的概念,代表代码逻辑的封装
  • 在 Node.js 中,每个 .js 文件都是一个模块。

例子

js 复制代码
// 一个简单的模块
module.exports = {
  greet: function (name) {
    return `Hello, ${name}!`;
  },
};

理解了模块我们再说什么是元数据

什么是元数据

对于元数据的理解关于在于字,在我看来元就是基础、基本的意思,所谓元数据就是基础数据,基本数据。

元数据是一个抽象的概念,它的作用是对一个实际物体所拥有的特性用一些关键词来描述,在编程领域,我们把实际的物体抽象为对象,把物体所拥有的特性,用对象所拥有的属性来描述。所以元数据,就类似于对象的属性,只不过它描述的不是对象的属性,而是模块的属性。

对于人这个对象来说,我们会用身高体重性别来描述这个人,这就是人的属性,也是人的元数据。

那么对于模块(一个代码单元)来说,同样有一些信息来描述这个模块,比如说它的名称、版本号、功能,依赖的模块,这些都是模块的属性,也是模块的元数据。

也就是说,所谓元数据就是对实际物质的抽象描述,而对于模块而言,其元数据的实体表示就是通过package.json文件来具体实现。

总的来说:元数据是对模块及其相关内容的描述,存储在 package.json 文件中。

元数据的特点

  • 描述模块的名称、版本号、作者、依赖关系等信息。
  • 告诉 npm 或其他工具如何处理该模块(如安装、运行)。

一个最简单的元数据(package.json)例子

json 复制代码
{
  "name": "fengdu-utils",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

什么是包

理解了模块和元数据后,我们再来看包。

包同样是一个抽象的概念,它是 npm 提出来的,它指的是符合 npm 注册表(数据库)规范的文件或目录,只有符合这个规范,才能发布到 npm 平台上。

而所谓的规范,就是符合 npm 所制定的元数据定义规则。

包的特点

  • 一个包就是一个符合 npm 规范的代码分发单元。
  • 包必须包含一个package.json文件,该文件描述了包的元数据(如名称、版本、依赖项等)。
  • 包可以是:
    • 文件:一个函数或模块(例如 lodash)。
    • 目录:一个完整的应用程序或工具(例如 create-react-app)。

例子:

  • 一个包可能包含:
    • index.js(主模块代码)。
    • lib/(其他模块或文件夹)。
    • package.json(描述信息)。
    • README.md(使用说明)。

包和模块的关系

  1. 包包含模块 :一个 npm 包通常包含多个模块。例如,一个包可能有一个主模块和多个辅助模块,每一个模块都是单独的js文件,所有这些都封装在包中。
  2. 模块是更基础的概念 :模块是代码的逻辑单元 ,而包是包含这些模块的分发单元。

区别总结

特性 包(Package) 模块(Module)
定义 用于分发的软件单元,包含代码和元数据 程序中独立的代码逻辑单元
作用 提供代码共享和管理(通过 npm 发布/下载) 封装功能逻辑,供程序导入和使用
范围 包含模块及其元信息(例如 package.json文件) 具体的代码实现,通常是 JavaScript 文件
依赖性 包可以包含多个模块或文件 模块可以是包的一部分,也可以独立存在
示例 express(一个 npm 包,包含多个模块) math.js(一个单独的模块文件)

简单比喻

如果用书籍做比喻:

  • 模块是书的内容,具体的章节和段落(比如一个函数或功能)。
  • 元信息是书的封面、目录和简介(比如书名、作者信息)。
  • 就是完整的一本书(既包含内容,又有封面和目录)。

因此,你可以理解为:

  • 模块是"实际的功能实现",是代码本体;
  • 元信息是对模块的"描述";
  • 包是这两者的结合,用来方便分发和管理。

总结

在 npm 中,包是一个更高层的概念,它是模块的载体,用于分发和管理代码。模块则是更基础的代码单元,专注于提供功能逻辑。

总的来所,包= 模块(代码、软件)+元数据(package.json),或者说由代码文件和package.json文件组成的一个目录(文件夹)就是一个 npm 包。

相关推荐
web135085886359 分钟前
前端node.js
前端·node.js·vim
m0_5127446410 分钟前
极客大挑战2024-web-wp(详细)
android·前端
潜意识起点34 分钟前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛38 分钟前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿1 小时前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256563 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@3 小时前
HTML5适配手机
前端·html·html5
@解忧杂货铺5 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
F-2H6 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
gqkmiss7 小时前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件