当前位置: 首页 > news >正文

前端包管理器的发展以及Npm、Yarn和Pnpm对比

在现代前端开发中,包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展,开发者经历了从 npm 一统天下到 Yarn 挑战格局,再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器(npm/Yarn/pnpm)进行全方位对比,分析其设计原理、性能表现和适用场景。

剖析package.json

现代前端工程中不管使用那种打包工具,都一定有一个该项目的描述文件,这个文件就是package.json,这个文件有很多描述当前工程的字段,我将其汇总如下图展示:
在这里插入图片描述
如上面图示,必填的字段有nameversion,这两个属性组成一个npm模块的唯一标识

npm install原理详解

npm的发展

npm@2

在早期的npm(npm2)安装依赖时,处理方式非常的简单粗暴,就是以递归的形式,严格按照package.json的结构以及子依赖包的package.json结构进行安装,直至子依赖包不在依赖其他模块。比如说有一个项目要-app依赖了两个模块moduleA 和moduleB,而模块A是一个纯js模块不依赖其他模块,但moduleB又依赖了moduleB1和moduleB2那最后的目录结构就是这样的:
在这里插入图片描述
这样的方式优点是层级结构明显,node_module的结构和package.json的目录结构一致,并且可以保证每次安装的目录结构都是一样的。但是如果我们的项目非常的庞大,依赖的模块很多很复杂,那么嵌套的层就会非常的深,如下图所示

在这里插入图片描述
除此之外,如果不同层级的模块依赖了相同的模块,就会导致大量的冗余。在windows系统中,文件路径的最大长度是260个字符,如果层级过深就会导致不可预知的问题。

npm@3

为了解决上面的问题,NPM在3.x版本中做了一次比较大的更新。将嵌套的结构改成扁平的结构,安装模块时不管是直接依赖还是子依赖的依赖,优先将其安装在node_module目录下。还是上面的例子,安装之后我们会得到下面的目录结构
在这里插入图片描述
如果此时我们有新的模块依赖了moduleB2的某个版本此时就会检查,如果当前的moduleB2的版本符合我们的要求就会跳过,否则就会在当前模块下的node_module下安装新的moduleB2的模块。如下图所示:
在这里插入图片描述
这样不仅没有完全解决老的问题(依赖还是会嵌套的越来越深)并且还会引入一个新的问题,由于在执行npm install 时是按照package.json的依赖顺序依次解析的,如果moduleAmoduleB的解析顺序就决定了目录结构,如果此时先解析了moduleA那么目录结构可能是这样的:
在这里插入图片描述
此外,我们在实际开发中有时为了使用最新版本只会锁定大的版本,这就导致某些依赖的小版本更新后也会造成依赖的改动,这种依赖结构的不确定性可能会给程序带来不可预知的问题。

npm@5+

为了解决npm install不确定性的问题,在npm@5的这个版本中新增了一个package-lock.json文件,而安装的方式还是沿用了之前npm3的扁平方式。但是因为有了package-lock.json可以锁定依赖结构的,只要项目目录下有这个文件,每次执行npm install后生成的node_module结构一定都是相同的。
package.lock.json的结构如下:
在这里插入图片描述
最外面的两个属性 name 、version 同 package.json 中的 name 和 version ,用于描述当前包名称和版本。
dependencies 是一个对象,对象和 node_modules 中的包结构一一对应,对象的 key 为包名称,值为包的一些描述信息:

  • version:包版本 —— 这个包当前安装在 node_modules 中的版本;
  • resolved:包具体的安装来源;
  • integrity:包 hash 值,基于 Subresource Integrity 来验证已安装的软件包是否被改动过、是否已失效;
  • requires:对应子依赖的依赖,与子依赖的 package.json 中 dependencies的依赖项相同。;
  • dependencies:结构和外层的 dependencies 结构相同,存储安装在子依赖 node_modules 中的依赖包‘’
    这里注意,并不是所有的子依赖都有 dependencies 属性,只有子依赖的依赖和当前已安装在根目录的 node_modules 中的依赖冲突之后,才会有这个属性。

其他npm6+

在这之后npm也一直在更新,比如npm6引入的npm audit,npm7的workspaces和peer依赖自动安装,这里汇总后续的每个npm的特点如下:

版本最大特点
npm 5引入 package-lock.json,提升安装速度和稳定性
npm 6npm audit 引入安全性检查,支持 npm ci,提升性能
npm 7引入工作空间支持、自动安装 peerDependencies,全新锁文件格式
npm 8性能优化、错误处理改进、增强的安全性功能
npm 9性能提升、增强的工作空间支持、npm exec 命令和更好的漏洞检测
使用建议

所以我们一般在项目应用开发中一般把package-lock.json文件提交,固定项目的文件结构,以避免带来不必要的麻烦。
当我们开发一个npm工具包时,我们开发的npm包是要被其他应用系统集成进去的,就像上面我们说到的扁平机制,如果锁定了依赖包的版本就没有办法和其他模块的依赖包共享符合版本号的依赖了,就会造成不必要的冗余,所以此时不应该把package-lock.json发布出去(npm默认也是不会吧package-lock.json发布出去就是这个原因)

npm缓存机制

当我们执行npm install npm update命令下载依赖后,如果这台机器第一次安装这个模块,除了会将依赖包安装在node_module中之外,也会在本地的缓存目录中缓存一份。我们可以通过npm config get cache查询缓存目录,比如在mac下可以看到如下:
在这里插入图片描述
在这个目录下又存在两个目录:content-v2、index-v5,content-v2 目录用于存储 tar包的缓存,而index-v5目录用于存储tar包的 hash。
npm也提供了一些命令来管理缓存数据

  • npm cache add:官方解释说这个命令主要是 npm 内部使用,但是也可以用来手动给一个指定的 package 添加缓存;
  • npm cache clean:删除缓存目录下的所有数据,为了保证缓存数据的完整性,需要加上 --force 参数;
  • npm cache verify:验证缓存数据的有效性和完整性,清理垃圾数据;
    基于缓存数据,npm 提供了离线安装模式,分别有以下几种:
  • –prefer-offline: 优先使用缓存数据,如果没有匹配的缓存数据,则从远程仓库下载;
  • –prefer-online: 优先使用网络数据,如果网络数据请求失败,再去请求缓存数据,这种模式可以及时获取最新的模块;
  • –offline: 不请求网络,直接使用缓存数据,一旦缓存数据不存在,则安装失败;
文件完整性

在我们下载依赖包结束时会进行文件完整性的校验,以此来确保我们下载的包是完整的。那这个过程是怎样的呢?
在下载依赖包之前,一般都会拿到npm对该依赖包计算的hash值,我们可以通过npm info来查看某个文件包的hash值,比如我们查看一下axios的信息:
在这里插入图片描述
当用户下载完成时,会在本地计算一次文件的hash值如果两个hash值相同则说明下载的依赖包是完整的,如果不同就会重新下载。

完整流程

  • 检查 .npmrc 文件:优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc文件 > npm 内置的 .npmrc 文件;

  • 检查项目中有无 lock 文件;

  • 无 lock 文件:

    • 从 npm 远程仓库获取包信息;
    • 根据 package.json 构建依赖树,构建过程:
      • 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录;
      • 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块;
      • 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包;
    • 在缓存中依次查找依赖树中的每个包
      • 不存在缓存:
        • 从 npm 远程仓库下载包;
        • 校验包的完整性;
        • 校验不通过:
          • 重新下载;
        • 校验通过:
          • 将下载的包复制到 npm 缓存目录;
          • 将下载的包按照依赖结构解压到 node_modules;
      • 存在缓存:将缓存按照依赖结构解压到 node_modules;
    • 将包解压到 node_modules;
    • 生成 lock 文件;
  • 有 lock 文件:

    • 检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突;
    • 如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同

整个过程如下图所示:
在这里插入图片描述

Yarn

yarn (Yet Another Resource Navigator)是 Facebook 开发的一个新的包管理器。它的开发是为了提供 NPM 当时缺乏的更高级的功能(例如版本锁定,但后续的功能npm都补充上了),同时也使其更安全、更可靠和更高效。
Yarn 现在更像是 NPM 的替代品,由于 Yarn 没有预装 Node.js,因此需要显式安装:

npm install yarn -g 

yarn的特点:

  1. 即插即用:从 Yarn 版本 2 开始,不再使用 node_modules 文件夹。相反,它会生成一个映射项目依赖关系的 .pnp.cjs 文件。这会导致更优化的依赖树和更快的项目启动和包安装;
  2. 零安装:此功能与 Plug’n’Play 结合使用,后者使用.pnp.cjs 文件来映射离线缓存中的包。这使您可以快速检索和安装已保存的软件包;
  3. 检查器:Yarn 带有一个内置的检查器,用于下载和安装包;

yarn在下载时使用了并行安装项目依赖,这在大型应用中的安装速度显著的快很多。

比如看一个简单的yarn4初始化的项目在这里插入图片描述
可以看到这个项目中安装了axios模块但没有使用node_module进行管理,而是使用了一个.pnp.cjs的文件进行管理

Yarn 和 NPM 的区别

YarnNPM
使用 yarn add 命令来安装依赖项使用 npm install 命令安装依赖项
使用并行安装依赖项按顺序安装依赖项
使用yarn.lock作为锁定文件使用package-lock.json作为锁定文件
支持即插即用功能,它会生成一个 .pnp.cjs 文件,其中包含项目的依赖关系图不支持
在安装大文件时更快安装大文件时更慢
支持零安装功能,允许您离线安装依赖项,几乎没有延迟不支持
在下载包时,它会利用包的许可信息在后台运行安全检查,以避免下载危险的脚本或导致依赖问题在 NPM 的早期版本中,安全性是一个主要问题。从版本 6 开始,每次安装包时,NPM 都会进行安全审计以避免漏洞并确保没有不兼容的依赖项
校验和验证包使用存储在 package-lock.json 文件中的 SHA-512 进行验证

Yarn 也支持 NPM 创建的 package-lock.json 文件,方便将版本数据从 NPM 迁移到 Yarn

yarn和npm3+的问题

在npm@3+ 和 yarn中,通过扁平化处理,解决依赖无法被共用,依赖层级太深的问题,所有的依赖都被平铺在node_modules中的一级目录。但是多个版本的包只有一个(最先安装的一个) 被提升上来,其余版本的包还是会嵌套安装到各自的依赖当中,之前提到的路径过长和重复安装的问题没有彻底解决。除此之外还有幽灵依赖的问题。比如本地没有显实的依赖axios这个模块,但是依赖了其他模块二其他模块依赖了axios这个模块,这就导致也会将axios模块安装到用户的node_module下,这导致用户在代码中实际也能使用axios模块的功能,显然这和我们的预期是不符合的。这就是幽灵依赖

Pnpm

pnpm,即performant npm,高性能的npm。相比起目前主流的包管理器,pnpm是速度快、节省磁盘空间的包管理器。

Pnpm性能对比

我们先看一下官网提供的性能对比数据:
在这里插入图片描述
在这里插入图片描述
可以看出,与目前主流的包管理器npm、yarn相比,无论有无cache、有无lockfile、有无node_modules,pnpm的安装速度都有明显的优势

Pnpm在磁盘中的存储

pnpm之所以这么快的最主要的原因是,pnpm通过hard link(硬连接)机制,节省磁盘空间并提升安装速度。
hard link(硬链接):多个文件名指向同一索引节点(Inode)。硬链接的作用 之一是允许一个文件拥有多个有效路径名,这样用户就可以建 立硬链接到重要的文件,以防止“误删”源数据

如果原始文件被删除,只要硬链接还存在,数据仍然可访问,文件并没有真正被删除。只有所有的硬链接都删除后,文件数据才会被清除

举个例子,如果有100各项目都依赖同一个三方模块,如果使用npm或者是yarn的话
那这个模块要被重复安装100次相同的“副本”。而使用 pnpm,package将被存放在一个统一的位置(如 Mac是 ~/.pnpm-store )。当安装软件包时,其包含的所有文件都会硬链接自此位置,而不会占用额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的package。因此,不会有上面提到的重复安装相同包的问题了。
当我们使用pnpm在本地一个项目安装axios时可以发现有个reused字段表之前已经安装过相同的包了。
而当安装版本不同的同名软件包时,仅会添加版本之间不同 的文件到存储器中,而不会因为一个文件的修改而保存package的所有文件。
同时该命令提供了一个选项,使用方法为pnpm store prune,它提供了一种用于删除一些不被全局项目所引用到的package的功能。如果需要,开发者可以用这个命令来管理已有的package。
在这里插入图片描述

Pnpm对node_Module的优化

除了节省磁盘空间,pnpm还有另一个重要特点是,建立非扁平的node_modules目录,并在引用依赖的时候通过sybolic link机制找到对应.pnpm目录的地址。我们看一下使用pnpm管理项目的node_module的目录结构
在这里插入图片描述
可以看到在node_module中都是平铺的形式管理三方依赖的模块,并且axioslodashnode_module中这两个文件夹的右侧都有一个小箭头,这是一个软连接实际是链接到了.pnpm下这样的路径:.pnpm中对应的模块。
sybolic link(软链接,也叫符号链接):类似于windows系统中的快捷方式,与硬链接不同,软链接就是一个 普通文件,只是数据块内容有点特殊,文件用户数据块中存放的内容是另一文件的路径名的指 向,通过这个方式可以快速定位到软连接所指向的源文件实体。
这样,pnpm 实现了相同模块不同版本之间隔离和复用。而且,node_modules目录是非扁平的,不存在由于提升带来的幽灵依赖问题。比如我们可以看在.pnpm目录下的axioslodash都有各自的node_module
在这里插入图片描述

小结

  1. pnpm 通过 hard link 在全局里面搞个 store 目录来存储 node_modules 依赖里面的 hard link 地址。这样节省了磁盘空间,并提升安装速度
  2. node_modules目录是非扁平的,在引用依赖的时候,则是通过 sybolic link 去找到对应虚拟磁盘目录下(.pnpm 目录)的依赖地址。这样,避免了之前npm和yarn扁平/非扁平安装带来的一系列问题;

整个流程如下图所示:
在这里插入图片描述

对比

特性npmyarnpnpm
安装方式自动随 Node.js 安装需要单独安装需要单独安装
包缓存支持缓存,但缓存机制较为简单支持缓存,安装时从缓存中获取加速支持强大的磁盘缓存机制,避免重复下载和浪费空间
安装速度相对较慢,尤其在大量依赖时更快,尤其是有缓存时更快,采用硬链接方式减少重复依赖的存储
依赖管理使用 node_modules 存储依赖使用 node_modules 存储依赖,优化了依赖的管理方式使用硬链接和符号链接来创建依赖树,提高存储效率
工作空间(Workspaces)从 npm 7 开始支持工作空间原生支持工作空间,用于管理 monorepos支持工作空间,适用于 monorepos 项目
锁文件package-lock.jsonyarn.lockpnpm-lock.yaml
安装依赖的精确性有时依赖版本可能不一致(尤其在没有锁文件的情况下)确保锁文件的精确性,安装一致高精度的依赖版本控制,确保每个开发环境一致
并发下载支持并发下载,但效率较低支持并发下载,速度更快使用并发下载并且非常高效
兼容性与大多数现有工具兼容高度兼容 npm,支持较多工具兼容 npm 和 Yarn,支持多种工具
安装的存储优化存储空间相对浪费,所有模块都存储在 node_modules有一定优化,减少重复存储使用硬链接存储,节省磁盘空间,避免重复依赖存储
社区支持最大,几乎所有 JavaScript 项目都支持良好,尤其在 Facebook 和 JavaScript 社区中受欢迎较新,但支持增长迅速,逐渐得到许多大项目的青睐

Monorepo项目选择包管理器

Monorepo的思想是严格统一,多个项目放在一个仓库里面。比较知名的像Antd、babel、npm7都是在用Monorepo方式进行管理的。Monorepo常见目录结构如下

- packages- project1- src- index.ts- package.json- project2- src- index.ts- package.json- project3- src- index.ts- package.json
- package.json
- tsconfig.json

这样有以下几点好处:

  1. 统一工作流:由于所有的项目放在一个仓库当中,复用起来非常方便,如果有依赖的代码变动,那么用到这个依赖的项目当中会立马感知到。并且所有的项目都是使用最新的代码,不会产生其它项目版本更新不及时的情况,对开发调试而言都带来了方便
  2. 降低基建成本:所有项目复用一套标准的工具和规范,无需切换开发环境,如果有新的项目接入,也可以直接复用已有的基建流程,比如 CI 流程、构建和发布流程。这样只需要很少的人来维护所有项目的基建,维护成本也大大减低
  3. 团队协作也更加容易 ,一方面大家都在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,另一方面,git commit 的历史记录也支持以功能为单位进行提交,之前对于某个功能的提交,需要改好几个仓库,提交多个 commit,现在只需要提交一次,简化了 commit 记录,方便协作

当我们开发维护一个monorepo的项目时比较合适的包管理工具是pnpm,因为pnpm具有npmyarn没有的独特优势,具体有以下几点:
4. 支持 Workspaces:pnpm 原生支持 workspaces,可以自动管理多个子项目的依赖,确保所有的 package 依赖关系正确无误。

  1. 高效的存储机制:pnpm 采用硬链接和符号链接来存储依赖,而不是像 npm 或 yarn 那样直接复制 node_modules,从而极大地节省了磁盘空间。例如:
    如果多个 package 依赖相同的 react,pnpm 只会在全局存储中保存一份,而不同的 package 只会创建指向它的链接。
    这样比 npm 和 yarn 节省磁盘空间,并且加快安装速度。
  2. 自动处理 package 之间的依赖:pnpm 能够自动解析 monorepo 内部的依赖,例如 package-a 依赖 package-b,pnpm 可以直接链接,而不需要手动指定路径。
    避免了手动 npm link 或 yarn workspaces run 这样的复杂操作。
  3. 严格的依赖管理:pnpm 的 node_modules 采用严格模式,避免了 npm 和 yarn 可能导致的幽灵依赖问题(即 package.json 没有声明依赖但仍然可以使用)。

如何在 pnpm 中启用 Workspaces

需要使用pnpm管理多包项目非常简单。只需要按照下面步骤即可

创建 pnpm Monorepo

在根目录下创建 pnpm-workspace.yaml:

packages:- "packages/*"  # 这里会自动识别 packages 目录下的所有子项目

然后在 package.json 中启用 workspaces:

{"name": "my-monorepo","private": true,"devDependencies": {"pnpm": "^8.0.0"}
}
创建多个子项目

创建 packages/package-a/package.json:

{"name": "package-a","version": "1.0.0","main": "index.js","dependencies": {"lodash": "^4.17.21"}
}

创建 packages/package-b/package.json,并让 package-b 依赖 package-a:

{"name": "package-b","version": "1.0.0","main": "index.js","dependencies": {"package-a": "workspace:*"}
}
安装依赖
pnpm install

pnpm 会自动解析 workspace:* 依赖,确保 package-b 能够正确依赖 package-a。
依赖会被存储在 node_modules/.pnpm 下,并通过符号链接管理。

对比各包管理器在monorepo下的作用

特性pnpm workspacesyarn workspacesnpm workspaces
存储方式硬链接+符号链接(节省空间)直接安装在 node_modules直接安装在 node_modules
安装速度🚀 最快中等最慢
依赖隔离严格(无幽灵依赖)可能有幽灵依赖可能有幽灵依赖
支持 workspace:* 语法支持支持支持
自动解析内部依赖自动解析自动解析自动解析
适合 Monorepo非常适合适合适合
缓存机制强大的缓存机制,避免重复安装依赖默认缓存,效率较高默认缓存,效率较低
依赖版本控制高精度版本控制,严格管理依赖高精度版本控制高精度版本控制
硬链接优化高效硬链接管理❌ 不支持❌ 不支持

相关文章:

前端包管理器的发展以及Npm、Yarn和Pnpm对比

在现代前端开发中,包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展,开发者经历了从 npm 一统天下到 Yarn 挑战格局,再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器(npm/Yarn/pnpm)进行全方位…...

node.js+兰空图床实现随机图

之前博客一直用的公共的随机图API,虽然图片的质量都挺不错的,但是稳定性都比较一般,遂打算使用之前部署的兰空图床,自己弄一个随机图 本文章服务器操作基于雨云——新一代云服务提供商的云服务器进行操作,有兴趣的话可…...

【MySQL】高频 SQL 50 题(基础版)

高频SQL50题(基础版) 1.查询 2.连接 MySQL多表查询(联合查询、连接查询、子查询) left join 左连接 我们首先执行LEFT JOIN操作,将两个表的数据基于 id 列进行组合。同样,我们使用 LEFT JOIN 来确保将所…...

盛铂科技 SMF106 低相位噪声贴片式频率综合器模块

在现代通信和电子设备领域,频率综合器作为关键组件,其性能优劣直接影响系统的整体表现。盛铂科技的 SMF106 低相位噪声贴片式频率综合器,以其卓越的性能和独特设计,成为众多高性能系统的选择。 一、频率覆盖范围广,步进…...

C语言如何实现面向对象?——从结构体到自由函数的思考

1. 问题的背景 面向对象编程(OOP)是一种广泛使用的编程范式,其核心思想包括封装、继承和多态。C、Java等语言原生支持OOP,但C语言作为一门面向过程的语言,是否也能实现面向对象?如果可以,如何实…...

深入探索C语言中的字符串处理函数:strstr与strtok

在C语言的字符串处理领域, strstr 和 strtok 是两个非常重要的函数,它们各自承担着独特的功能,为开发者处理字符串提供了强大的支持。 一、strstr函数:字符串查找的利器 strstr 函数用于在一个字符串中查找另一个字符串的首次出现…...

浅聊Docker使用、部署

在Java面试中,当被问到关于Docker中间件的使用、部署及在实际项目中的考虑时,可以按照以下结构和内容来详细回答: 一、Docker中间件的使用 1. Docker是什么? Docker是一个开源平台,允许开发者将应用程序及其依赖项打…...

jenkins war Windows安装

Windows安装Jenkins 需求1.下载jenkins.war2.编写快速运行脚本3.启动Jenkins4.Jenkins使用 需求 1.支持在Windows下便捷运行Jenkins; 2.支持自定义启动参数; 3.有快速运行的脚步样板。 1.下载jenkins.war Jenkins下载地址:https://get.j…...

学习数据结构(9)栈和队列上

1.栈的概念 栈是一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作 的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出(先进先出)的原则 栈的插入操作叫做进栈/压栈/入栈&#xff…...

【git-hub项目:YOLOs-CPP】本地实现03:跑自己的实例分割模型

本节博客,我们继续讲解,如何在cpu+windows上,跑通自己的实例分割模型。 目录 模型 类别名称 量化 导出模型 拉取最新代码 进入官网ultralytics 模型 该项目包括存储在 models 和 quantized_models 目录中的各种预训练标准 YOLO 模型: 模型类型模型名称标准模型yolo5…...

MySQL和SQL server的区别

在当今数据驱动的世界里,数据库技术的选择对于企业和个人开发者来说至关重要。MySQL 和 SQL Server 是两个广泛使用的数据库管理系统(DBMS),它们各自拥有独特的优势和适用场景。本文将深入探讨这两个数据库系统之间的区别&#xf…...

C#运动控制——轴IO映射

1、IO映射的作用 该功能允许用户对专用 IO 信号的硬件输入接口进行任意配置,比如轴的急停信号,通过映射以后,可以将所有轴的急停信号映射到某一个IO输入口上,这样,我们只要让一个IO信号有效就可以触发所有轴的急停。 进…...

DeepSeek官方发布R1模型推荐设置

今年以来,DeepSeek便在AI领域独占鳌头,热度一骑绝尘。其官方App更是创造了惊人纪录,成为史上最快突破3000万日活的应用,这一成绩无疑彰显了它在大众中的超高人气与强大吸引力。一时间,各大AI及云服务厂商纷纷投身其中&…...

DeepSeek教unity------MessagePack-03

数据契约兼容性 你可以使用 [DataContract] 注解代替 [MessagePackObject]。如果类型用 DataContract 进行注解,可以使用 [DataMember] 注解代替 [Key],并使用 [IgnoreDataMember] 代替 [IgnoreMember]。 然后,[DataMember(Order int)] 的…...

《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器

周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期:Google开…...

img标签的title和alt

img标签的title和alt 显示上 title:鼠标移入到图片上时候显示的内容&#xff1b; alt:图片无法加载时候显示的内容; <div class"box"><div><!-- title --><h3>title</h3><img src"./image/poster.jpg" title"这是封…...

MambaMorph brain MR-CT

loss代码实现了几种用于医学图像配准(Registration)和分割(Segmentation)任务的损失函数,主要包括以下几种: NCC (Normalized Cross-Correlation): 功能: 计算局部归一化互相关损失,用于衡量两个图像之间的相似性。 应用场景: 通常用于图像配准任务,通过最大化图像之间…...

小米 R3G 路由器(Pandavan)实现网络打印机功能

小米 R3G 路由器&#xff08;Pandavan&#xff09;实现网络打印机功能 一、前言 家中有多台 PC 设备需要打印服务&#xff0c;但苦于家中的 Epson L380 打印机没有网络打印功能&#xff0c;并且配置 Windows 共享打印机实在是过于繁琐且需要共享机保持唤醒状态过于费电。想到…...

Python PyCharm DeepSeek接入

Python PyCharm DeepSeek接入 创建API key 首先进入DeepSeek官网,https://www.deepseek.com/ 点击左侧“API Keys”,创建API key,输出名称为“AI” 点击“创建",将API key保存,复制在其它地方。 在PyCharm中下载Continue插件 安装 下载中 下载完成后,点击OK 配…...

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第二十节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析&#xff08;WriteMemoryByAddress_0x3D服务&#xff09; 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月14日 关键词&#xff1a;UDS协议、0x3D服务、内存写入、ISO 14229-1:2023、ECU测试 一、服务功能概述…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...