- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章一篇带你了解npm的原理由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
npm据称成为世界最大的包管理器?原因真的只是用户友好?
用来初始化一个简单的package.json文件。package.json文件用来定义一个package的描述文件.
1、npm init的执行的默认行为 。
执行npm init --yes,全部使用默认的值.
2、 自定义npm init行为 。
npm init命令的原理是:调用脚本,输出一个初始化的package.json文件.
获取用户输入使用prompt()方法.
npm的核心功能:依赖管理。执行npm i从package.json中dependencies和devDependencies将依赖包安装到当前目录的node_modules文件夹中.
1、package定义 。
npm i 就可以安装一个包。通常package就是我们需要安装的包名,默认配置下npm会从默认的源(Registry)中查找该包名的对应的包地址,并且下载安装。 还可以是一个指向有效包名的http url/git url/文件夹路径.
package的准确定义,符合以下a)到g)其中一个条件,他就是一个package:
package的准确定义 。
2、安装本地包/远程git仓库包 。
共享依赖包,并非非要把包发布到npm源上才能使用.
(1)场景1:本地模块引用 。
开发中避免不了模块之间调用,开发中,我们把频繁调用的配置模块放在根目录,然后如果有很多层级目录,后来引用 。
这样的路径引用不利于代码重构。这时候我们需要考虑把这个模块分离出来供其他模块共享。比如config.js可以封装成一个package放到node_modules目录下.
不需要手动拷贝或者创建软连接到node_modules目录,npm 有自己的解决方案:
方案:
1、新增config文件夹,将config.js移入文件夹,名字修改为index.js,创建package.json定义config包 。
2、在项目的package.json新增依赖项,然后执行npm i.
查看 node_modules 目录我们会发现多出来一个名为 config,指向上层 config/ 文件夹的软链接。这是因为 npm 识别 file: 协议的url,得知这个包需要直接从文件系统中获取,会自动创建软链接到 node_modules 中,完成“安装”过程.
(2)场景2:私有git共享package 。
团队内会有一些代码/公用库需要在团队内不同项目间共享,但可能由于包含了敏感内容.
我们可以简单的将被依赖的包托管到私有的git仓库中,然后将git url保存到dependencies中。npm会直接调用系统的git命令从git仓库拉取包的内容到node_modules中.
npm支持的git url格式:
。
git 路径后可以使用 # 指定特定的 git branch/commit/tag, 也可以 #semver: 指定特定的 semver range. 。
比如:
(3)场景3:开源package问题修复 。
此时我们可以手动进入 node_modules 目录下修改相应的包内容,也许修改了一行代码就修复了问题。但是这种做法非常不明智.
方案:
fork原作者的git库,在自己的repo修复问题,然后将dependencies中的相应依赖改为自己修复后版本的git url就可以解决问题.
npm i执行完毕,node_modules中看到所有的依赖包。开发人员无关注node_modules文件夹的结构细节,关注业务代码中引用依赖包.
理解node_modules结构帮助我们更好理解npm如何工作。npm2到npm5变化和改进.
3.1 npm2 。
npm2在安装依赖包,采用的是简单的递归安装方法。每一个包都有自己的依赖包,每一个包的依赖都安装在自己的node_modules中,依赖关系层层递进,构成整个依赖树,这个依赖树与文件系统中的文件结构树一一对应.
最方便的依赖树的方式在根目录下执行npm ls.
优点:
层级结构明显,便于傻瓜式管理.
缺点:
复杂工程,目录结构可能太深,深层的文件路径过长触发window文件系统中文件路径不能超过260个字符长.
部分被多个包依赖的包在很多地方重复安装,造成大量的冗余.
3.2 npm3 。
npm3的node_modules目录改成更加扁平状层级结构。npm3在安装的时候遍历整个依赖树,计算最合理的文件夹安装方式,所有被重复依赖的包都可以去重安装.
npm来说,同名不同版本的包是两个独立的包.
npm3的依赖树结构不再与文件夹层级一一对应.
3.3 npm5 。
沿用npm3的扁平化依赖包安装方式。最大的变化时增加package-lock.json文件.
package-lock.json作用:锁定依赖安装结构,发现node_modules目录文件层级结构是与json的结构一一对应.
npm5默认会在执行npm i后生成package-lock.json文件,提交到git/svn代码库.
要升级,不要使用 5.0版本.
注意:在 npm 5.0 中,如果已有 package-lock 文件存在,若手动在 package.json 文件新增一条依赖,再执行 npm install, 新增的依赖并不会被安装到 node_modules 中, package-lock.json 也不会做相应的更新.
介绍依赖包升级管理相关知识.
4.1 语义化版本semver 。
npm依赖管理的一个重要特性采用语义化版本(semver)规范,作为版本管理方案.
语义化版本号必须包含三个数字,格式:major.minor.patch。意思是:主版本号.小版本号.修改版本号.
我们需要在dependencies中使用semver约定的指定所需依赖包的版本号或者范围.
常用的规则如下图:
semver语义化版本 。
1、任意两条规则,用空格连接起来,表示“与”逻辑,即为两个规则的交集.
如 >=2.3.1 <=2.8.0 可以解读为: >=2.3.1 且 <=2.8.0 。
2、任意两条规则,用||连接起来,表示“或”逻辑,即为两条规则的并集.
如 ^2 >=2.3.1 || ^3 >3.2 。
3、更直观的表示版本号范围的写法 。
4、在 MAJOR.MINOR.PATCH 后追加 - 后跟点号分隔的标签,作为预发布版本标签 通常被视为不稳定、不建议生产使用的版本.
4.2 依赖版本升级 。
在安装完一个依赖包之后有新的版本发布了,如何使用npm进行版本升级呢?
使用npm3的结论:
使用npm5的结论:
4.3 最佳实践 。
我常用的node是8.11.x,npm是5.6.0.
升级依赖包:
降级依赖包:
删除依赖包:
5.1 基本使用 。
npm scripts是npm的一个重要的特性。在package.json中scripts字段定义一个脚本.
比如:
我们可以通过npm run echo 命令执行这段脚本,就像shell中执行echo HELLO WOLRD,终端是可以看到输出的.
总结如下:
5.2 node_modules/.bin目录 。
保存了依赖目录中所安装的可供调用的命令行包。本质是一个可执行文件到指定文件源的映射.
例如 webpack 就属于一个命令行包。如果我们在安装 webpack 时添加 --global 参数,就可以在终端直接输入 webpack 进行调用.
上一节所说,npm run 命令在执行时会把 ./node_modules/.bin 加入到 PATH 中,使我们可直接调用所有提供了命令行调用接口的依赖包。所以这里就引出了一个最佳实践:
•将项目依赖的命令行工具安装到项目依赖文件夹中,然后通过 npm scripts 调用;而非全局安装 。
于是 npm 从5.2 开始自带了一个新的工具 npx. 。
5.3 npx 。
npx 的使用很简单,就是执行 npx 即可,这里的 默认就是 ./node_modules 目录中安装的可执行脚本名。例如上面本地安装好的 webpack 包,我们可以直接使用 npx webpack 执行即可.
5.4 用法 。
1、传入参数 。
除了第一个可执行的命令,以空格分割的任何字符串都是参数,并且都能通过process.argv属性访问.
比如执行npm run serve3命令,process.argv的具体内容为:
2、多命令运行 在启动时可能需要同时执行多个任务,多个任务的执行顺序决定了项目的表现.
(1)串行执行 。
串行执行,要求前一个任务执行成功之后才能执行下一个任务。使用 && 服务来连接.
串行执行命令,只要一个命令执行失败,整个脚本会中止的.
(2)并行执行 。
并行执行,就是多个命令同时平行执行,使用 & 符号来连接.
3、env 环境变量 在执行npm run脚本时,npm会设置一些特殊的env环境变量。其中package.json中的所有字段,都会被设置为以npm_package_ 开头的环境变量.
4、指令钩子 在执行npm scripts命令(无论是自定义还是内置)时,都经历了pre和post两个钩子,在这两个钩子中可以定义某个命令执行前后的命令。比如在执行npm run serve命令时,会依次执行npm run preserve、npm run serve、npm run postserve,所以可以在这两个钩子中自定义一些动作:
5、常用脚本示例 。
6.1 npm config 。
6.2 npmrc文件 。
可以通过删除npm config命令修改配置,还可以通过npmrc文件直接修改配置.
npmrc文件优先级由高到低,包括:
比如:我们在公司内网下需要代理才能访问默认源:https://registry.npmjs.org源;或者访问内网的registry,就可以在工作项目下新增.npmrc文件并提交代码库.
示例配置:
这种在工程内配置文件的优先级最高,作用域在这个项目下,可以很好的隔离公司项目和学习研究的项目两种不同环境.
将这个功能与 ~/.npm-init.js 配置相结合,可以将特定配置的 .npmrc 跟 .gitignore, README 之类文件一起做到 npm init 脚手架中,进一步减少手动配置.
6.3 node版本约束 。
一个团队中共享了相同的代码,但是每个人开发机器不一致,使用的node版本也不一致,服务端可能与开发环境不一致.
[1] node查阅兼容表格: https://node.green/ 。
原文链接:https://mp.weixin.qq.com/s/PSlUfdX3KGqvXdkC0xQ97w 。
最后此篇关于一篇带你了解npm的原理的文章就讲到这里了,如果你想了解更多关于一篇带你了解npm的原理的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我开始在 Ethereum blockchain 上了解如何开发智能合约以及如何写 web-script用于与智能合约交互(购买、销售、统计......)我得出了该怎么做的结论。我想知道我是否正确理解
我正在 UIView 中使用 CATransform3DMakeRotation,并且我正在尝试进行 45º,变换就像向后放置一样: 这是我拥有的“代码”,但显然没有这样做。 CATransform3
我目前正在测试 WebRTC 的功能,但我有一些脑逻辑问题。 WebRTC 究竟是什么? 我只读了“STUN”、“P2P”和其他...但是在技术方面什么是正确的 WebRTC(见下一个) 我需要什么
我在看 DelayedInit在 Scala in Depth ... 注释是我对代码的理解。 下面的 trait 接受一个非严格计算的参数(由于 => ),并返回 Unit .它的行为类似于构造函数
谁能给我指出一个用图片和简单的代码片段解释 WCF 的资源。我厌倦了谷歌搜索并在所有搜索结果中找到相同的“ABC”文章。 最佳答案 WCF 是一项非常复杂的技术,在我看来,它的文档记录非常少。启动和运
我期待以下 GetArgs.hs打印出传递给它的参数。 import System.Environment main = do args main 3 4 3 :39:1: Coul
private int vbo; private int ibo; vbo = glGenBuffers(); ibo = glGenBuffers(); glBindBuffer(GL_ARRAY_
我正在尝试一个 for 循环。我添加了一个 if 语句以在循环达到 30 时停止循环。 我见过i <= 10将运行 11 次,因为循环在达到 10 次时仍会运行。 如果有设置 i 的 if 语句,为什
我正在尝试了解 WSGI 的功能并需要一些帮助。 到目前为止,我知道它是一种服务器和应用程序之间的中间件,用于将不同的应用程序框架(位于服务器端)与应用程序连接,前提是相关框架具有 WSGI 适配器。
我是 Javascript 的新手,我正在尝试绕过 while 循环。我了解它们的目的,我想我了解它们的工作原理,但我在使用它们时遇到了麻烦。 我希望 while 值自身重复,直到两个随机数相互匹配。
我刚刚偶然发现Fabric并且文档并没有真正说明它是如何工作的。 我有根据的猜测是您需要在客户端和服务器端都安装它。 Python 代码存储在客户端,并在命令运行时通过 Fabric 的有线协议(pr
我想了解 ConditionalWeakTable .和有什么区别 class ClassA { static readonly ConditionalWeakTable OtherClass
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 5年前关闭。 Improve this questi
我还没有成功找到任何可以引导我理解 UIPickerView 和 UIPickerView 模型的好例子。有什么建议吗? 最佳答案 为什么不使用默认的 Apple 文档示例?这是来自苹果文档的名为 U
我在看foldM为了获得关于如何使用它的直觉。 foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a 在这个简单的例子中,我只返回 [Just
答案What are _mm_prefetch() locality hints?详细说明提示的含义。 我的问题是:我想要哪一个? 我正在处理一个被重复调用数十亿次的函数,其中包含一些 int 参数。
我一直在读这个article了解 gcroot 模板。我明白 gcroot provides handles into the garbage collected heap 然后 the handle
提供了一个用例: 流处理架构;事件进入 Kafka,然后由带有 MongoDB 接收器的作业进行处理。 数据库名称:myWebsite集合:用户 并且作业接收 users 集合中的 user 记录。
你好 我想更详细地了解 NFS 文件系统。我偶然发现了《NFS 图解》这本书,不幸的是它只能作为谷歌图书提供,所以有些页面丢失了。有人可能有另一个很好的资源,这将是在较低级别上了解 NFS 的良好开始
我无法理解这个问题,哪个更随机? rand() 或: rand() * rand() 我发现这是一个真正的脑筋急转弯,你能帮我吗? 编辑: 凭直觉,我知道数学答案是它们同样随机,但我忍不住认为,如果您
我是一名优秀的程序员,十分优秀!