npm内部机制与核心原理

server/2024/9/19 23:28:08/ 标签: 前端工程化

npm 的核心目标:
Bring the best of open source to you, your team and your company.
npm 最重要的任务是安装和维护开源库。

npm 安装机制与背后思想

npm 的安装机制非常值得探究。Ruby 的 Gem,Python 的 pip 都是全局安装机制,但是 npm 的安装机制秉承了不同的设计哲学。

它会优先安装依赖包到当前目录,使得不同应用项目的依赖各成体系,同时还能减轻包作者的 API 兼容性压力,但这样的缺陷也很明显:如果项目 A 和项目 B 都依赖的公共库 C,那么 C 一般会在项目A和项目B中各被安装一次。

当然,对于一些工具模块,比如 supervisor 和 gulp,仍然可以使用全局安装模式,这样方便注册 path 变量,利用我们在任何地方直接使用 supervisor、gulp 命令。不过,一般建议不同项目维护自己局部的 gulp 开发工具以适配不同的项目需求。

下面的流程图体现了 npm 的安装机制:
在这里插入图片描述构建依赖树时,当前依赖项目无论是直接依赖还是子依赖,我们都应该遵循扁平化原则优先将其放置在 node_modules 根目录下。在这个过程中,遇到相同模块应先判断已放置在依赖树中的模块版本是否符合对新模块版本的要求,如果符合就跳过,不符合则在当前模块的 node_modules 下放置该模块。

npm 缓存机制

对于一个依赖包的同一版本进行本地化缓存,这是当代依赖包管理工具的常见设计。使用时要先执行以下命令:

npm config get cache
// C:\Users\xxxxxx\AppData\Local\npm-cache

cd 命令进入缓存目录可以看到 _cacache 文件夹。在 npm v5 版本之后,缓存数据均放在根目录的 _cacache 中请添加图片描述
content-v2: 存放一些二进制文件。为了使这些二进制文件可读,将文件的扩展名改为 .tgz,然后进行解压,得到的结果其实就是npm包资源。
index-v5:存放一些描述性文件,事实上就是 content-v2 中文件的索引。
tmp:临时文件

这些缓存是如何被存储并利用的呢?

这就和 npm install机 制联系在一起了。当 npm install 执行时,会通过 pacote 将相应的包资源解压在对应的 node_modules 下面。npm 下载依赖时,会先将依赖下载到缓存中,再将其解压到项目的 node_modules 下。pacote 依赖 npm-registry-fetch 来下载包资源,npm-registry-fetch 可以通过设置 cache 属性在给定的路径下根据 IETF RFC 7234 生成缓存数据。

接着,在每次安装资源时,根据 package-lock.json 中存储的 integrity、version、name 信息生成一个唯一的 key,这个 key 能对应到 index-v5 下的缓存记录。如果发现有缓存资源,就会找到 tar 包的 hash 值,根据 hash 值找到缓存的包,并再次通过 pacote 将对应的二进制文件解压到相应的项目 node_modules 下,省去了网络下载资源的时间。

npm 不完全指南

自定义 npm init

npm 支持自定义 npm init,快速创建一个符合自己需求的自定义项目。npm init 命令本身并不复杂,它的功能其实就是调用Shell 脚本输出一个初始化的 package.json 文件。相应地,我们要自定义 npm init 命令,就是写一个 Node.js 脚本,它的 module.exports 即为 package.json 配置内容。

为了实现更加灵活的自定义功能,我们可以使用 prompt() 方法,获取用户输入内容:

const desc = prompt('请输入项目描述', '描述...')
module.exports = {key: 'value',name: prompt('name?', process.cwd().split('/').pop()),version: prompt('version?', '0.1.1'),description: desc,main: 'index.js',repository: prompt('github repository url', '', function() {if (url) {run('touch README.md');run('git init');run('git add README.md');run('git commit -m "first commit"');run(`git remote add origin ${url}`);run('git push -u origin master');}return url})
}

假设该脚本名为 .npm-init.js,执行以下命令来确保 npm init 所对应的脚本指向正确的文件

npm config set init-module ~\.npm-init.js

我们也可以通过配置 npm init 默认字段来自定义 npm init 内容:

npm config set init.author.name "Lucas"
npm config set init.author.email "xxx.com"
npm config set init.author.url "xxx.com"
npm config set init.license "MIT"
npx 的作用

npx 在 npm v5.2 版本中被引入,解决了使用 npm 时面临的快速开发、调试,以及在项目内使用全局模块的痛点。

在传统 npm 模式下,如果需要使用代码检测工具 ESLint,就要先进行安装,命令如下:

npm install eslint --save-dev

然后在项目根目录下执行命令,或通过项目脚本和 package.json 的 npm scripts 字段调用 ESLint。

./node_modules/.bin/eslint --init
./node_modules/.bin/eslint yourfile.js

而使用 npx 就简单多了:

npx eslint --init
npx eslint yourfile.js

npx 可以直接运行 node_modules/.bin 文件夹下的文件。npx 可以自动去 node_modules/.bin 路径和环境变量 $PATH 里面检查命令是否存在,而不需要再在 package.json 中定义相关的 script。

npx 另一个更实用的特点是,它在执行模块时会优先安装依赖,但是在安装成功后便删除此依赖,避免了全局安装带来的问题。

npm 多源镜像和企业级部署私服原理

npm 中的源(regsitry) 其实就是一个查询服务。我们可以通过 npm config 命令来设置安装源或某个作用范围域对应的安装源,很多企业也会搭建自己的 npm 源。我们可以通过 npm-preinstall 的钩子和 npm 脚本,在安装公共依赖前自动切换源。

"scripts": {"preinstall": "node ./bin/preinstall.js"
}
// 其中 preinstall.js 脚本的逻辑是通过 Node.js 执行 npm config set 命令
require(' child_process').exec('npm config get registry', function(error, stout, stderr) {if (!stdout.toString().match(/registry\.x\/com/)) {exec('npm config set @xscope:registry https://xxx.com/npm/')}
})

http://www.ppmy.cn/server/8727.html

相关文章

Kali Linux如何开启ssh远程连接服务

在Kali Linux中开启SSH服务,可以按照以下步骤进行操作: 切换到管理员用户:在终端中输入su root,然后输入root用户的密码以切换到root用户。这是因为修改SSH服务的配置文件通常需要管理员权限。 安装SSH服务器:如果尚未…

Python零基础从小白打怪升级中~~~~~~~TCP网络编程

TCP网络编程 一、什么是TCP协议 TCP( Transmission control protocol )即传输控制协议,是一种面向连接、可靠的数据传输协议,它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接 :数据传输之前客户端和…

骑砍2霸主MOD开发(4)-游戏场景(scene)制作

一.MapScene和MissionScene MapScene:进入游戏首次加载的RTS视角大地图场景对应scene_name为Main_map,引擎固定加载SandBox/SceneObj/Main_map. MissionScene:进入酒馆,野外战斗等第三人称游戏场景 二.游戏场景(scene.xscene) 1.Terrain地形 <1.layers:纹理layer增量 <2…

c#创建安装windows服务

在C#中创建并安装Windows服务&#xff0c;通常需要以下几个步骤&#xff1a; 创建Windows服务项目编写服务逻辑编译服务项目安装服务启动和停止服务 下面是一个简单的步骤指南&#xff1a; 步骤 1: 创建Windows服务项目 在Visual Studio中&#xff0c;创建一个新的Windows服…

JVM虚拟机(十二)ParallelGC、CMS、G1垃圾收集器的 GC 日志解析

目录 一、如何开启 GC 日志&#xff1f;二、GC 日志分析2.1 PSPO 日志分析2.2 ParNewCMS 日志分析2.3 G1 日志分析 三、GC 发生的原因3.1 Allocation Failure&#xff1a;新生代空间不足&#xff0c;触发 Minor GC3.2 Metadata GC Threshold&#xff1a;元数据&#xff08;方法…

K8S调度下的ingress-controller集群的实现以及nginx配置

# 22、K8S调度下的ingress-controller集群的实现以及nginx配置 目标&#xff1a; 1. 实现ingress-controller的集群部署 实现方法&#xff1a; 1. 为ingress-controller 规划两个节点 2.将这两个节点 打上自定义的 label 3.修改yaml文件&#xff0c;并重新创建 ingress-co…

VMware 15 虚拟机网络遇到的问题

剧情提要 通过Cent os7 的镜像文件&#xff0c;创建了一个虚拟机A&#xff08;后面简称A&#xff09;&#xff0c;事后发现&#xff0c;宿主机无法ping通A 在虚拟机中通过IP a 看到的IP信息也没有只管的ip信息如图 然后执行&#xff0c;宿主机才能访问A。 sudo dhclient ens…

逻辑自洽地区分【左值与右值】

前言 由于不同的文章和书籍&#xff0c;对左值和右值的区分皆有不同&#xff0c;这里我只是给自己定了一个逻辑可以自洽的标准&#xff0c;供自己去区分左值和右值&#xff0c;所以本篇博客&#xff0c;属于一个笔记。 C primer对左值和右值的介绍 C中的表达式&#xff1a;要么…

Windows使用freeSSHd搭建sftp服务器

一、安装 1、运行freeSSHd.exe&#xff08;最好以管理员方式运行&#xff09; 2、选择安装位置 3、选择全部安装 4、是否创建开始启动栏快捷入口 5、是否创建桌面快捷方式 6、安装 7、安装完成&#xff0c;点击close 8、安装私钥 9、是否要安装为服务 10、全部安装完成 二、配…

如何进行JVM的调优

进行Java虚拟机&#xff08;JVM&#xff09;的调优是一项关键的工作&#xff0c;旨在优化JVM的性能&#xff0c;提高应用程序的响应速度和吞吐量&#xff0c;并确保系统的稳定运行。JVM调优通常涉及到调整堆大小、选择合适的垃圾收集器、监控运行时性能以及分析内存泄漏等方面。…

【MongoDB】数据的自动过期,TTL索引

文章目录 1. 前言2.概念与使用2.1.使用方式2.2.数组中包含日期字段2.3.设置具体的过期时间点2.4.额外的过滤条件 3.总结 1. 前言 在近期的工作中&#xff0c;使用了MongoDB来保存了一些日志数据&#xff0c;但是这些日志数据具有一定的时效性&#xff0c;也就是按照业务的需要…

上传文件到HDFS

1.创建文件夹 hdfs -dfs -mkdir -p /opt/mydoc 2.查看创建的文件夹 hdfs -dfs -ls /opt 注意改文件夹是创建在hdfs中的&#xff0c;不是本地&#xff0c;查看本地/opt&#xff0c;并没有该文件夹。 3.上传文件 hdfs dfs -put -f file:///usr/local/testspark.txt hdfs://m…

Linux基本命令之正则表达式(转义字符)

一&#xff1a;查看二进制文件 strings 命令&#xff1a;strings 文件名 生成链接文件 ln 命令&#xff1a;ln 选项 源文件(f1) 链接文件&#xff08;f2&#xff09; 软连接&#xff1a;eg:ln -s f1 f2 软链接不能跨分区链接&#xff0c;但可以在同一分区的不同目录下链接…

算法课程笔记——全排列

要最小 ventor用endl 递归方式#include <cstdio>#include <iostream>#include <algorithm>#include <string>using namespace std;const int MAXN 10;bool visit[MAXN];//判断某个元素是否被访问过char sequence[MAXN];//存放找到的全排列void GetPer…

文献速递:深度学习肝脏肿瘤诊断---基于深度学习的肝细胞结节性病变在整片组织病理图像上的分类

Title 题目 Deep Learning-Based Classification of Hepatocellular Nodular Lesions on Whole-Slide Histopathologic Images 基于深度学习的肝细胞结节性病变在整片组织病理图像上的分类 Background 背景 Hepatocellular nodular lesions (HNLs) constitute a heterogen…

c语言中,数组取地址的书写格式

数组取地址 为了更好的区分数组取地址时的情况&#xff0c;我们建立两个数组&#xff0c;arr1一维数组和arr2二维数组&#xff0c;用printf函数来打印出每个例子arr1和arr2的地址&#xff0c;这样可以更加直观的区分出来。 首先我们看到第一组打印&#xff0c;可以看到若是直接…

c可变参数简单实验

1.概要 print_numbers(int count, ...)va_list ap;va_start(ap, count);int number va_arg(ap, int);va_end(ap); 2.代码 #include <iostream> #include <stdarg.h>void print_numbers(int count, ...) {va_list ap;int i;va_start(ap, count);for (i 0; i &l…

14:00面试,14:07就出来了,问的问题有点变态。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 从小厂出来&#xff0c;没想到在另一家公司又寄了。 到…

Ceph 分布式文件系统 搭建及使用

一、Ceph 介绍 在当今数据爆炸式增长的时代&#xff0c;企业对于可靠、可扩展的存储解决方案的需求日益迫切。Ceph 作为一种开源的、可伸缩的分布式存储解决方案&#xff0c;正逐渐成为企业级存储领域的热门选择。Ceph是一种由Radicalbit公司开发的开源分布式存储系统&#xf…

汇编语言实验11

汇编语言实验11 assume cs:code,ds:datadata segmentdb "Beginners All-purpose Symbolic Instruchtion Code.",0 data endscode segment ;代码段start: mov ax,datamov ds,axmov si,0call lettersmov ax,4c00hint 21hletters:mov cx,0mov cl,byte ptr [si] ; 如果…