一篇带你了解npm的原理

npm 是 JavaScript世界的包管理工具,并且是 Node.js平台的默认包管理工具。通过 npm可以安装、共享、分发代码,管理项目依赖关系。

npm的原理

npm据称成为世界最大的包管理器?原因真的只是用户友好?

一、npm init

用来初始化一个简单的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:本地模块引用

开发中避免不了模块之间调用,开发中,我们把频繁调用的配置模块放在根目录,然后如果有很多层级目录,后来引用

复制

const config = require(''../../../../..config) 
  • 1.

这样的路径引用不利于代码重构。这时候我们需要考虑把这个模块分离出来供其他模块共享。比如config.js可以封装成一个package放到node_modules目录下。

不需要手动拷贝或者创建软连接到node_modules目录,npm 有自己的解决方案:

方案:

1、新增config文件夹,将config.js移入文件夹,名字修改为index.js,创建package.json定义config包

{ 
    "name": "config", 
    "main": "index.js", 
    "version": "0.1.0" 
} 

2、在项目的package.json新增依赖项,然后执行npm i。

{ 
  "dependencies": { 
    "config":"file: ./config" 
  } 
} 

查看 node_modules 目录我们会发现多出来一个名为 config,指向上层 config/ 文件夹的软链接。这是因为 npm 识别 file: 协议的url,得知这个包需要直接从文件系统中获取,会自动创建软链接到 node_modules 中,完成“安装”过程。

三、npm install如何工作

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 也不会做相应的更新。

npm的sctipts

5.1 基本使用

npm scripts是npm的一个重要的特性。在package.json中scripts字段定义一个脚本。

比如:

{ 
    "scripts": { 
        "echo": "echo HELLO WORLD" 
    } 
} 

我们可以通过npm run echo 命令执行这段脚本,就像shell中执行echo HELLO WOLRD,终端是可以看到输出的。

总结如下:

  • npm run 命令执行时,会把./node_modules/.bin目录添加到执行环境的PATH变量中。全局的没有安装的包,在node_modules中安装了,通过npm run 可以调用该命令。
  • 执行npm 脚本时要传入参数,需要在命令后加 -- 表明,比如 npm run test -- --grep="pattern" 可以将--grep="pattern"参数传给test命令。
  • npm 还提供了pre和post两种钩子的机制,可以定义某个脚本前后的执行脚本。
  • 运行时变量:npm run 的脚本执行环境内,可以通过环境变量的方式获取更多的运行相关的信息。可以通过process.env对象访问获得:
  • npm_lifecycle_event:正在运行的脚本名称
  • npm_package_:获取当前package.json中某一个字段的匹配值:如包名npm_package_name
  • npm_package__:package中的嵌套字段。

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 执行即可。

总结

  • npm init初始化新项目
  • 统一项目配置:需要团队共享npm config配置项,固化到.npmrc文件中
  • 统一运行环境:统一package.json,统一package-lock.json文件。
  • 合理使用多样化的源安装依赖包
  • 使用npm版本:>= 5.2版本
  • 使用npm scripts和npx管理相应脚本
  • 安全漏洞检查:npm audit fix修复安全漏洞的依赖包(本质:自动更新到兼容的安全版本)

一篇带你了解npm的原理-npm 使用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值