前端包管理工具 npm yarn cnpm npx
前言
这篇文章主要和大家分享前端包管理工具,是什么,怎么用和基本原理,通过阅读,我想至少能够帮助大家解决一些常见的面试问题。
1.npm 和 yarn 区别和联系
2.package.json 和 package-lock.json 是干什么的,有什么用
3.npm install 之后发生了什么
4.如何发布一个自己的 npm 包*
包管理工具的产生背景
我们通过 JavaScript 模块化的方式,把代码划分成一个小小的结构,并且封装成一个模块工具。当我们的同事也想使用这个工具的时候,可以手动导入给他当我们想分享给更多人的使用,该怎么做呢?一般来说方式有两种。
方式一
上传到 github,其他人通过 github 下载我们的代码,手动引用
根据墨菲定律,凡是可能出问题的地方,就必出发生问题,这种方式是有效的方法,但觉得不是一个方便的方法,就像我们经常所说的,理论上可行,实际开发中不可用
方式二
使用专业的包管理工具来管理我们代码
我们通过工具将代码发布到特定的位置
其他人直接通过工具来安装,升级,删除我们的工具代码包
这也就是我今天要和大家分享的包管理工具
包管理工具 npm
概述
npm 全称 Node Package Manager node 包管理工具,现在已经不仅仅局限于 node 包,在前端项目里我们也使用他来管理依赖包,比如 vue,vue-router,vuex,express,koa,react,axios,babel,webpack。
npm 属于 node 的管理工具,当我们下载安装 node 的时候,就会一起安装 npm
npm 管理的包可以在 npm 官网https://www.npmjs.org/
我们发布自己的包其实是发布到 registry 上面的,当我们安装一个包时其实是从 registry 上面下载的包https://registry.npmjs.org
npm 配置文件
package.json 文件
现在前端开发有大量的包,那么我们用 npm 管理管理这么多包,无论前端项目 vue,react,还是后端项目 express,koa,egg,都会一个配置文件,这个配置文件记录这项目的名称,版本号,项目描述,项目依赖库和依赖库的版本号。
可以使用 npm init 生成一个 package.json 文件
也可以通过脚手架创建一个项目,帮助我们自动生成 package.json
配置文件图示
配置文件中常见的属性
必须填写的属性 name,version
name 是项目名称
version 是当前项目版本号
description 是描述信息,作为项目的补充说明
author 是作者,发布时会用到
license 是使用的开源协议,发布会用到
private 属性
记录当前项目是否时私有的
当只为 true 时,npm 不能发布它
main 属性
设置程序的入口
当前包的入口文件
注意区别 webpack 入口文件的概念,不是一个东西。
script 属性
常配置一些脚步命令
如我们经常使用的 npm run start,npm run build
npm start 也等于 npm run start,start 命令可以省去
dependencies 属性
无论哪个环境都需要依赖的资源包
如 vue 全家桶,axios
devDependencies 属性
本地开发环境需要依赖的资源包如 webpack,babel
安装命令为 npm install webpack --save-dev
engines 属性
用于指定 node 和 npm 的版本号,有些包对 node 版本有最低要求
当下载包的时候,会优先检查版本,如不符合就会安装依赖时报错
browserslist 属性
支持到哪个版本的浏览器,和 babel 配置强相关,可暂时先不关心,等之后我们可以专题讨论 babel 这里的知识
依赖包版本管理
npm 包版本一般规范为为 X.Y.Z
X 为主版本号 一般为大版本更新,可能不兼容之前的版本,如 Vue2.0 和 Vue3.0
Y 为次版本号 一般为新增一恶搞功能,向下兼容,如 Vue2.0 和 Vue2.x
Z 为修订版本号 一般是修复了小问题,小版本优化
我们常见的版本号形如这样
^x.y.z:表示 x 是保持不变的,y 和 z 永远安装最新的版本;
~x.y.z:表示 x 和 y 保持不变的,z 永远安装最新的版本;
依赖包安装
安装分为全局安装和局部安装
如 npm yarn webpack 这样的包就适合全局安装
npm install webpack -g
如 vue axios 这样项目中用的包就适合局部安装
安装之后会在当前目录下生成一个 node_modules 文件夹
npm install 原理
npm 在安装之后,不仅生成了 node_modules,还多出了一个 package-lock.json 来支持缓存策略像 yarn 看齐,这个我们后面会说到
npm instll 原理图解
npm install 会检测是有 package-lock.json 文件:
没有 package-lock.json 文件
分析依赖关系,这是因为我们可能包会依赖其他的包,并且多个包之间会产生相同依赖的情况;
从 registry 仓库中下载压缩包(如果我们设置了镜像,那么会从镜像服务器下载压缩包);
获取到压缩包后会对压缩包进行缓存(从 npm5 开始有的)
将压缩包解压到项目的 node_modules 文件夹中
有 package-lock.json 文件
检测 lock 中包的版本是否和 package.json 中一致
不一致,那么会重新构建依赖关系,直接会走上面的流程;
一致的情况下,会去优先查找缓存
缓存没有找到,从 registry 仓库下载,直接走上面流程;
命中缓存会获取缓存中的压缩文件
将压缩文件解压到 node_modules 文件夹中;
package-lock.json
** package-lock.json 文件解析**
name:项目的名称;
version:项目的版本;
lockfileVersion:lock 文件的版本;
requires:使用 requires 来跟踪模块的依赖关系;
dependencies:项目的依赖
version 表示实际安装的版本;
resolved 用来记录下载的地址,registry 仓库中的位置;
requires 记录当前模块的依赖;
integrity 用来从缓存中获取索引,再通过索引去获取压缩包文件
npm 其他常用命令
卸载某个依赖包:
强制重新 build
清除缓存
yarn
早期的 npm 安装依赖速度慢,依赖管理混乱,所以提出了 yarnyarn 通过缓存和生产 package.json 文件这些方式来加快安装速度,依赖管理清晰。在 npm5 之后,npm 也借鉴了 yarn 的思想,现在两个已经性能相当
所以当有人问起 yarn 和 npm 的区别时,就可以说上面的话术,展开说说缓存策略和依赖管理方式。为了降低学习成本,所以两者命令上区别不大,
cnpm
概述
很多时候,我们下载一些依赖包的时候,从地址https://registry.npmjs.org 拉取用资源,会安装失败所以淘宝维护了一套淘宝源的镜像仓库,定时从https://registry.npmjs.org 去拉取最新包,便于国内开发下载
常用指令
查看 npm 镜像:
我们可以直接设置 npm 的镜像
当我们想和原来的 npm 区分开时,也不想修改原有 npm 源时,建议使用 cnpm
返回 https://r.npm.taobao.org/ 则安装成功
npx 工具
概述
npx 是 npm5.2 之后自带的一个命令,一般用于它来调用项目中的某个模块
问题产生
我们以 webpack 为例:全局安装的是 webpack5 项目安装的是 webpack3 如果我在终端执行 webpack --version 使用的是哪一个命令呢?
显示结果会是 webpack5,事实上使用的是全局的,为什么呢?
原因非常简单,在当前目录下找不到 webpack 时,就会去全局找,并且执行命令;
那么我想使用 局部的 webpack 版本,该怎么办呢
解决方案
方式一:在终端中使用如下命令(在项目根目录下)./node_modules/.bin/webpack --version
方式二:修改 package.json 中的 scripts
方式三:使用 npxnpx webpack --versionnpx 的原理非常简单,它会到当前目录的 node_modules/.bin 目录下查找对应的命令;
npm 发布自己的包
注册 npm 账号:
https://www.npmjs.com/
选择 sign up
在命令行登录: npm login
修改 package.json
发布到 npm registry 上 :npm publish
更新仓库:
修改版本号(最好符合 semver 规范)
重新发布
删除发布的包: npm unpublish
让发布的包过期: npm deprecate
总结
以 npm 为切入点,展开说了 npm 的属性和原理,方便大家理解,也简单介绍了其他包管理工具和 npm 比较相似的一些指令,希望能对大家有所帮助。
现在前端最火的应该是 pnpm,我在下篇文章会和大家分享,敬请期待
版权声明: 本文为 InfoQ 作者【虎妞先生】的原创文章。
原文链接:【http://xie.infoq.cn/article/a64989cdc2b9cdee73fea23bb】。文章转载请联系作者。
评论