包管理工具

目录

  • 全文概要
  • 概念介绍
    • 代码共享方案
    • 包是什么
    • 包管理工具
    • 常用的包管理工具
  • npm
    • npm 的安装
    • npm 基本使用
      • 初始化
      • 配置文件
      • 搜索包
      • 下载安装包
      • require 导入 npm 包基本流程
    • 项目安装
      • 生产环境与开发环境
      • 生产依赖与开发依赖
    • npm install 原理
    • package-lock.json
    • npm其他常用命令
    • 配置命令别名
    • 拓展:windows全局安装
      • 修改 windows 执行策略
      • 环境变量 Path
  • cnpm
    • 介绍
    • 安装
    • 操作命令
    • npm 配置淘宝镜像
  • yarn
    • yarn 介绍
    • yarn 特点
    • yarn 安装
    • yarn 常用命令
    • yarn 配置淘宝镜像
    • npm 和 yarn 选择
  • 包发布流程
    • 创建与发布
    • 更新包
    • 删除包
  • npx工具
    • 局部命令的执行
  • pnpm
    • 硬连接和软连接的概念
    • pnpm到底做了什么
    • pnpm创建非扁平的 node_modules 目录
    • pnpm的安装和使用
    • pnpm的存储store
  • 扩展内容

全文概要

包管理工具总结:

这一章,主要讲解了包管理工具,包括对于包、包管理工具

**包:**一组特定功能的源码合集

**包管理工具:**通过包管理工具对包进行管理,包括下载、更新、删除包等等。常见的前端包管理工具有npm、yarn、cnpm、pnpm这些。

npm的使用:

// 初始化包
npm init -y
// 下载包
npm install

package.json:

作用:记录项目详细信息的配置文件,包括项目版本信息,以及项目所依赖的库信息等。

常见属性:name、version、description

重要属性:

main:用于设置程序的入口,比如 index.js

scripts:用于配置一些脚本命令,比如 startservedevbuild、等等

package-lock.json

作用:

1-记录项目依赖包的固定版本

package.json 中记录的包的版本相对宽松,package-lock.json 则记录的较为固定,针对当前项目的包做记录。

2-查找包的缓存

比如可以通过package-lock.json的 Intergrity 来查找包对应的缓存

注意:


npm install 原理

image.png

结合例子来说明一整个流程:

比如我们安装 axios ,通过 npm install axios

npm会判断 lock 文件,如果没有:

首先,构建包的依赖关系,判断 axios 所依赖的各项包

然后,通过 registry仓库 下载压缩包

其次,npm对拿到的包进行缓存处理

接着,将压缩包解压到 node_modules

最后,生成 package-lock.json 文件。

如果有:

首先,会检测包的依赖一致性,比如下载的 axios 包以及依赖包的版本是多少,是否是最新的,还是需要按照一定特定的版本来处理,这些问题需要在依赖分析环节处理好。

然后,npm 会查找缓存,如果有对应依赖包的话,就会进行下一步,如果没有的话,就会从 registry仓库进行压缩包的下载。

其次,npm对拿到的包进行缓存处理。

接着,将压缩包解压到 node_modules 中。

最后,生成 package-lock.json 文件。


cnpm、yarn

cnpm:由 淘宝 构建的npm的完整镜像,由于服务部署在国内的阿里云上,所以包的下载速度很快

yarn:由 Facebook 出品,特点就是速度特别快,然后安全且可靠。


包的发布过程

创建 index.js 文件,通过 module.exports 暴露所需的属性与方法。

采用npm init初始化包,

npm包的发布过程:

1-包构建:创建文件夹,并创建文件 index.js, 在文件中声明函数,使用 module.exports 暴露

2-初始化:npm init 工具包,package.json 填写包的信息 (包的名字是唯一的)

3-登陆:在命令行登陆 npm login

4-发布:npm publish 发布到 npm registry

5-更新仓库:1.修改版本号(最好符合semver规范) 2.重新发布

在 package.json 中进行修改,然后再发布


npx

作用:主要用于调用项目中的某个模块的指令。

比如现在我想要使用项目的webpack,而非全局的webpack。我可以有几种做法,

比如我可以在 node_module 下去执行 webpack —version 这个命令,也可以去在 package.json 文件中去设定 script 脚本来执行 webpack —version 命令,那最终呢,其实都是为了查看当前项目的webpack的版本。

那其实,还有一种最合适的方式,就是通过 npx webpack —version 来执行,它会自动项目目录的 node_modules/bin 目录下查找对应的命令。


pnpm

概念:高性能的npm

特点:

1-节省空间:

  • 依赖包统一存储在硬盘的指定位置,通过 .pnpm store 连接到此
  • 同一依赖包磁盘上只存储一份,若需要使用不同版本,则对版本间不同的文件进行分开存储。

2-包的扁平化管理:旨在解决包的引用问题

  • 通过软硬连接解决包重复依赖问题

举例:

1-项目中引用包 axios

2-axios包会引用 node_modules/axios,它是个软连接,并引向 .pnpm/axios@1.7.7 ,它是硬连接,指向 .pnpm store

3-.pnpm store 指向磁盘

image.png

常用命令:

// 项目中已经有 package.json 后,通过 install 来安装
pnpm install
// 新增 包
pnpm add <pkg> 



概念介绍

代码共享方案

image.png

1-通过官网或者Github来下载,并通过

问题:需要手动引入,并且需要长期自己去维护版本。

2-通过包管理工具来进行包管理

优点:通过 npm install 来维护版本包即可



包是什么

概念:『包』英文单词是 package ,代表了一组特定功能的源码集合



包管理工具

管理『包』的应用软件,可以对「包」进行 下载,安装 ,更新,删除,上传 等操作

借助包管理工具,可以快速开发项目,提升开发效率 。同时,其他程序员也可以直接通过工具来安装、升级、删除我们的工具代码。

包管理工具是一个通用的概念,很多编程语言都有包管理工具,所以 掌握好包管理工具非常重要。



常用的包管理工具

下面列举了前端常用的包管理工具

  • npm
  • yarn
  • cnpm



npm

**概念:**npm 全称 Node Package Manager ,翻译为中文意思是『Node 的包管理工具』

npm 是 node.js 官方内置的包管理工具,是 必须要掌握住的工具

包存放位置:

我们发布自己的包其实是发布到registry上面的;

当我们安装一个包时其实是从registry上面下载的包;

官网:https://www.npmjs.org



npm 的安装

node.js 在安装时会 自动安装 npm ,所以如果你已经安装了 node.js,可以直接使用 npm

可以通过 npm -v 查看版本号测试,如果显示版本号说明安装成功,反之安装失败

查看版本时可能与上图版本号不一样,不过不影响正常使用



npm 基本使用

初始化

创建一个空目录,然后以此目录作为工作目录 启动命令行工具 ,执行 npm init

npm init命令的作用是将文件夹初始化为一个『包』, 交互式创建 package.json 文件

package.json 是包的配置文件,每个包都必须要有 package.json


配置文件

配置文件:package.json

项目的配置文件记录你项目的名称、版本号、项目描述等,以及项目所依赖的其他库的信息和依赖库的版本号。

配置文件获取方式:

方式一:手动从零创建项目,npm init –y

注意:-y表示所有都是yes

方式二:通过脚手架创建项目,脚手架会帮助我们生成package.json,并且里面有相关的配置。

常见的配置文件:

image.png

了解:我们可以通过框架的脚手架来创建一个项目,省去npm install一堆文件的烦恼

**必须填写的属性:**name、version

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

private属性:

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

main属性:

  • 设置程序的入口

理解:我们可以通过包的 package.json 文件来设置 main 属性,从而设定包的程序入口

案例:

比如我们使用 axios 模块 const axios = require('axios');

通过 axiospackage.json 文件可以查看到 main 属性,那最终我们可以通过 main 属性来找到 axios 包的程序入口

image.png

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等工具的工作原理,所以不再给出详情);

依赖的版本管理:

我们会发现安装的依赖版本出现:^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永远安装最新的版本;

package.json 内容示例:

{"name": "01_npm", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC"
}

属性翻译

{"name": "1-npm", #包的名字 "version": "1.0.0", #包的版本 "description": "", #包的描述 "main": "index.js", #包的入口文件 "scripts": { #脚本配置 "test": "echo \"Error: no test specified\" && exit 1" },"author": "", #作者 "license": "ISC" #开源证书
}

初始化的过程中还有一些注意事项:

1-package name ( 包名 ) 不能使用中文、大写,默认值是文件夹的名称,所以文件夹名称也不

能使用中文和大写

2-version ( 版本号 )要求 x.x.x 的形式定义, x 必须是数字,默认值是 1.0.0

3-ISC 证书与 MIT 证书功能上是相同的,关于开源证书扩展阅读 http://www.ruanyifeng.com/bl og/2011/05/how_to_choose_free_software_licenses.html

3-package.json 可以手动创建与修改

4-使用 npm init -y 或者 npm init --yes 极速创建 package.json


搜索包

搜索包的方式有两种

  1. 命令行 『npm s/search 关键字』
  2. 网站搜索 网址是 https://www.npmjs.com/

经常有同学问,『我怎样才能精准找到我需要的包?』 这个事儿需要大家在实践中不断的积累,通过看文章,看项目去学习去积累


下载安装包

安装npm包分两种情况:

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

对于全局安装的理解:

通常使用npm全局安装的包都是一些工具包:yarn、webpack等;

并不是类似于 axios、express、koa等库文件;

所以全局安装了之后并不能让我们在所有的项目中使用 axios 等库;

理解:

比如我们安装qq之后,可以把qq.exe添加到环境变量中,这样我们在命令行中敲入qq,就可以直接唤起qq应用程序。

再举一个例子,当敲入命令 npm install webpack -g ,这样webpack会被安装到一个node专门管理的目录,而且这个目录被添加到环境变量中。当webpack全局安装成功,我们就可以在命令行中敲入webpack的命令了。


运行之后文件夹下会增加两个资源

  • node_modules 文件夹 存放下载的包
  • package-lock.json 包的锁文件 ,用来锁定包的版本

安装 uniq 之后, uniq 就是当前这个包的一个 依赖包 ,有时会简称为 依赖

比如我们创建一个包名字为 A,A 中安装了包名字是 B,我们就说 B 是 A 的一个依赖包, 也会说 A依赖B


require 导入 npm 包基本流程

1-在当前文件夹下 node_modules 中寻找同名的文件夹

2-在上级目录中下的 node_modules 中寻找同名的文件夹,直至找到磁盘根目录

案例:

需求:自己手动创建包,并且引入

实现步骤:

1-文件 why 文件夹

2-设置 why 文件夹中的 index.js 文件

3-在 main.js 中通过 require 来引入创建的包

image.png



项目安装

生产环境与开发环境

开发环境是程序员 专门用来写代码 的环境,一般是指程序员的电脑,开发环境的项目一般 只能程序员自己访问

生产环境是项目 代码正式运行 的环境,一般是指正式的服务器电脑,生产环境的项目一般 每个客户都可以访问


生产依赖与开发依赖

我们可以在安装时设置选项来区分 依赖的类型 ,目前分为两类:

类型命令补充
生产依赖npm i -S uniq
npm i --save uniq-S 等效于 --save, -S 是默认选项
包信息保存在 package.json 中 dependencies 属性
开发依赖npm i -D less
npm i --save-dev less-D 等效于 --save-dev
包信息保存在 package.json 中 devDependencies 属性

举个例子方便大家理解,比如说做蛋炒饭需要 大米 , 油 , 葱 , 鸡蛋 , 锅 , 煤气 , 铲子 等

其中 锅 , 煤气 , 铲子 属于开发依赖,只在制作阶段使用

而 大米 , 油 , 葱 , 鸡蛋 属于生产依赖,在制作与最终食用都会用到

所以 开发依赖 是只在开发阶段使用的依赖包,而 生产依赖 是开发阶段和最终上线运行阶段都用到的依赖包

举例:

局部安装分为开发时依赖和生产时依赖:

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


npm install 原理

问题:

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

npm install 的原理图:

image.png

步骤:

1-查看是否有 lock 文件

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

没有lock文件

  • 分析依赖关系,这是因为包可能会依赖其他的包,并且多个包之间会产生相同依赖的情况;
  • 从registry仓库中下载压缩包(如果我们设置了镜像,那么会从镜像服务器下载压缩包);
  • 获取到压缩包后会对压缩包进行缓存(从npm5开始有的);
  • 将压缩包解压到项目的node_modules文件夹中(前面我们讲过,require的查找顺序会在该包下面查找)

有lock文件

检测lock中包的版本是否和package.json中一致(会按照semver版本规范检测);

: 不一致,那么会重新构建依赖关系,直接会走顶层的流程;

一致的情况下,会去优先查找缓存

: 没有找到,会从registry仓库下载,直接走顶层流程;

查找到,会获取缓存中的压缩文件,并且将压缩文件解压到node_modules文件夹中;

结合例子理解:

比如 npm install axios

首先会检测是否有 lock 文件,如果没有,则会构建依赖关系,然后从 registry 仓库中下载压缩包,并把获取到的压缩包进行缓存,最后把压缩包解压到项目的 node_modules 文件夹中。

在以上搞定之后,会生成 package-lock.json 文件

image.png

此时,如果我们把 node_modules 文件删除,再次通过 npm i axios 对axios进行安装:

首先会检测依赖文件的一致性,如果一致,则会查找缓存,若找到,会获取缓存中的压缩文件,并且将压缩文件解压到node_modules文件夹中。



package-lock.json

作用:

1-查找包的缓存

2-检测依赖一致性

在查找缓存的过程中,如何确定包,比如确定是 axios ,需要标识符来确定,那就可以通过 package-lock.json 来确定,它里面保存了对应包的标识符,npm会根据这个标识符来查找对应的包

其次,不同项目使用的 axios 的版本可能会不一致,此时不同项目就可以通过 package-lock.json 来确定对应项目的包的版本。

package-lock.json文件解析:

image.png

  • name:项目的名称;

  • version:项目的版本;

  • lockfileVersion:lock文件的版本;

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

    • 这个如果true的话,表示下面的dependencies中的包的依赖库,既可以是 requires,也可以是dependecies (早期的时候,包的依赖的库是用 requires)

      image.png

  • dependencies:项目的依赖

当前项目依赖axios,但是axios依赖follow-redireacts;

比如axios中的属性如下:

  • version表示实际安装的axios的版本;
  • resolved用来记录下载的地址,registry仓库中的位置;
  • requires/dependencies记录当前模块的依赖;
  • integrity用来从缓存中获取索引,再通过索引去获取压缩包文件;
    • 后面的数值表示一段通过算法生成的 标识,通过解析这个标识,能够生成对应的目录结构。npm会先从这个目录文件中去获取缓存文件,如拿不到,则会从对应的远程仓库中进行下载。


npm其他常用命令

卸载某个依赖包

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

强制重新build

npm rebuild

清除缓存

npm cache clean

安装指定版本的包

项目中可能会遇到版本不匹配的情况,有时就需要安装指定版本的包,可以使用下面的命令的

## 格式 
npm i <包名@版本号> ## 示例 
npm i jquery@1.11.2

删除依赖

项目中可能需要删除某些不需要的包,可以使用下面的命令

## 局部删除 
npm remove uniq 
npm r uniq ## 全局删除 
npm remove -g nodemon

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

https://docs.npmjs.com/cli-documentation/cli

更多的命令,可以根据需要查阅官方文档



配置命令别名

通过配置命令别名可以更简单地执行命令

配置 package.json 中的 scripts 属性

{..."scripts": {"server": "node server.js","start": "node index.js", }, ..
}

配置完成之后,可以使用别名执行命令

npm run server 
npm run start

不过 start 别名比较特别,使用时可以省略 run

npm start

补充说明:

  • npm start是项目中常用的一个命令,一般用来启动项目
  • npm run 有自动向上级目录查找的特性,跟 require 函数也一样
  • 对于陌生的项目,我们可以通过查看 scripts 属性来参考项目的一些操作



拓展:windows全局安装

我们可以执行安装选项 -g 进行全局安装

npm i -g nodemon

全局安装完成之后就可以在命令行的任何位置运行 nodemon 命令

该命令的作用是 自动重启 node 应用程序

说明:

  • 全局安装的命令不受工作目录位置影响
  • 可以通过 npm root -g 可以查看全局安装包的位置
  • 不是所有的包都适合全局安装 , 只有全局类的工具才适合,可以通过查看包的官方文档来确定安装方式,这里先不必太纠结

修改 windows 执行策略

Untitled

windows 默认不允许 npm 全局命令执行脚本文件,所以需要修改执行策略

1-以 管理员身份 打开 powershell 命令行

2-键入命令 set-ExecutionPolicy remoteSigned

Untitled

3-键入 A 然后敲回车 👌

4-如果不生效,可以尝试重启 vscode


环境变量 Path

Path 是操作系统的一个环境变量,可以设置一些文件夹的路径,在当前工作目录下找不到可执行文件 时,就会在环境变量 Path 的目录中挨个的查找,如果找到则执行,如果没有找到就会报错

Untitled

补充说明:

  • 如果希望某个程序在任何工作目录下都能正常运行,就应该将该程序的所在目录配置到环境 变量 Path 中
  • windows 下查找命令的所在位置 cmd 命令行 中执行 where nodemon
    • powershell命令行
    • 执行get-command nodemon



cnpm

介绍

cnpm 是一个淘宝构建的 npmjs.com 的完整镜像,也称为『淘宝镜像』,网址https://npmmirror.com/

cnpm 服务部署在国内 阿里云服务器上 , 可以提高包的下载速度

官方也提供了一个全局工具包 cnpm ,操作命令与 npm 大体相同



安装

我们可以通过 npm 来安装 cnpm 工具

npm install -g cnpm --registry=https://registry.npmmirror.com


操作命令

功能命令
初始化cnpm init / cnpm init
安装包cnpm i uniq
cnpm i -S uniq
cnpm i -D uniq
cnpm i -g nodemon
安装项目依赖cnpm i
删除cnpm r uniq


npm 配置淘宝镜像

用 npm 也可以使用淘宝镜像,配置的方式有两种

  • 直接配置
  • 工具配置

直接配置

执行如下命令即可完成配置

npm config set registry https://registry.npmmirror.com/

工具配置

使用 nrm 配置 npm 的镜像地址 npm registry manager

1-安装 nrm

npm i -g nrm

2-修改镜像

nrm use taobao

3-检查是否配置成功(选做)

npm config list

检查 registry 地址是否为 https://registry.npmmirror.com/ , 如果 是 则表明成功

补充说明:

1-建议使用第二种方式 进行镜像配置,因为后续修改起来会比较方便

2-虽然 cnpm 可以提高速度,但是 npm 也可以通过淘宝镜像进行加速,所以 npm 的使用率还是高于 cnpm




yarn

yarn 介绍

yarn 是由 Facebook 在 2016 年推出的新的 Javascript 包管理工具,官方网址: https://yarnpkg.com/



yarn 特点

yarn 官方宣称的一些特点

  • 速度超快:yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大 化资源利用率,因此安装速度更快
  • 超级安全:在执行代码之前,yarn 会通过算法校验每个安装包的完整性
  • 超级可靠:使用详细、简洁的锁文件格式和明确的安装算法,yarn 能够保证在不同系统上无差异的 工作


yarn 安装

我们可以使用 npm 安装 yarn

npm i -g yarn


yarn 常用命令

功能命令
初始化yarn init / yarn init -y
安装包yarn add uniq 生产依赖
yarn add less --dev 开发依赖
yarn global add nodemon 全局安装
删除包yarn remove uniq 删除项目依赖包
yarn global remove nodemon 全局删除包
安装项目依赖yarn
运行命令别名yarn <别名> # 不需要添加 run

思考题:

这里有个小问题就是 全局安装的包不可用 ,yarn 全局安装包的位置可以通过 来查看,

那你有没有办法使 yarn 全局安装的包能够正常运行?



yarn 配置淘宝镜像

可以通过如下命令配置淘宝镜像

yarn config set registry https://registry.npmmirror.com/

可以通过 yarn config list 查看 yarn 的配置项



npm 和 yarn 选择

大家可以根据不同的场景进行选择

  1. 个人项目
    1. 如果是个人项目, 哪个工具都可以 ,可以根据自己的喜好来选择
  2. 公司项目
    1. 如果是公司要根据项目代码来选择,可以 通过锁文件判断 项目的包管理工具
      1. npm 的锁文件为 package-lock.json
      2. yarn 的锁文件为 yarn.lock

包管理工具不要混着用,切记,切记,切记




包发布流程

创建与发布

我们可以将自己开发的工具包发布到 npm 服务上,方便自己和其他开发者使用,操作步骤如下:

准备工作:

npm账号注册:https://www.npmjs.com/signup

自定义npm包发布:

1-创建文件夹,并创建文件 index.js, 在文件中声明函数,使用 module.exports 暴露

2-npm 初始化工具包,package.json 填写包的信息 (包的名字是唯一的)

3-登陆:在命令行登陆 npm login

4-发布:npm publish 发布到 npm registry

5-更新仓库:1.修改版本号(最好符合semver规范) 2.重新发布

在 package.json 中进行修改,然后再发布

自定义npm包使用:

建议:可以在webpack环境下去使用,从而可以使用 ES Module

先下载 webpack

npm i webpack webpack-cli

然后执行 webpack 进行打包

npx webpack

最后,在 src/index.html 中加载打包后的代码

<script src="./dist/main.js"></script>

致此,即可完整使用自定义的包

一些命令:

删除发布的包:npm unpublish

让发布的包过期:npm deprecate

案例:

1-创建文件夹,并创建文件 index.js, 在文件中声明函数,使用 module.exports 暴露

2-npm 初始化工具包,package.json 填写包的信息 (包的名字是唯一的)

image.png

3-登陆:在命令行登陆 npm login

4-发布:npm publish 发布到 npm registry



更新包

后续可以对自己发布的包进行更新,操作步骤如下

  1. 更新包中的代码
  2. 测试代码是否可用
  3. 修改 package.json 中的版本号
  4. 发布更新
npm publish


删除包

执行如下命令删除包

npm unpublish --force

删除包需要满足一定的条件, https://docs.npmjs.com/policies/unpublish

  • 你是包的作者
  • 发布小于 24 小时
  • 大于 24 小时后,没有其他包依赖,并且每周小于 300 下载量,并且只有一个维护者



npx工具

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

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

我们以webpack为例:

全局安装的是webpack5.1.3

项目安装的是webpack3.6.0

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

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

如何解决这个问题呢?



局部命令的执行

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

方式一:明确查找到node_module下面的webpack

方式二:在 scripts定义脚本,来执行webpack;

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

./node_modules/.bin/webpack --version

nathanchen@192 test_npx % ./node_modules/.bin/webpack --version
3.6.0

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

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

理解:如果我们在 package.json 的 script 中去执行某个命令,那么它优先会去 node_modules 下去查找对应的文件。

方式三:使用npx

npx webpack --version

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




pnpm

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

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

image.png

解决的痛点:

1-解决多项目占据相同的包的问题,以节省大量空间。

2-包的扁平化管理

哪些公司在用呢?

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



硬连接和软连接的概念

硬链接(hard link):

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

理解:我们将mp4的数据存储到磁盘中。然后通过操作系统下的文件系统来找到这个存储位置。

比如,我们通过文件系统下的 test.mp4 来定位到磁盘中的 Data 。以上的连接的称之为硬连接。

image.png

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

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

理解:软连接的本质是保存的文件的路径。比如我们在桌面创建一个名叫shortcut的快捷方式,点击它可以链接访问到 test.mp4 。以上的连接称之为软连接。

image.png

参考用图:

image.png

硬链接和软连接的演练

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

image.png

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

文件的硬链接

image.png

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

文件的软连接:

image.png

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


pnpm到底做了什么

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

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

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

理解:

比如现在通过 pnpm 来安装 axios,pnpm会在某地保存一份 axios 文件的硬连接,指向磁盘中 axios的实际存储位置。当 Project 1 需要使用 axios 时,只需要重新建立一次硬连接,指向磁盘中的 axios即可。

image.png

image.png



pnpm创建非扁平的 node_modules 目录

当使用 npm 或 Yarn Classic 安装依赖包时,所有软件包都将被提升到 node_modules 的 根目录下。其结果是,源码可以访问 本不属于当前项目所设定的依赖包;

image.png

简单总结一下:

1-项目中引用包 axios

2-axios包会引用 node_modules/axios,它是个软连接,并引向 .pnpm/axios@1.7.7 ,它是硬连接,指向 .pnpm store

3-.pnpm store 指向磁盘

理解:

早期的npm的包管理方式是非扁平的,比如 node_modules 下包含 webpack,然后 webpack 又包含对应所需的一些包,如此形成一个层层的结构。

node_moduleswebpacknode_modulesajvanymatchbabelnode_modulesanymatch

问题是,比如现在有 babel,里面也包含 anymatch,就会导致它和 webpack 中 anymatch 的包重复。因此到后期,npm就开始变成扁平化。

node_moduleswebpackbabelajvanymatch

但是扁平化也会造成一定的问题。比如说,当我们在项目中引入 webpack 包,它会自动引入 anymatch,而在项目的 package.json 中并没有记录这个包。问题是,我们依然可以在项目中去引用这个包的内容,这就会导致当我们删除 webpack 后,项目中又需要使用 anymatch 包,但是删除的过程会顺带把 anymatch 删除,从而导致项目无法正常运行。

srcmain.js| const webpack = require("webpack")| const anymatch = require("anymatch")
package.json

案例:

目标:练习使用 pnpm

步骤:

1-初始化 pnpm

nathanchen@192 pnpm_test % pnpm init           
Wrote to /Users/nathanchen/Downloads/pnpm_test/package.json{"name": "pnpm_test","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC"
}
nathanchen@192 pnpm_test % pnpm --version
8.6.11

2-加入 axios 包

nathanchen@192 pnpm_test % pnpm add axios                  ╭─────────────────────────────────────────────────────────────────╮│                                                                 ││                Update available! 8.6.11 → 9.9.0.                ││   Changelog: https://github.com/pnpm/pnpm/releases/tag/v9.9.0   ││                Run "pnpm add -g pnpm" to update.                ││                                                                 ││     Follow @pnpmjs for updates: https://twitter.com/pnpmjs      ││                                                                 │╰─────────────────────────────────────────────────────────────────╯Packages: +9
+++++++++
Packages are hard linked from the content-addressable store to the virtual store.Content-addressable store is at: /Users/nathanchen/Library/pnpm/store/v3Virtual store is at:             node_modules/.pnpm
Progress: resolved 9, reused 7, downloaded 2, added 9, donedependencies:
+ axios 1.7.7Done in 2.2s

pnpm包的查找过程,以及处理包的扁平化问题:

index.js通过 node_modules 下的 axios 软连接找到 .pnpm 下的 axios ,然后这里再通过硬连接连接到磁盘中 axios 真实存在的位置。

.pnpm/axios@1.7.7/node_modules/form-data 本身又是一个软连接,连接到 .pnpm/form-data@4.0.0 ,然后在这里再通过硬连接连接到磁盘的真实位置。从而通过这种方式,来处理在index.js中可能引用form-data 包的问题。

image.png



pnpm的安装和使用

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

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

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

npm 命令pnpm 等价命令备注
npm installpnpm install项目中已经有 package.json 后,通过 install 来安装
npm install pnpm add
npm uninstall pnpm remove
npm run pnpm

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



pnpm的存储store

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

在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



扩展内容

在很多语言中都有包管理工具,比如:

语言包管理工具
PHPcomposer
Pythonpip
Javamaven
Gogo mod
JavaScriptnpm/yarn/cnpm/other
RubyrubyGems

除了编程语言领域有包管理工具之外,操作系统层面也存在包管理工具,不过这个包指的是『 软件包 』

操作系统包管理工具网址
Centosyumhttps://packages.debian.org/stable/
Ubuntuapthttps://packages.ubuntu.com/
MacOShomebrewhttps://brew.sh/
Windowschocolateyhttps://chocolatey.org/

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

HarmonyOS ArkTS 用户首选项的开发及测试

本节以一个“账本”为例&#xff0c;使用首选项的相关接口实现了对账单的增、删、改、查操作&#xff0c;并使用自动化测试框架arkxtest来对应用进行自动化测试。 为了演示该功能&#xff0c;创建一个名为“ArkTSPreferences”的应用。应用源码可以在文末《跟老卫学HarmonyOS开…

【齐家网-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

医学数据分析实训 项目十 基于深度残差神经网络的皮肤癌检测

文章目录 综合实践三 基于深度残差神经网络的皮肤癌检测实现步骤1&#xff1a;图像数据预处理实现步骤2&#xff1a;模型构建实现步骤3&#xff1a;性能度量提交要求 1 基于深度残差神经网络的皮肤癌检测代码2 结果分析 综合实践三 基于深度残差神经网络的皮肤癌检测 皮肤镜图…

毕业设计选题:基于ssm+vue+uniapp的校园商铺系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

828华为云征文 | 在华为云X实例上部署微服务架构的文物大数据管理平台的实践

前言 文物大数据管理平台的需求日益增长&#xff0c;要求系统具备强大的数据存储、智能查询和数据分析功能。通过微服务架构&#xff0c;平台可以灵活地管理用户、文件存储、文物知识、资源管理以及报表统计等模块。本文将以实际案例为基础&#xff0c;详细介绍如何在华为云Fl…

实现西门子PLC与发那科机器人通讯接收正负值偏移

PLC与发那科机器人通讯组信号的无法接受负数&#xff0c;并且高低字节取反&#xff1b; 解决办法如下&#xff1a; 在发送数据时双方约定一个基数&#xff0c;通讯时双方上这个值&#xff0c;或减去这个值即可&#xff1b; 如下图&#xff0c;当前约定收发数据范围为-20到20之…

【2024】前端学习笔记8-内外边距-边框-背景

学习笔记 外边距&#xff1a;Margin内边距&#xff1a;Padding边框&#xff1a;Border背景&#xff1a;Background 外边距&#xff1a;Margin 用于控制元素周围的空间&#xff0c;它在元素边框之外创建空白区域&#xff0c;可用于调整元素与相邻元素&#xff08;包括父元素和兄…

ORCA-3D避障代码和原理解析

二维ORCA原理参考&#xff1a; https://zhuanlan.zhihu.com/p/669426124 ORCA原理图解代码解释 1. 找到避障速度增量 u 碰撞处理分为三种情况&#xff1a; &#xff08;1&#xff09;没有发生碰撞&#xff0c;且相对速度落在小圆里 &#xff08;2&#xff09;没有发生碰撞&a…

蓝星多面体foc旋钮键盘复刻问题详解

介绍&#xff1a; 本教程是针对立创开源项目 承载我所有幻想的键盘 - 立创开源硬件平台 作者是 蓝星多面体 这里我总结一下我复刻过程中的一些问题 一 <<编译环境怎么搭建&#xff1f;>> 第一步 安装vscode 下载vscode &#xff08;可以在各大应用平台…

如何删除EXCELL文件中的空行?

1&#xff0c;选择某一列 2&#xff0c;点击《开始》《查找和选择》>《定位条件》&#xff0c;调出《定位条件》的选择框&#xff1b; 3&#xff0c;在定位条件选项框&#xff0c;选择《空值》&#xff1b; 4&#xff0c;找到变灰被选中的某一行&#xff0c;右击《删除》 5&…

高级算法设计与分析 学习笔记6 B树

B树定义 一个块里面存了1000个数和1001个指针&#xff0c;指针指向的那个块里面的数据大小介于指针旁边的两个数之间 标准定义&#xff1a; B树上的操作 查找B树 创建B树 分割节点 都是选择正中间的那个&#xff0c;以免一直分裂。 插入数字 在插入的路上就会检查节点需不需要…

Qt 类型选择器和类选择器的区别

概念上的区别请查看此篇博客&#xff1a;Qt 样式表、选择器、盒子模型&#xff0c;下面我直接举例说明。 示例界面&#xff1a; 1、类型选择器&#xff1a; QWidget {background-color: rgb(255, 85, 127); }运行结果&#xff08;因为QPushButton是QWidget的子类&#xff0…

MongoDB的备份和恢复命令

一、下载 MongoDB Database Tools 官方网址&#xff1a;Download MongoDB Command Line Database Tools | MongoDB 将解压后的文件夹移动到MongoDB的bin目录下&#xff0c;同时配置mongodb-database-tools的bin目录进入环境变量。 以上有问题请参考文章&#xff1a;使用cmd命…

已解决npm ERR! request to https://registry.npm.taobao.org/@vant%2farea-data failed

在npm insrall的时候&#xff0c;报错&#xff0c;完整报错如下 简单来说就是淘宝原镜像域名&#xff08;http://registry.npm.taobao.org&#xff09;的 HTTPS 证书到期了&#xff0c;导致npm在使用镜像的时候报错&#xff0c;需要更换镜像域名。 清空缓存 npm cache clean …

计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI

首先安装需要的python库&#xff0c; 安装完之后利用navicat导入数据库文件bili100.sql到mysql中&#xff0c; 再在pycharm编译器中连接mysql数据库&#xff0c;并在设置文件中将密码修改成你的数据库密码。最后运行app.py&#xff0c;打开链接&#xff0c;即可运行。 B站爬虫数…

pytorch学习笔记一:作用、安装和基本使用方法、自动求导机制、自制线性回归模型、常见tensor格式、hub模块介绍

文章目录 一、安装二、基本使用方法①创建一个矩阵②获得随机值③初始化全零矩阵④直接传入数据⑤构建矩阵&#xff0c;然后随机元素值⑥展示矩阵大小⑦矩阵计算8、取索引9、view操作&#xff1a;改变矩阵维度10、与numpy的协同操作 三、自动求导机制1&#xff09;定义tensor成…

介绍一下常用的激活函数?

常用的激活函数 Sigmoid函数Tanh函数ReLU函数Leaky ReLU函数Softmax函数 Sigmoid函数 特点&#xff1a; 将任意实数映射到(0,1)区间内&#xff0c;输出值可以作为概率来解释。 函数平滑且易于求导&#xff0c;但其导数在两端趋近于0&#xff0c;即存在梯度消失问题。 输出值不…

算法训练——day18 两数之和三数之和

1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回…

【Java版】云HIS系统源码

云HIS系统介绍 云HIS系统是一款满足基层医疗机构各类业务需要的健康云产品。该产品能帮助基层医疗机构完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;还能与公卫、PACS等各类…

【有啥问啥】深入解析:机器学习中的过拟合与欠拟合

深入解析&#xff1a;机器学习中的过拟合与欠拟合 在机器学习中&#xff0c;过拟合&#xff08;overfitting&#xff09;和欠拟合&#xff08;underfitting&#xff09;是模型性能中常见的两大挑战。它们反映了模型的学习能力与泛化能力的不平衡&#xff0c;直接影响模型在训练…