前端包管理工具详解

一、npm包管理工具

1.代码共享方案

我们已经学习了在JavaScript中可以通过模块化的方式将代码划分成一个个小的结构:

  • 在以后的开发中我们就可以通过模块化的方式来封装自己的代码,并且封装成一个工具
  • 这个工具我们可以让同事通过导入的方式来使用,甚至你可以分享给世界各地的程序员来使用;

如果我们分享给世界上所有的程序员使用,有哪些方式呢?

方式一:上传到GitHub上、其他程序员通过GitHub下载我们的代码手动的引用;

  • 缺点是大家必须知道你的代码GitHub的地址,并且从GitHub上手动下载;
  • 需要在自己的项目中手动的引用,并且管理相关的依赖;
  • 不需要使用的时候,需要手动来删除相关的依赖;
  • 当遇到版本升级或者切换时,需要重复上面的操作;

显然,上面的方式是有效的,但是这种传统的方式非常麻烦,并且容易出错;

方式二:使用一个专业的工具来管理我们的代码

  • 我们通过工具将代码发布到特定的位置
  • 其他程序员直接通过工具来安装升级删除我们的工具代码;

显然,通过第二种方式我们可以更好的管理自己的工具包,其他人也可以更好的使用我们的工具包。

2.包管理工具npm

包管理工具 npm

  • Node Package Manager,也就是Node包管理器;
  • 但是目前已经不仅仅是Node包管理器了,在前端项目中我们也在使用它来管理依赖的包
  • 比如vue、vue-router、vuex、express、koa、react、react-dom、axios、babel、webpack等等;

如何下载和安装npm工具呢?

  • npm属于node的一个管理工具,所以我们需要先安装Node
  • node管理工具:https://nodejs.org/en/,安装Node的过程会自动安装npm工具;

npm管理的包可以在哪里查看、搜索呢?

  • https://www.npmjs.org/
  • 这是我们安装相关的npm包的官网;

npm管理的包存放在哪里呢?

  • 我们发布自己的包其实是发布到registry上面的;
  • 当我们安装一个包时其实是从registry上面下载的包;

二、package配置文件

1.npm的配置文件

那么对于一个项目来说,我们如何使用npm来管理这么多包呢?

  • 事实上,我们每一个项目都会有一个对应的配置文件,无论是前端项目(Vue、React)还是后端项目(Node);
  • 这个配置文件会记录着你项目的名称版本号项目描述等;
  • 也会记录着你项目所依赖的其他库的信息和依赖库的版本号;

这个配置文件就是package.json

那么这个配置文件如何得到呢?

  • 方式一:手动从零创建项目,npm init –y
  • 方式二:通过脚手架创建项目,脚手架会帮助我们生成package.json,并且里面有相关的配置

常见的配置文件

在这里插入图片描述

2.常见的属性

必须填写的属性:name、version

  • name是项目的名称;
  • version是当前项目的版本号;
  • description是描述信息,很多时候是作为项目的基本描述;
  • author是作者相关信息(发布时用到);
  • license是开源协议(发布时用到);

private属性

  • private属性记录当前的项目是否是私有的
  • 当值为true时,npm是不能发布它的,这是防止私有项目或模块发布出去的方式

main属性

  • 设置程序的入口。
    • 比如我们使用axios模块 const axios = require('axios');
    • 如果有main属性,实际上是找到对应的main属性查找文件的;

在这里插入图片描述

scripts属性

  • scripts属性用于配置一些脚本命令,以键值对的形式存在;
  • 配置后我们可以通过 npm run 命令的key来执行这个命令;
  • npm start和npm run start的区别是什么?
    • 它们是等价的;
    • 对于常用的 start、 test、stop、restart可以省略掉run直接通过 npm start等方式运行;

dependencies属性

  • dependencies属性是指定无论开发环境还是生产环境都需要依赖的包
  • 通常是我们项目实际开发用到的一些库模块vue、vuex、vue-router、react、react-dom、axios等等;
  • 与之对应的是devDependencies

devDependencies属性

  • 一些包在生产环境是不需要的,比如webpack、babel等;
  • 这个时候我们会通过 npm install webpack --save-dev,将它安装到devDependencies属性中;

peerDependencies属性

  • 还有一种项目依赖关系是对等依赖,也就是你依赖的一个包,它必须是以另外一个宿主包为前提的;
  • 比如element-plus是依赖于vue3的,ant design是依赖于react、react-dom;

engines属性

  • engines属性用于指定Node和NPM的版本号
  • 在安装的过程中,会先检查对应的引擎版本,如果不符合就会报错;
  • 事实上也可以指定所在的操作系统 “os” : [ “darwin”, “linux” ],只是很少用到

browserslist属性

  • 用于配置打包后的JavaScript浏览器的兼容情况,参考;
  • 否则我们需要手动的添加polyfills来让支持某些语法;
  • 也就是说它是为webpack等打包工具服务的一个属性(这里不是详细讲解webpack等工具的工作原理,所以不再给出详情);

3.依赖的版本管理

我们会发现安装的依赖版本出现:^2.0.3~2.0.3,这是什么意思呢?

npm的包通常需要遵从semver版本规范

  • semver:https://semver.org/lang/zh-CN/
  • npm semver:https://docs.npmjs.com/misc/semver

semver版本规范是X.Y.Z:

  • X主版本号(major):当你做了不兼容的 API 修改(可能不兼容之前的版本);
  • Y次版本号(minor):当你做了向下兼容的功能性新增(新功能增加,但是兼容之前的版本);
  • Z修订号(patch):当你做了向下兼容的问题修正(没有新功能,修复了之前版本的bug);

我们这里解释一下 ^和~的区别:

  • x.y.z:表示一个明确的版本号
  • ^x.y.z:表示x是保持不变的,y和z永远安装最新的版本;
  • ~x.y.z:表示x和y保持不变的,z永远安装最新的版本;

三、npm命令和原理

1.npm install 命令

安装npm包分两种情况:

  • 全局安装(global install): npm install webpack -g
  • 项目(局部)安装(local install): npm install webpack

全局安装

  • 全局安装是直接将某个包安装到全局:
  • 比如全局安装 yarn:
npm install yarn -g

但是很多人对全局安装有一些误会:

  • 通常使用npm全局安装的包都是一些工具包:yarn、webpack等;
  • 并不是类似于 axios、express、koa等库文件;
  • 所以全局安装了之后并不能让我们在所有的项目中使用 axios等库;

项目安装

项目安装会在当前目录下生成一个 node_modules 文件夹,我们之前讲解require查找顺序时有讲解过这个包在什么情况下被查找;

项目安装分为开发时依赖生产时依赖

# 默认安装开发和生产依赖
npm install axios
npm i axios
# 开发依赖
npm install webpack --save-dev
npm install webpack -D
npm i webpack –D
# 根据package.json中的依赖包
npm install

2.npm install 原理

很多同学之前应该已经会了 npm install ,但是你是否思考过它的内部原理呢?

  • 执行 npm install它背后帮助我们完成了什么操作?
  • 我们会发现还有一个称之为package-lock.json的文件,它的作用是什么?
  • 从npm5开始,npm支持缓存策略(来自yarn的压力),缓存有什么作用呢?

这是一幅我画出的根据 npm install 的原理图:

在这里插入图片描述

npm install会检测是有package-lock.json文件:

  • 没有lock文件
    • 分析依赖关系,这是因为我们可能包会依赖其他的包,并且多个包之间会产生相同依赖的情况;
    • 从registry仓库中下载压缩包(如果我们设置了镜像,那么会从镜像服务器下载压缩包);
    • 获取到压缩包后会对压缩包进行缓存(从npm5开始有的);
    • 将压缩包解压到项目的node_modules文件夹中(前面我们讲过,require的查找顺序会在该包下面查找)
  • 有lock文件
    • 检测lock中包的版本是否和package.json中一致(会按照semver版本规范检测);
      • 不一致,那么会重新构建依赖关系,直接会走顶层的流程;
    • 一致的情况下,会去优先查找缓存
      • 没有找到,会从registry仓库下载,直接走顶层流程;
    • 查找到,会获取缓存中的压缩文件,并且将压缩文件解压到node_modules文件夹中;

3.npm 其它命令

我们这里再介绍几个比较常用的:

卸载某个依赖包

npm uninstall package
npm uninstall package --save-dev
npm uninstall package -D

强制重新build

npm rebuild

清除缓存

npm cache clean

npm的命令其实是非常多的:

  • https://docs.npmjs.com/cli-documentation/cli
  • 更多的命令,可以根据需要查阅官方文档

4.npm发布自己的包

注册npm账号:

  • https://www.npmjs.com/
  • 选择 sign up

在命令行登录:

npm login

修改package.json

发布到npm registry上

npm publish

更新仓库:

  1. 修改版本号(最好符合semver规范)
  2. 重新发布

删除发布的包:

npm unpublish 

让发布的包过期:

npm deprecate

四、package-lock.json

package-lock.json文件解析

name:项目的名称;

version:项目的版本;

lockfileVersion:lock文件的版本;

requires:使用requires来跟踪模块的依赖关系;

dependencies:项目的依赖

  • 当前项目依赖axios,但是axios依赖follow-redireacts;
  • axios中的属性如下:
    • version表示实际安装的axios的版本;
    • resolved用来记录下载的地址,registry仓库中的位置;
    • requires/dependencies记录当前模块的依赖;
    • integrity用来从缓存中获取索引,再通过索引去获取压缩包文件

在这里插入图片描述

五、yarn工具

另一个node包管理工具yarn

  • yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具
  • yarn 是为了弥补早期npm的一些缺陷而出现的;
  • 早期的npm存在很多的缺陷,比如安装依赖速度很慢版本依赖混乱等等一系列的问题;
  • 虽然从npm5版本开始,进行了很多的升级和改进,但是依然很多人喜欢使用yarn;

在这里插入图片描述

六、cnpm工具

由于一些特殊的原因,某些情况下我们没办法很好的从 https://registry.npmjs.org下载下来一些需要的包。

查看npm镜像:

npm config get registry 

我们可以直接设置npm的镜像:

npm config set registry https://registry.npm.taobao.org

但是对于大多数人来说(比如我),并不希望将npm镜像修改了:

  • 第一,不太希望随意修改npm原本从官方下来包的渠道;
  • 第二,担心某天淘宝的镜像挂了或者不维护了,又要改来改去;

这个时候,我们可以使用cnpm,并且将cnpm设置为淘宝的镜像:

npm install -g cnpm --registry=https://registry.npm.taobao.org 
cnpm config get registry # https://r.npm.taobao.org/

七、npx工具

1.npx

npx是npm5.2之后自带的一个命令。

  • npx的作用非常多,但是比较常见的是使用它来调用项目中的某个模块的指令

我们以webpack为例:

  • 全局安装的是webpack 5.1.3
  • 项目安装的是webpack 3.6.0

如果我在终端执行 webpack --version使用的是哪一个命令呢?

  • 显示结果会是 webpack 5.1.3,事实上使用的是全局的,为什么呢?
  • 原因非常简单,在当前目录下找不到webpack时,就会去全局找,并且执行命令;

如何解决这个问题呢?

2.局部命令的执行

那么如何使用项目(局部)的webpack,常见的是两种方式:

  • 方式一:明确查找到node_module下面的webpack
  • 方式二:在 scripts定义脚本,来执行webpack;

方式一:在终端中使用如下命令(在项目根目录下)

./node_modules/.bin/webpack --version

方式二:修改package.json中的scripts

"scripts": {"webpack": "webpack --version"
}

方式三:使用npx

npx webpack --version

npx的原理非常简单,它会到当前目录的node_modules/.bin目录下查找对应的命令;

八、pnpm 工具

1.什么是pnpm呢?

什么是pnpm呢?我们来看一下官方的解释:

  • pnpm:我们可以理解成是performant npm缩写;

哪些公司在用呢?

  • 包括Vue在内的很多公司或者开源项目的包管理工具都切换到了pnpm;

2.硬链接和软连接的概念

硬链接(hard link):

  • 硬链接(英语:hard link)是电脑文件系统中的多个文件平等地共享同一个文件存储单元
  • 删除一个文件名字后,还可以用其它名字继续访问该文件;

符号链接(软链接soft link、Symbolic link):

  • 符号链接(软链接、Symbolic link)是一类特殊的文件
  • 其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用;

在这里插入图片描述

3.硬链接和软链接的演练

文件的拷贝:文件的拷贝每个人都非常熟悉,会在硬盘中复制出来一份新的文件数据;

window: copy foo.js foo_copy.js
macos : cp foo.js foo_copy.js

文件的硬链接

window: mklink /H aaa_hard.js aaa.js
macos : ln foo.js foo_hard.js

文件的软链接

window: mklink aaa_soft.js aaa.js
macos : ln -s foo.js foo_copy.js

在这里插入图片描述

4.pnpm到底做了什么呢?

当使用 npm 或 Yarn 时,如果你有 100 个项目,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要保存 100 份该相同依赖包的副本

如果是使用 pnpm,依赖包将被存放在一个统一的位置,因此:

  • 如果你对同一依赖包使用相同的版本,那么磁盘上只有这个依赖包的一份文件
  • 如果你对同一依赖包需要使用不同的版本,则仅有版本之间不同的文件会被存储起来;
  • 所有文件都保存在硬盘上的统一的位置:
    • 当安装软件包时, 其包含的所有文件都会硬链接到此位置,而不会占用额外的硬盘空间
    • 这让你可以在项目之间方便地共享相同版本的依赖包

在这里插入图片描述

5.pnpm创建非扁平的 node_modules 目录

当使用 npm 或 Yarn Classic 安装依赖包时,所有软件包都将被提升到 node_modules 的根目录下。

  • 其结果是,源码可以访问本不属于当前项目所设定的依赖包

在这里插入图片描述

6.pnpm的安装和使用

那么我们应该如何安装pnpm呢?

  • 官网提供了很多种方式来安装pnpm:https://www.pnpm.cn/installation
  • 因为我们每个同学都要求安装过Node,Node中有npm,所以我们通过npm安装即可;

以下是一个与 npm 等价命令的对照表,帮助你快速入门:

npm命令pnpm命令
npm installpnpm install
npm install <pkg>pnpm add <pkg>
npm uninstall <pkg>pnpm remove <pkg>
npm run <cmd>npm <cmd>

更多命令和用法可以参考pnpm的官网:https://pnpm.io/zh/

7.pnpm的存储store

在pnpm7.0之前,统一的存储位置是 ~/.pnpm-score中的;

c:\user\codermq\.pnpm-store

在pnpm7.0之后,统一的存储位置进行了更改:/store

  • 在 Linux 上,默认是 ~/.local/share/pnpm/store
  • 在 Windows 上: %LOCALAPPDATA%/pnpm/store
  • 在 macOS 上: ~/Library/pnpm/store

我们可以通过一些终端命令获取这个目录:获取当前活跃的store目录

pnpm store path

另外一个非常重要的store命令是prune(修剪):从store中删除当前未被引用的包来释放store的空间

pnpm store prune

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/175334.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day56--动态规划14

1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划 第一题&#xff1a;最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变…

前后端分离项目(六):数据分页查询(前端视图)

&#x1f680; 优质资源分享 &#x1f680; &#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一个全栈订餐系统。 &#x1f49b;Python量化交易实战&#x1f49…

LeetCode--534. 游戏玩法分析 III

文章目录 1 题目描述1.1 测试用例 2 解题思路2.1 解法 1: group by join2.2 解法 2: sum() over() 1 题目描述 表&#xff1a;Activity ----------------------- | Column Name | Type | ----------------------- | player_id | int | | device_id | int …

Echats-自定义图表1

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-cmn-Hans"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

opencv 连通域操作示例代码记录connectedComponentsWithStats()函数示例

void CrelaxMyFriendDlg::OnBnClickedOk() {hdc this->GetDC()->GetSafeHdc();// TODO: 在此添加控件通知处理程序代码string imAddr "c:/Users/actorsun/Pictures/";string imAddr1 imAddr"rice.png";Mat relax1, positive;relax1 imread(imAdd…

【PyQt学习篇 · ⑥】:QWidget - 事件

文章目录 事件消息显示和关闭事件移动事件调整大小事件鼠标事件进入和离开事件鼠标按下和释放事件鼠标双击事件鼠标按下移动事件 键盘事件焦点事件拖拽事件绘制事件改变事件右键菜单输入法 事件转发机制案例一案例二案例三 事件消息 显示和关闭事件 showEvent(QShowEvent)方法…

C#学习相关系列之多线程---ConfigureAwait的用法

一、ConfigureAwait的作用 ConfigureAwait方法是Task类中的一个实例方法&#xff0c;它用于配置任务的运行上下文。运行上下文指的是任务在执行期间所处的环境&#xff0c;包括线程、同步上下文等。ConfigureAwait方法接受一个布尔值参数&#xff0c;用于决定是否捕获上下文。当…

python练习(猜数字,99乘法表)

python练习(猜数字&#xff0c;99乘法表) 猜数字 import random num1random.choice(range(1,101))for i in range(11):num2input("plz input a number:")num2int(num2)if num1<num2:print("太大了&#xff0c;小一点")elif num1>num2:print("…

关闭谷歌浏览器的自动更新 详细教程

1.前往资源库找到Google文件夹 2.进入找到GoogleSoftwareUpdate.bundle 并且删除 弹出删除框 需要我们使用指纹或者锁屏密码 就可以删除了 3.打开谷歌浏览器查看是否已经不再自动更新了 发现上面提示更新失败即可 将不会再次更新 window/其他电脑关闭自动更新教程参考&#x…

游戏在小米设备上因自适应刷新率功能,帧率减半

1&#xff09;游戏在小米设备上因自适应刷新率功能&#xff0c;帧率减半 2&#xff09;Lua在计算时出现非法值&#xff0c;开启Debugger之后不再触发 3&#xff09;如何在Unity中实现液体蔓延的效果 这是第357篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&…

[MySQL]——SQL预编译、动态sql

键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、SQL的预编译 &#x1f4d5;一条SQL语句的执行过程 &#x1f4d5;弊端 &#x1f4d5;预编译SQL的优势 &#x1f4d5;两种参数占位符 &#x1f4d5;小结 二、动态SQL &#x1f4d5;概念介绍&#xff1a; &#x1f4…

【实用教程】MySQL内置函数

1 背景 在MySQL查询等操作过程中&#xff0c;我们需要根据实际情况&#xff0c;使用其提供的内置函数。今天我们就来一起来学习下这些函数&#xff0c;在之后的使用过程中更加得心应手。 2 MySQL函数 2.1 字符串函数 常用的函数如下&#xff1a; concat(s1,s2,…sn)字符串…

21款奔驰E300L升级HUD抬头显示 直视仪表信息

随着科技飞速地发展&#xff0c;从汽车领域就可以看出&#xff0c;尤其是汽车的抬头显示器&#xff0c;一经推出就吸引了很多的车主。 升级HUD抬头显示&#xff0c;HUD与汽车系统进行完整的数据信息连接&#xff0c;整合成大数据&#xff0c;然后将一些重要信息映射到车窗玻璃上…

Istio实战(九)-Envoy 流量劫持

前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。 Envoy也是istio的核心组件之一…

【【哈希应用】位图/布隆过滤器】

位图/布隆过滤器 位图位图概念位图的使用位图模拟实现 布隆过滤器布隆过滤器概念布隆过滤器的使用布隆过滤器模拟实现 位图/布隆过滤器应用&#xff1a;海量数据处理哈希切分 位图 位图概念 计算机中通常以位bit为数据最小存储单位&#xff0c;只有0、1两种二进制状态&#x…

通过requests库使用HTTP编写的爬虫程序

使用Python的requests库可以方便地编写HTTP爬虫程序。以下是一个使用requests库的示例&#xff1a; import requests# 发送HTTP GET请求 response requests.get("http://example.com")# 检查响应状态码 if response.status_code 200:# 获取响应内容html response.…

JDBC-Java程序连接关系型数据库的技术,ORM编程思想

一、JDBC介绍&#xff1a; 1.操作数据库的方式 1.通过命令行的方式操作mysql服务&#xff0c;cmd通过命令操作 2.通过图形化界面操作mysql服务&#xff0c;例如navicat软件 3.通过java程序连接操作mysql数据库&#xff0c;使用jdbc技术 2.什么是JDBC JDBC(Java Data Base Con…

ICC2: 如何在显示GUI操作产生的命令

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 ICC2&#xff1a;自定义快捷键和菜单 VIEW -> Perference -> Global Settings 把display commands in logging console 下面几个都勾上即可。

PicoDiagnostics (NVH设备软件)-Mongoose识别不了VIN码

如果Mongoose J2534诊断线识别不到车辆的VIN码&#xff0c;通常在PD软件中会像下图那样提示。 遇到这种情况&#xff0c;首先确保你的电脑是否已经安装J2534驱动&#xff1a;打开【设备管理器】&#xff0c;如果你将示波器和Mongoose J2534诊断线连接到电脑&#xff0c;【设备管…

C语言数组首地址学习1

C语言数组名也是数组首地址&#xff1b;数组首地址&#xff0c;也就是数组首元素地址&#xff1b; 数组首地址也可以用第0个元素加&表示&#xff0c;数值a的首地址是&a[0]&#xff1b; #include <stdio.h> int main(){int nums[5];int i;//从控制台读取用户输…