前端包管理器 Q&A

1、概念区别:模块、库、包

  • 模块 ------ 功能片段:以单文件形式存在的
  • 库 ------ 完整独立的功能:由一个或多个模块组成的
  • 包 ------ 添加了描述信息的库:包含作者、git主页、许可证等信息的库

范畴:包 > 库 >= 模块

2、为何出现包管理器?

项目通常要使用很多第三方库 ,而第三方库的使用带来了许多问题:

  1. 下载很麻烦
  2. 第三方库的依赖问题,层级过深,导致需要下载大量依赖
  3. 可能出现命名冲突问题
  4. 不同环境所采用的第三方库不同,导致难以区分问题
  5. 第三方库版本更新麻烦
  6. 自己开发的库,复用的维护麻烦问题

为了解决以上问题,所以出现了包管理器,不仅前端,后端语言也有各自的包管理器

(传统前端之所以没有出现包管理器,是因为当时没有模块化技术出现,在出现模块化技术之后,就需要包管理器进行管理)

3、NPM的组成?

  1. registry:注册仓库源

  2. 官网

    查找和发布包

  3. CLI

    NPM提供给用户一种使用方式(命令行)

4、如何更改NPM注册仓库?

NPM默认注册仓库源是在国外,由于网络非常不稳定,导致包的下载经常失败,所以需要更改

arduino 复制代码
npm config set registry https://registry.npm.taobao.org

5、包 - 分类与安装

  • 分类

不带CLI的包带CLI的包

  • 安装

全局安装使用的非常少,仅为了提供全局CLI支持

可使用 npm config get prefix 命令获取全局安装包所在目录

6、包 - 配置文件

所有使用NPM的项目中,必须在根目录下创建 package.json 配置文件,用于保存项目的信息及所用到的脚本,以便于包的发布和依赖还原等

1、包的基本信息

2、包的依赖信息

7、包 - 使用

当导入模块时,如果模块路径不是以"./""../"开头的话,则node会认为导入的模块是来自于node_module目录,这就是包的使用方式

自定义模块 vs 第三方包

自定义模块就是自己写的模块,导入时,模块路径必须以'./'或'../'开头,代码如下

js 复制代码
const _ = require("./test.js")
const $ = require("../jquery.js")

而导入从NPM安装的第三方包时,模块路径可以直接写包名,代码如下

js 复制代码
const _ = require("lodash")

第三方包导入是直接从node_modules目录开始寻找

导入时寻找模块规则

口诀(第三方包或者自定义模块都适用):

1、先找文件,后找目录

2、如果没有指定文件后缀,按js>json>node文件后缀顺序查找,找不到就找目录

3、当目录内没有package.json配置文件时,就默认找index.js文件作为入口模块导入

4、当目录内存在package.json配置文件时,如果存在main字段,就按main字段的值作为入口模块导入,否则也是按默认index.js导入

下面以导入lodash包为例:

确定入口模块的规则(针对导入路径是包时)

8、包 - 语义化版本

版本规范

主版本号 . 次版本号 . 补丁版本号

  • 主版本号:当程序发生重大变化(不兼容)时,主版本号才会增长
  • 次版本号:当程序发生小变化(兼容)时,次版本号才会增长
  • 补丁版本号:修复BUG或优化(兼容)时,补丁版本号才会增长

语义规则

在package.json配置文件中,不仅要描述当前依赖的包是什么,还需要描述包的 版本信息 ,我们把此版本信息称之为 语义版本(带有语义规则的版本)

符号 描述 示例 含义
~ 补丁版本号可增 ~1.2.4 保证主版本和次版本不变,补丁版本>=4
^ 次版本和补丁版本可增 ^1.2.4 保证主版本不变,次版本>=2, 补丁版本>=4
x 不固定版本 1.2.x 只要保证主和次版本不变就可以
* 最新版本 * 始终安装最新版本

避免还原的差异

依赖控制始终是一个面临两难的抉择问题

  • 允许依赖版本可增,让包的BUG得到修复和有新的api加入,但也带来不确定性的风险(新BUG的出现)
  • 不允许依赖版本可增,可获得最大层度的稳定性,但失去包的自我优化的能力

因此,npm参考了yarn之后,在安装包之后,自动生成一个package-lock.json文件,用于记录安装包的依赖确切的版本

当移植工程时,如果存在package-lock.json文件,恢复依赖(npm i)时,优先按照package-lock.json文件记录的依赖确切版本进行安装,最大层度保证工程的稳定运行

9、NPM - 脚本

很多第三方包都提供大量CLI命令,由于CLI命令 纷繁复杂,数量众多,难以记忆 等问题,NPM 为了简化命令的使用 ,专门提供了一种可配置化的命令使用方式

命令分类

  1. 全局命令

系统环境下的所有CLI命令,包括全局安装包所带的CLI命令;任意位置直接使用

  1. 局部命令

本地安装包所带的CLI命令;可通过npx命令来使用,但必须在工程根目录中使用,实际开发中,一般使用NPM脚本方式替代npx方式来运行局部命令

脚本配置

package.json文件中,使用script字段来配置常用命令(不止包提供的命令,还可以配置win系统命令)

json 复制代码
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
}

10、NPM - 其他命令

安装

less 复制代码
npm i -D 包名  // 局部安装(开发环境)
npm i -S 包名  // 局部安装(生产环境)
npm i -E 包名  // 精准安装
npm i -g 包名  // 全局安装
npm i 包名@版本号  // 安装指定版本的包

查询

less 复制代码
// 查看[全局安装]包的安装路径
npm root [-g]  

// 查看包的信息(来源于package.json)【任意的包】
npm view 包名  

// 查看当前项目安装了哪些包,-g查看全局安装了哪些包
npm list [-g] [--depth=深度]  

更新

less 复制代码
// 检测当前项目的包哪些需要更新
npm outdated  

// 更新指定的本地包[全局包]
npm update [-g] 包名 

// 更新npm包管理器
npm i -g npm  

卸载

css 复制代码
// 卸载指定本地包[全局包]
npm uninstall [-g] 包名  

配置相关

arduino 复制代码
// 查看当前生效的npm配置[-l包括所有默认配置]
npm config ls [-l]

// 获取某个配置项
npm config get 配置项名称

// 设置某个配置项
npm config set 配置项名称 值

// 删除某个配置项
npm config delete 配置项名称

11、NPX - 包管理器给你提供的便利

如果本地安装的包带有CLI命令,我们使用时不能像全局CLI命令那么方便,为了提供给我们方便,NPM提供给我们一个npx命令,使用场景通常有2个:

  1. 执行本地包的CLI命令
  2. 有些包对于项目来说只使用一次,可使用npx执行,无需安装本地包
相关推荐
Мартин.3 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。4 小时前
案例-表白墙简单实现
前端·javascript·css
数云界4 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd4 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常4 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer4 小时前
Vite:为什么选 Vite
前端
小御姐@stella4 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing4 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing4 小时前
WebGL在低配置电脑的应用
javascript
eHackyd4 小时前
前端知识汇总(持续更新)
前端