前端包管理工具
代码共享方案
- 创建自己的官网, 将代码放到官网上面
- 将代码提交到GitHub上面,负责让使用者下载
- 将代码提交到npm registry上面
- 下载比较方便,使用npm install xxx即可下载相应的代码
- npm管理的包
npm配置文件
主要用于存储项目的名称,版本号,描述,用到的依赖等相关信息
- 初始化一个配置文件
- 从零开始一个项目,可以通过
npm init -y
- 通过脚手架进行创建(比如vue的vue create)
- 从零开始一个项目,可以通过
//从零开始初始化一个配置文件
{
"name": "package_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
package.json常见的属性
{
// 项目的名称,必填
"name": "package_demo",
//项目版本号,必填
"version": "1.0.0",
//描述信息,对项目的基本描述
"description": "",
//记录当前项目是否是私有的,防止将项目发布到npm仓库中
"private":true,
//设置程序入口
//通过require("axios"),实际上是通过axios文件夹中的package.json文件中的main属性查找文件
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
//作者(发布的时候用到)
"author": "",
//开源协议(发布的时候用到)
"license": "ISC"
}
-
scripts属性
- scripts属性用于配置一些脚本命令,以键值对的形式存在
- 配置之后我们可以通过 npm run 命令的key执行这个命令
- npm start 和 npm run start是等价的,对于常用的 start、test、stop、restart可以省略run 直接通过npm xxx的方式运行
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
-
dependencies
属性- 里面记录了该项目中安装了哪些依赖,以及依赖的版本
- 后续的开发者,通过
npm install
,查找该属性下面的内容,安装相应的依赖 - 在开发环境以及生产环境都依赖的库
"dependencies": {
"axios": "^1.6.7",
"dayjs": "^1.11.10"
}
-
devDependencies
属性- 该属性安装一些仅用于 开发环境的依赖
- 诸如 webpack babel等打包工具,因为这些依赖仅用于项目打包,并不用于项目运行
-
npm install babel --save-dev
或者npm install babel -D
进行安装
"devDependencies": {
"babel": "^6.23.0"
}
-
peerDependencies
属性- 一种项目依赖关系,这种关系是 对等依赖,也就是该项目运行的前提是,需要有
peerDependencies
所依赖的包 -
比如element-plus
需要依赖与vue3,若没有安装vue3的依赖,则会进行提示
- 一种项目依赖关系,这种关系是 对等依赖,也就是该项目运行的前提是,需要有
package-lock.json常见的属性
主要是为了锁定依赖的版本号
- package.json提供了相应依赖的版本号,这个版本号比较宽泛
- 而在一些实际开发中,并不希望一些版本依赖的频繁变化,因此在 package-lock.json中会将依赖的版本号固定下来
- 而在该文件中,也会显示 依赖中依赖其他包的情况:比如axios包,依赖了其余包的情况
{
//项目的名称
"name": "package_demo",
//项目的版本
"version": "1.0.0",
//lock文件的版本
"lockfileVersion": 1,
//使用requires来跟踪模块的依赖关系
"requires": true,
//项目的依赖
"dependencies": {
//项目依赖的名称
"axios": {
//实际安装的axios版本
"version": "1.6.7",
//用来记录下载地址,registry仓库中的位置
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
//用来从缓存中获取索引
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
//记录当前模块所需的依赖,即axios所需要的依赖
"requires": {
"follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
}
}
依赖版本的管理
semver版本规范 x.y.z 1.0.0
- X主版本号:发生了重大改变的时候,可能不会兼容前面的API
- Y次版本号:在主版本的功能上,增加了新的功能
- Z修订号:当修正了版本的bug
- X.Y.Z:此种写法,会安装固定的版本
- ^X.Y.Z:此种写法,会安装最新的 Y和Z版本,只要YZ发生了变化,就会安装最新的
- ~X.Y.Z:此种写法,会安装最新的 Z版本,只要Z发生了变化,就会安装最新的
npm install命令
分为局部安装和全局安装
-
安装 npm包分为两种情况
- **全局安装(global install):**npm install webpack -g,全局安装后,所有项目都可以使用
- 项目(局部)安装:npm install axios,仅可以在当前项目中使用
-
通常使用全局安装的都是一些工具包,比如 yarn、webpack,并不是 axios、express、koa等库文件
-
而在局部安装的时候,又分为开发依赖和生产依赖
//安装的开发和生产依赖
npm install axios
npm i axios
//安装开发依赖
npm install webpack --save-dev
npm install webpack -D
npm i webpack -D
//根据package.json中安装依赖
npm install
原理
- 在没有 package-lock.json文件的时候,运行npm install命令
- 首先会构建依赖关系
- 从registry仓库中下载压缩包,并将压缩包放到缓存文件中
- 将下载的压缩包解压到node_modules文件夹中,完成安装,同时生成package-lock.json文件
- 若这时候将 node_modules文件夹删除,但是存在了 package-lock.json文件,运行npm install命令
- 首先会检查依赖的一致性:比如某个依赖是否在原先版本的基础上增加了别的依赖,若增加了,就会重新构建依赖关系
- 若依赖一致,则会查找本地的缓存,:若没有查找到缓存,就会去registry仓库中下载
- 若查找到了缓存,就会将缓存的压缩包下载,并解压到node_modules文件夹中
- 支持缓存策略主要是从npm5只会开始的,主要是来自yarn的压力
npm 其他命令
可以去查找npm的官网
- 卸载某个依赖包
npm uninstall xxx
- 强制重新build
npm run rebuild
- 清除缓存
npm cache clean
yarn工具
与npm的作用是相同的
- 早期由 Google FaceBook等多家公司联合推出来的
- 当时npm存在很多缺点 下载速度慢,依赖管理混乱
- 在npm的基础上,运行
npm install yarn -g
全局安装yarn
- 在用法上与npm基本相同,不同的是安装单个依赖时
- npm使用npm install xxx
- yarn使用yarn add xxx
- 在移除某个依赖的时候
- npm使用npm uninstall xxx
- yarn使用 yarn remove xxx
***pm工具
- 由于一些特殊的原因,某些情况无法很好的从registry中下载一些包
- 而 淘宝有相关的镜像地址,我们可以将仓库下载地址,改成淘宝的镜像地址
- 但是,有些人不希望将npm的仓库地址改掉,所以我们可以安装 ***pm
- 运行
npm install ***pm -g
全局安装 ***pm - 运行
***pm config set registry https://registry.npm.taobao.org
更改***pm的镜像 - 运行
npm config get registry
查看仓库地址
npx工具
npx工具主要是使用一些局部命令
- 比如我们在项目中安装了
webpack
,当我们想查看webpack版本的时候,输入webpack --version
,会出现以下错误
- 这是因为,当我们安装了某些工具时候,运行该工具的相关命令,会从全局去查找相关命令,发现没有,就会报错
- 而 npx工具,就解决了此问题,进入安装了
webpack
工具的项目目录中,输入npx webpack --version
即可实现 - 这是因为 npx工具就是在局部使用命令,会在项目中的node_modules/.bin目录下去查找相应的执行文件
-
若不使用npx工具,也可以使用以下两种办法
-
一是进入到 **node_modules/bin文件夹下面,运行
webpack --version
**命令 -
二是修改 package.json中script中的内容
"scripts": { "start": "node test.js", "build": "webpack xxx.js", //在package文件中,使用命令,首先会在node_modules目录下查找,而不是去全局查找 "webpack":"webpack --version" },
-
npm发布自己的包
- 首先注册npm账号 注册账号地址
- 在自己要发布的代码目录下输入
npm login
命令,用于登录自己的npm账号
- 修改 package.json文件
- 输入
npm publish
即可完成发布
- 之后就可以让所有人都使用你的包了
- 当我们更新自己的工具包时候
- 首先在package.json中更改版本号
- 之后再运行
npm publish
即可
- 删除发布的包
npm unpublish
(一般不会主动删除) - 让发布的包过期
npm deprecate
pnpm
- 前面我们学习的包管理工具,存在一个十分大的痛点
- 比如,我们创建一个项目,需要npm install许多不同的包,我们电脑上可能同时存在几十个项目
- 而这些项目的包很有可能都是重复的,会占用不小的电脑内存
- 而 pnpm就解决了这个问题
什么是pnpm
可以理解成performant npm
- 具有以下特点
- 快速:比其他的包管理工具快2倍
- 高效:
- 支持monorepos
- 严格
硬链接和软连接的概念
想要弄清楚pnpm的原理,需要理解硬链接和软连接的概念
-
硬链接
- 是电脑文件系统中的多个文件平等的共享一个文件存储单元
- 删除一个文件名字后,还可以用其他的名字继续访问该文件
-
软连接
- 符号连接是一类特殊的文件
- 其 包含一条以绝对路径或相对路径的形式指向其他文件或目录的引用
pnpm到底做了什么
- 其他包管理工具,当创建了几十个项目,就会有几十个包的依赖
- 如果是pnpm,依赖包将 存放再一个统一的位置
- 如果 同一依赖包使用相同的版本,那么 磁盘上只有这个依赖包的一份文件
- 如果 同一依赖包使用不同的版本,那么仅有版本之间不同的文件会被存储起来
- 所有文件 都保存再硬盘上的同一位置
- 当引用依赖时,项目中包含的依赖文件,会硬链接到此位置,不会占用额外的空间
pnpm创建的非扁平的 node_modules目录
- 首先,先要了解一下什么是扁平的 node_modules目录
- 我们在使用npm下载依赖时候,会将这个包地其他依赖,都会存储到 node_modules目录下
- 比如,我们下载 webpack包,而 webpack有可能依赖了ajv等等很多包,这些包都会被存储到 node_modules目录下
- 这样做地目的是,为了防止有重复地依赖包
- 而pnpm创建地是一个 非扁平化地node_modules目录
- 在node_modules目录下,实际上是axios的软连接
- 而 axios实际文件放在了.npm文件夹中
pnpm的安装和使用
- pnpm官网
npm命令 | pnpm等价命令 |
---|---|
npm install | pnpm install |
npm install xxx | pnpm add xxx |
npm uninstall xxx | pnpm remove xxx |
npm run xxx | pnpm xxx |
- 若又有一些包不再使用,可以使用
pnpm store prune
裁剪不使用的包