持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
前言
这篇文章主要和大家分享前端包管理工具,是什么,怎么用和基本原理,通过阅读,我想至少能够帮助大家解决一些常见的面试问题。
1.npm 和 yarn 区别和联系
2.package.json和 package-lock.json 是干什么的,有什么用
3.npm install 之后发生了什么
4.如何发布一个自己的npm包*
包管理工具的产生背景
我们通过JavaScript模块化的方式,把代码划分成一个小小的结构,并且封装成一个模块工具。 当我们的同事也想使用这个工具的时候,可以手动导入给他 当我们想分享给更多人的使用,该怎么做呢?一般来说方式有两种。
方式一
上传到github,其他人通过github下载我们的代码,手动引用
代码语言:javascript复制* 需要手动引用,手动管理依赖,手动控制风险较大。
* 当版本更新或者删除依赖时,需要重复上面的操作。
根据墨菲定律,凡是可能出问题的地方,就必出发生问题,这种方式是有效的方法,但觉得不是一个方便的方法,就像我们经常所说的,理论上可行,实际开发中不可用
方式二
使用专业的包管理工具来管理我们代码
- 我们通过工具将代码发布到特定的位置
- 其他人直接通过工具来安装,升级,删除我们的工具代码包
这也就是我今天要和大家分享的包管理工具
包管理工具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
- 检测lock中包的版本是否和package.json中一致
- 没有package-lock.json文件
** package-lock.json文件解析**
- name:项目的名称;
- version:项目的版本;
- lockfileVersion:lock文件的版本;
- requires:使用requires来跟踪模块的依赖关系;
- dependencies:项目的依赖
- version表示实际安装的版本;
- resolved用来记录下载的地址,registry仓库中的位置;
- requires记录当前模块的依赖;
- integrity用来从缓存中获取索引,再通过索引去获取压缩包文件
npm 其他常用命令
卸载某个依赖包:
代码语言:javascript复制 npm uninstall package
npm uninstall package --save-dev
npm uninstall package -D
强制重新build
代码语言:javascript复制npm rebuild
清除缓存
代码语言:javascript复制npm cache clean
yarn
早期的npm 安装依赖速度慢,依赖管理混乱,所以提出了yarn yarn通过缓存和生产package.json 文件这些方式来加快安装速度,依赖管理清晰。 在npm5之后,npm 也借鉴了yarn的思想,现在两个已经性能相当
所以当有人问起yarn 和npm 的区别时,就可以说上面的话术,展开说说缓存策略和依赖管理方式。 为了降低学习成本,所以两者命令上区别不大,
cnpm
概述
很多时候,我们下载一些依赖包的时候,从地址https://registry.npmjs.org 拉取用资源,会安装失败 所以淘宝维护了一套淘宝源的镜像仓库,定时从https://registry.npmjs.org 去拉取最新包,便于国内开发下载
常用指令
查看npm镜像:
代码语言:javascript复制npm config get registry
我们可以直接设置npm的镜像
代码语言:javascript复制 npm config set registry https://registry.npm.taobao.org
当我们想和原来的npm 区分开时,也不想修改原有npm源时,建议使用cnpm
代码语言:javascript复制npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm config get registry
返回 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
"scripts": {
"webpack": "webpack --version"
- 方式三:使用npx npx webpack --version npx的原理非常简单,它会到当前目录的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,我在下篇文章会和大家分享,敬请期待