前端得包管理你有过几个?

一位用不好包管理器的前端,是一个入门级前端,一个用不好webpack的前端,是一个初级前端

三个包管理器是可以一起用的,只要你够胆大心细,就没任何问题!

javeScript编写中, 我们尽量不要定义全局变量,封装函数尽量不要有副作用, 因为全部变量的查询时间会比局部变量的查询慢, 更是考虑在 Node 的环境中无法被垃圾回收的问题

老规矩 先看原理

npm

  • npm 是 Node.js 能够如此成功的主要原因之一。npm 团队做了很多的工作,以确保 npm 保持向后兼容,并在不同的环境中保持一致。

  • npm 是围绕着 语义版本控制(semver)的思想而设计。

  • 给定一个版本号:主版本号. 次版本号. 补丁版本号, 以下这三种情况需要增加相应的版本号:

  • 主版本号:当 API 发生改变,并与之前的版本不兼容的时候

  • 次版本号:当增加了功能,但是向后兼容的时候

  • 补丁版本号:当做了向后兼容的缺陷修复的时候

  • npm 2 会安装每一个包所依赖的所有依赖项。如果我们有这么一个项目,它依赖项目 A,项目 A 依赖项目 B,项目 B 依赖项目 C,那么依赖树将如下所示:

  • 这个结构可能会很长。这对于基于 Unix 的操作系统来说只不过是一个小烦恼,但对于 Windows 来说却是个破坏性的东西,因为有很多程序无法处理超过 260 个字符的文件路径名。

  • npm 3采用了扁平依赖关系树来解决这个问题,所以我们的 3 个项目结构现在看起来如下所示:

存了已经下载的每个版本的压缩包。本地缓存的内容可以通过 npm cache ls 命令进行查看。本地缓存的设计有助于减少安装时间。

  • 这样,一个原来很长的文件路径名就从./node_modules/package-A/node_modules/package-B/node-modules/some-file-name-in-package-c.js变成了/node_modules/some-file-name-in-package-c.js

  • 这种方法的缺点是,npm必须首先遍历所有的项目依赖关系,然后再决定如何生成扁平的 node_modules 目录结构。npm 必须为所有使用到的模块构建一个完整的依赖关系树,这是一个耗时的操作,是 npm 安装速度慢的一个很重要的原因。

  • 想当然的以为每次运行npm install命令时,NPM都得从互联网上下载所有内容。

  • 但是,npm是有本地缓存的,它保存了已经下载的每个版本的压缩包。本地缓存的内容可以通过npm cache ls命令进行查看。本地缓存的设计有助于减少安装时间。

cnpm

  • cnpmnpm用法完全一致,只是在执行命令时将npm改为cnpm

  • npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,如果 npm 的服务器在中国就好了,于是淘宝团队干了这事。来自官网:“这是一个完整 npmjs.org 镜像,你可以用此代替官方版本 (只读),同步频率目前为 10 分钟 一次以保证尽量与官方服务同步。”

  • 官方地址:http://npm.taobao.org

  • 安装: npm install -g cnpm --registry=https://registry.npm.taobao.org

Yarn

  • Yarn一开始的主要目标是解决上一节中描述的由于语义版本控制而导致的 npm 安装的不确定性问题。虽然可以使用npm shrinkwrap来实现可预测的依赖关系树,但它并不是默认选项,而是取决于所有的开发人员知道并且启用这个选项。

  • Yarn采取了不同的做法。每个 yarn 安装都会生成一个类似于 npm-shrinkwrap.json 的 yarn.lock 文件,而且它是默认创建的。除了常规信息之外,yarn.lock文件还包含要安装的内容的校验和,以确保使用的库的版本相同。

  • yarn 是经过重新设计的崭新的 npm 客户端,它能让开发人员并行处理所有必须的操作,并添加了一些其他改进。

  • 运行速度得到了显著的提升,整个安装时间也变得更少

  • 像 npm 一样,yarn 使用本地缓存。`与npm不同的是,yarn无需互联网连接就能安装本地缓存的依赖项,它提供了离线模式`

  • 允许合并项目中使用到的所有的包的许可证

  • 通常情况下不建议通过 npm 进行安装。npm 安装是非确定性的,程序包没有签名,并且 npm 除了做了基本的 SHA1 哈希之外不执行任何完整性检查,这给安装系统程序带来了安全风险。(作者曾经在一个上百个依赖包的项目中使用npm丢包过,代价非常大,泪水不自觉掉下来)

首先看一次非常失败的包下载 竟然是从全局读取的资源 (不配置webpack别名是因为就这一个路径这么长)

首先我们从原理入手 ,我们使用 npm inityarn init ,cnpm init 的时候 发生了什么 ?

  • 生成package.json文件

  • json文件内部声明初始的版本信息、作者信息等,如果你是需要上传到 npm 上作为命令行工具,应该配置bin等声明入口字段

那么当我们使用npm i , yarn add ,cnpm i 操作时候会发生什么 ?

  • 首先会根据你的命令行后缀是否加了 -g 或者global判断,下载的包是放在全局的环境,还是当前package.json文件对应的node_module文件夹目录下 (这点尤其重要,有人出 BUG,就是因为在用npm , cnpm时候没有注明添加的是全局依赖还是本地依赖,导致json文件上没有对应的包名,项目永远起不来)

  • 然后根据你的指令--save 或者-D--save -dev判断是开发依赖还是线上依赖,其实这点在yarn上没有问题,因为yarn有自己的一套检查包完整性的机制,不会丢包,还会自动判断添加依赖,出bug一般是cnpmnpm,没有明确-g或者--savenpm只有检查程序员签名的机制,没有检查包完整性的机制,也不会自动添加依赖到json文件,那么就会出现丢包的假象,所以建议主要使用`yarn`

yarn 和 npm 对比

npm 的缺点汇总:

  • 同一个项目,安装的时候无法保持一致性。由于 package.json 文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。

    "5.0.3",
    "~5.0.3",
    "^5.0.3"
  • “5.0.3” 表示安装指定的 5.0.3 版本,“~5.0.3” 表示安装 5.0.X 中最新的版本,“^5.0.3” 表示安装 5.X.X 中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是 OK 的,有的同事会由于安装的版本不一致出现bug

  • 安装的时候,包会在同一时间下载和安装,中途某个时候,一个包抛出了一个错误,但是 npm 会继续下载和安装包。因为 npm 会把所有的日志输出到终端,有关错误包的错误信息就会在一大堆npm打印的警告中丢失掉,并且你甚至永远不会注意到实际发生的错误。

`yarn`的优点

  • 速度快 。速度快主要来自以下两个方面:

  • 并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是并行执行所有任务,提高了性能。

离线模式:如果之前已经安装过一个软件包,用Yarn再次安装时之间从缓存中获取,就不用像npm那样再从网络下载了

  • 安装版本统一:为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。

  • 更简洁的输出:npm 的输出信息比较冗长。在执行 npm install 的时候,命令行里会不断地打印出所有被安装上的依赖。相比之下,Yarn 简洁太多:默认情况下,结合了 emoji直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。

  • 多注册来源处理:所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。

  • 更好的语义化: yarn改变了一些npm命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。

那不是标题党? 说了yarn这么多优点,我们为什么还要npm呢?

你不用npm publish ,你怎么上传包到npm? 你不用cnpm,是下载不了一些包的

搞清楚三者下载包(依赖)的本质结果:

  • 首先向对应的node_module文件夹下面下载包(如果你非要下到全局,那么再见)

  • 再然后是json文件中添加对应的依赖字段, 确定是线上依赖还是开发依赖

  • 只要做到这两者 你就下包成功

  • 总结就是 只要结果 过程管你是啥

使用yarn下载过的包,再使用npm cnpm下载 会重复下载,删除之前的包

  • puppeteer这个包所依赖的mini版谷歌浏览器使用cnpm下载就可以完美解决

  • prerender-spa-plugin这个包依赖上面的木偶戏 puppeteer这个包,也可以用cnpm下载

  • 混合使用包管理器切记,不要重复下载依赖,npm cnpm下载依赖,一定要添加注明是什么依赖,是否全局安装

  • yarnnpm i两者,选择前者,原因在上面有提到,总体来说,yarn是不二选择,但是其他两者也不可缺少,比如electron这个依赖,使用cnpm就可以完美一键安装

只要胆大心细,就可以把三者用得如鱼得水,不然就会被按在地上摩擦,实践过程踩坑也是正常 觉得写得好别忘了关注我的专栏,给个赞再走~

原文作者:Peter谭金杰

地址:https://segmentfault.com/a/1190000019299845

原创系列推荐

1. JavaScript 重温系列(22篇全)

2. ECMAScript 重温系列(10篇全)

3. JavaScript设计模式 重温系列(9篇全)

4. 正则 / 框架 / 算法等 重温系列(16篇全)

5. Webpack4 入门手册(共 18 章)(上)

6. Webpack4 入门手册(共 18 章)(下)

7. 59篇原创系列汇总

点这,与大家一起分享本文吧

【Web技术】334- yarn、npm、cnpm 三者如何优雅的在一起使用 ?的更多相关文章

  1. 大话npm,cnpm和yarn

    npm:基于node.js的包管理工具; 常用命令 npm install 包名; 缺点:因服务器在国外,所以下载包的速度超级慢,所以出现了cnpm和yarn cnpm:跟npm是一样的,这是淘宝出的 ...

  2. npm cnpm yarn 安装

    安装node.js,其中已经集成了npm,可以将npm切换到国内镜像 $ npm config set registry https://registry.npm.taobao.org -- 配置后可 ...

  3. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  4. 深入分析Java Web技术内幕(修订版)

    阿里巴巴集团技术丛书 深入分析Java Web技术内幕(修订版)(阿里巴巴集团技术丛书.技术大牛范禹.玉伯.毕玄联合力荐!大型互联网公司开发应用实践!) 许令波 著   ISBN 978-7-121- ...

  5. 【01】npm/cnpm安装

    包安装相关信息: 1.node_modules文件夹 node_modules文件夹在nodejs中是一个特殊的文件夹,通过它的名字就可以看出,该文件夹也是用于存放node模块.如果一个模块表达式不是 ...

  6. node.js 和 npm/cnpm/nrm 的安装

    node.js 和 npm/cnpm/nrm 的安装 安装 node.js.去 官网 下载,下载 LTS 版本的.安装时一路点确定,不要改动任何设置. 在 git-bash 或是 cmd 下,输入 n ...

  7. HTML5 Dashboard – 那些让你激动的 Web 技术

    HTML5 Dashboard 是一个 Mozilla 推出的项目,里面展示了最前沿的 HTML5,CSS3,JavaScript 技术.每一项技术都有简洁,在线演示以及详细的文档链接.这些技术将成为 ...

  8. HTML5 模拟现实物理效果,感受 Web 技术魅力

    Ball Pool 是一个基于 HTML5 技术的实验,模拟现实物理效果,让你在 Web 中感受自然物体的运动.玩法介绍:可以随意拖动圆球.点击页面背景.晃动浏览器.双击页面背景或者按住鼠标左键,有不 ...

  9. Soundslice – 美妙乐谱!Web 技术高大上的应用

    Web 技术的不断发展让我们能够开发各种好玩的功能.这里给大家分享一个使用 HTML5 技术实现的在线乐谱,可以播放的哦,也可以选择一个片段进行循环播放.赶紧来体验一下:) 您可能感兴趣的相关文章 1 ...

随机推荐

  1. spark-宽依赖和窄依赖

    一.窄依赖(Narrow Dependency,) 即一个RDD,对它的父RDD,只有简单的一对一的依赖关系.也就是说, RDD的每个partition ,仅仅依赖于父RDD中的一个partition ...

  2. JMeter从0开始-笔记

    1.安装Jmeter之前 安装Jmeter之前需要先配置Java环境,我们下载的是jmeter4.0,所以java版本最好是选用java8以上的版本. 安装JDk1.6的步骤如下: 点击下载的JDK文 ...

  3. opencv 5 图像转换(2 霍夫变换)

    霍夫线变换 标准霍夫变换和多尺度霍夫变换(HoughLines()函数) 实例: #include <opencv2/opencv.hpp> #include <opencv2/im ...

  4. think PHP 查询、更改

    最近公司没有什么新项目,故准备搞搞PHP,正好后端有一些小东西需要搞一下,我就来试试吧. PHP 基于think PHP 3 实现功能: 1.为销售绑定虚拟号码分组(查询可以绑定的分组 -> 绑 ...

  5. HTML学习 day02

    1.HTML的相关概念 网站建设流程 网页组成  网页主要由三部分组成:结构(Structure).表现(Presentation)和行为(Behavior). html(Hypertext Mark ...

  6. 概率分布的python实现

    接上篇概率分布,这篇文章讲概率分布在python的实现. 文中的公式使用LaTex语法,即在\begin{equation}至\end{equation}的内容可以在https://www.codec ...

  7. selenium webdriver学习--------iframe的处理

    有时候我们在定位一个页面元素的时候发现一直定位不了,反复检查自己写的定位器没有任何问题,代 码也没有任何问题.这时你就要看一下这个页面元素是否在一个iframe中,这可能就是找不到的原因之一.如果你在 ...

  8. springmvc运行流程简单解释(源码解析,文末附自己画的流程图)

    首先看一下DispatcherServlet结构: 观察HandlerExecutionChain对象的创建与赋值,这个方法用来表示执行这个方法的整条链. 进入getHandler方法: 此时的变量h ...

  9. 源码分析 RocketMQ DLedger 多副本之 Leader 选主

    目录 1.DLedger关于选主的核心类图 1.1 DLedgerConfig 1.2 MemberState 1.3 raft协议相关 1.4 DLedgerRpcService 1.5 DLedg ...

  10. ruby2.2 DevKit 安装后无法使用解决方案

    windows 系统下,Ruby 的某些 gem 包需要 DevKit 才能正常安装,2.4 以后的版本可以一键安装 DevKit,之前的版本只能手动安装. 2.4 以后的可以到官网下载:https: ...