纱线2隆重推出 ??

嗨,大家好经过365天的密集开发,我非常高兴地发布了Yarn 2的第一个稳定版本。在这篇文章中,我将解释该版本对我们社区的意义。系好安全带

如果您想了解更多有关Yarn 1的信息,请继续阅读,因为我们稍后将详细介绍我们的计划:未来计划。如果您只想立即从Yarn 2开始,请查看《入门或迁移》指南。

发布概述

描述此发行版特别困难-它包含核心的基本更改,并随我们自己的使用而诞生新功能。

强调

  • 重新设计了输出,以提高可读性
  • 为提高可读性而设计
  • 我们的CLI命令(yarn add,…)现在知道工作区
  • 跑步 yarn install 可以根据回购设置为可选
  • 更安全 npx 对方叫 yarn dlx 运行一键式工具
  • 使用以下命令在所有工作区上运行命令 yarn workspaces foreach
  • 软件包可以通过以下方式进行修改: patch: 协议
  • 本地包可以通过新的引用 portal: 协议
  • 设计了新的工作流程以有效释放工作空间
  • 现在可以声明性地对工作区进行自动修复

但是也…

  • 现在仅在绝对需要时才触发软件包构建
  • 现在可以基于每个软件包启用或禁用软件包构建
  • 脚本现在在标准化外壳中执行
  • 对等依赖性现在甚至可以通过 yarn link
  • 锁定文件现在是正确的YAML
  • 现在,代码库已满TypeScript
  • 现在可以通过插件扩展纱线

重大变化…

  • 配置设置已标准化
  • 盘点必须遵守其边界
  • 捆绑包依赖项不再受支持
  • 软件包存储在只读档案中

这些重点只是所有更改和改进的一部分;可以在此处找到更详细的变更日志,并在此处提供升级说明。

经常问的问题

对于此版本,我们应该感谢谁?

SysGears的larixer已经完成了大量工作,他潜入引擎深处,其任务是尽可能轻松地过渡到Yarn 2。特别是他写了整个 node_modules 兼容性层,我可以告诉您这并非易事

我还要感谢在开发过程中自发加入我们一周或一个月的每个人。特别是最初的Windows支持是embraser01,bgotink是键入我们的文件系统API,deini是他对CLI的贡献,Daniel是在基础结构迁移方面的帮助。

没有开放源代码社区的许多人的支持,不可能完成这项工作-我想尤其是Babel的Nicolò和Browserify的Jordan的支持,但他们远非仅有的:Gatsby团队,接下来,Vue,Webpack,Parcel,Husky等……您的支持真正改变了世界。

最后,Yarn 2的项目负责人和设计架构师确实是MaëlNison。我的时间很大一部分是由Datadog赞助的,Datadog是开发JS的超级涂料(正在招聘do),还有我的未婚夫和我们的猫。永远不要忘记,所有开源项目背后都是维护者及其家人。

迁移到Yarn 2有多容易?

多亏了我们的Beta测试人员和生态系统的普遍支持,我们才得以大大减轻与此类重大升级相关的痛苦。可以使用《迁移指南》进行更详细的介绍,但是一般来说,只要您使用工具的最新版本(ESLint,Babel,TypeScript,Gatsby等),一切都应该很好。

不过,有一个特别的警告:在即插即用(PnP)环境中,目前无法使用Flow和React-Native。我们期待与他们各自的团队合作,找出如何使我们的技术兼容。同时,您可以根据需要选择保留纱线1的时间,或者使用 node_modules 插件,旨在为平滑升级提供一个优美的降级路径(请注意,它仍在开发中-期待龙腾)。此处有更多详细信息。

如果您不想升级所有项目,请运行 yarn policies set-version ^1 在需要保留在纱线1上的存储库中,并提交结果。 Yarn始终会喜欢签入的二进制文件而不是全局签入的二进制文件,这是确保团队中每个人共享完全相同版本的最佳方法

遗留代码库会发生什么?

纱线1.22将在下周发布。完成后,1.x分支将正式进入维护模式-这意味着除非绝对需要修补漏洞,否则它将不会从我那里得到进一步的发布。新功能将专门针对纱线2开发。实际上:

  • 旧版存储库(yarnpkg/yarn)将移至 yarnpkg/legacy 反映其维护状态。暂时将其保持打开状态,但我们可能会在一两年内将其存档。

  • 现代存储库不会重命名为 yarnpkg/yarn,因为那样会破坏大量的反向链接历史记录。它将保持 yarnpkg/berry 在可预见的未来。

  • 旧网站将移至legacy.yarnpkg.com,新网站(当前为next.yarnpkg.com)将迁移到主域名。

  • yarn npm上的软件包将这样更新:

    • berry 标签将始终指向最新的2.x版本。
    • legacy 标签将始终指向最新的1.x版本。
    • latest 标签将是的别名 legacy 几个星期,然后将切换到 berry。如果他们的应用程序与Yarn 2不兼容,则需要进行此舞蹈以使每个人都有时间固定其Yarn版本。
  • Node Docker映像很可能会从Node 14(预计在2020年4月)开始交付Yarn2。在此之前,您可以放心使用 yarnPath 几乎无需更改配置即可在所有Node映像上无缝使用Yarn 2。

  • 我们正在转向一个完全自动化的GitHub Actions工作流,并且尚未实施某些OS注册表(尤其是Homebrew,Chocolatey等)。结果,他们可能比其他人晚收到Yarn 2更新。同时, yarn set version (要么 yarn policies set-version 在纱1上)是处理升级的推荐方法。

我们预计其中大部分更改将在2020年2月1日之前完成。

深入

CLI输出

早在发布Yarn时,与其他解决方案(加上表情符号!)相比,它的CLI输出是向前迈出了一大步,但是仍然存在一些问题。特别是,许多消息是相当隐晦的,并且颜色是在与内容而不是与内容打交道。基于这一经验,我们决定为Yarn 2尝试一些不同的东西:

现在,几乎所有消息都有自己的错误代码,可以在我们的文档中进行搜索。在这里,您将找到有关每条消息的内容的全面说明-包括建议的修复程序。现在,颜色用于支持每个消息的重要部分,通常是软件包名称和版本,而不是每行。

我们希望在接下来的几个月中做出一些调整(特别是在色盲可访问性方面),但是随着时间的流逝,我认为您会喜欢上这款新显示器的

工作区感知的CLI

使用工作空间有时可能会令人不知所措。向一个工作区添加新的依赖项时,需要牢记整个项目的状态。 “我应该使用哪个版本?我的其他工作空间已经使用了什么?”等。

现在,Yarn通过各种方式促进了此类设置的维护:

  • yarn up 将一次升级所有工作区中的软件包
  • yarn add -i 将提供与其他工作空间(和其他一些选择)所用版本相同的版本。
  • 版本插件将为您提供一种方法,当再次释放其中一个工作区时,检查所有相关工作区是否被颠簸。

这些变化突显了我们希望带给Yarn的新体验:该工具成为盟友而不是负担。

零安装

“零安装”一词虽然本身不​​是一项功能,但它包含大量针对特定目标而量身定制的Yarn功能-通过从等式中消除熵的主要来源,使您的项目尽可能稳定和快速。

简而言之,由于Yarn现在直接从缓存中读取供应商文件,因此,如果缓存已成为存储库的一部分,则无需再次运行yarn install。当然,它会影响存储库的大小,但与Yarn 1的脱机镜像功能相当-非常合理。

有关更多详细信息(例如“为什么与签入 node_modules 目录”),请参阅此文档页面。

新命令: yarn dlx

纱线2引入了一个新命令,称为 yarn dlx (dlx代表下载并执行),其基本功能与 npx 以稍微危险些的方式。以来 npx 既可以用于本地脚本又可以用于远程脚本,打字错误可能会给攻击者打开大门:

$npx serv # Oops, should have been "serve"

对于dlx而言,这不是问题,它专门下载并执行远程脚本-永远不会本地脚本。本地脚本始终可以通过yarn run或直接按其名称运行:

$yarn dlx terser my-file.js
$yarn run serve
$yarn serve

新命令: yarn workspaces foreach

在多个存储库上运行命令是一个相对常见的用例,到目前为止,您需要使用外部工具才能执行此操作。由于工作区工具插件扩展了Yarn,您不再需要这种情况了:

$yarn workspaces foreach run build

该命令还支持控制执行的选项,这些选项使您可以告诉Yarn遵循依赖关系,并行执行命令,跳过工作空间等。在此处查看选项的完整列表。

新协议: patch:

纱线2具有称为 patch:。每当需要将更改应用于依赖关系树中的特定程序包时,都可以使用此协议。其格式类似于以下内容:

{
  "dependencies": {
    "left-pad": "patch:left-pad@1.3.0#./my-patch.patch"
  }
}

resolutions 字段,您甚至可以修补位于依赖树深处的软件包。而且由于 patch: 协议只是另一个数据源,它受益于与所有其他协议相同的机制-包括缓存和校验和

新协议: portal:

纱线2具有称为 portal:。你可以看到 portal: 作为现有产品的配套产品 link: 协议。哪里 link: 协议用于告诉Yarn创建指向本地磁盘上任何文件夹的符号链接, portal: 协议用于创建到任何软件包文件夹的符号链接。

{
  "dependencies": {
    "@my/app": "link:./src",
    "eslint-plugin-foo": "portal:./pkgs/eslint-plugin-foo"
  }
}

那你说有什么区别呢?很简单:门户网站遵循传递依赖关系,而链接则不需要。甚至更好的是,无论符号链接包的位置在哪里,门户网站都正确遵循对等方的依赖关系。

工作区发布

使用工作区会带来很多问题,可伸缩的发行版可能是最大的发行版之一。这里周围的大多数大型开源项目都使用Lerna或类似的工具,以便自动跟踪应用于工作区的更改。

当我们开始发布Yarn 2的beta版本时,我们很快注意到我们将遇到同样的问题。我们环顾四周,但是现有的解决方案似乎有重要的要求-例如,使用Lerna您将不得不每次都释放所有软件包,或者跟踪自己需要释放哪些软件包。其中一些工作可以自动化,但是当您考虑到要释放的工作空间可能也需要再次释放不相关的软件包时(例如,因为他们在预盘点步骤中使用了它),它将变得更加复杂

为了解决这个问题,我们设计了一个全新的工作流程,可通过一个名为 version。此工作流程(在此处记录)使您可以将部分发布职责委派给您的贡献者。为了使事情变得更好,它还附带了一个可视界面,使管理发布在公园中散步

此工作流仍处于试验阶段,但对我们而言效果很好,我们认为在使用工作区构建大型项目时,它将很快证明您的工具包不可缺少的一部分。

工作空间约束

工作区很快证明自己是我们最有价值的功能之一。这些年来,无数的项目和应用切换到了它们。但是,它们并非完美无缺。特别是,要使工作区依赖项保持同步需要格外小心。

纱线2附带了一个称为约束的新概念。约束提供了一种方法来指定通用规则(使用Prolog,一种声明性编程语言),所有规则都必须满足这些规则才能通过验证。例如,以下内容将防止您的工作区依赖于下划线-并且可以自动修复

gen_enforced_dependency(WorkspaceCwd, 'underscore', null, DependencyType) :-
  workspace_has_dependency(WorkspaceCwd, 'underscore', _, DependencyType).

此其他约束将要求您的所有工作空间在其清单中正确描述存储库字段:

gen_enforced_field(WorkspaceCwd, 'repository.type', 'git') :-
  workspace(WorkspacedCwd).

gen_enforced_field(WorkspaceCwd, 'repository.url', 'ssh://git@github.com/yarnpkg/berry.git') :-
  workspace(WorkspacedCwd).

约束绝对是我们最先进,最强大的功能之一,因此,如果您需要时间来解决这个问题,请不要担心。我们将跟进博客文章,以探索它们的详细信息-观看此空间

建立依赖性跟踪

Yarn 1中的一个经常出现的问题是,过去本机软件包的重建远远超出了应有的范围。例如,跑步 yarn remove 用于完全重建依赖关系树中的所有软件包。

从Yarn 2开始,我们现在跟踪列出了安装后脚本的每个软件包的单个依赖关系树,并且仅在这些依赖关系树以某种方式更改时才运行它们:

➤ YN0000: ┌ Link step
➤ YN0007: │ sharp@npm:0.23.0 must be rebuilt because its dependency tree changed
➤ YN0000: └ Completed in 16.92s
➤ YN0000: Done with warnings in 21.07s

每包构建配置

现在,Yarn 2允许您指定是否应基于每个程序包运行构建脚本。目前,默认是运行所有内容,因此默认情况下,您可以选择禁用特定软件包的构建:

{
  "dependenciesMeta": {
    "core-js": {
      "built": false
    }
  }
}

如果您希望默认情况下禁用所有功能,只需将其关闭即可 enableScripts 在您的设置中,然后明确启用 built 标记在 dependenciesMeta

归一化壳

早在Yarn 2还是年轻的时候,我们收到的第一个外部PR就涉及Windows支持。事实证明,Windows用户很多,兼容性对他们来说很重要。特别是,他们通常会遇到脚本字段的问题,通常仅在Bash上对其进行测试。

Yarn 2附带了一个基本的shell解释器,该解释器知道足以让您获得90%的脚本领域通常使用的语言结构。由于有了这个解释器,无论您的脚本是在OSX还是Windows上执行的,它们都将运行相同的脚本:

{
  "scripts": {
    "redirect": "node ./something.js > hello.md",
    "no-cross-env": "NODE_ENV=prod webpack"
  }
}

更好的是,此shell允许我们构建更紧密的集成,例如将命令行参数公开给用户脚本:

{
  "scripts": {
    "lint-and-build": "yarn lint "$@" && yarn build "$@""
  }
}

改进的对等依赖链接

因为Node会在所有必需的路径上调用realpath(除非–preserve-symlinks处于启用状态,这种情况很少发生),所以对等依赖项无法通过yarn link起作用,因为它们是从链接包实际位置的角度加载的磁盘,而不是依赖于磁盘。

由于Plug’n’Play可以强制Node实例化程序包以满足其所有依赖集的次数,因此Yarn现在能够正确支持这种情况。

新的锁定文件格式

早在创建Yarn时,就决定了锁定文件将使用与YAML非常相似的格式,但是有一些键差异(例如,键及其值之间没有冒号)。对于第三方工具作者来说,这相当令人讨厌,因为解析器是定制的,语法不是标准的。

从Yarn 2开始,锁定文件和配置文件的格式都更改为纯YAML:

"@yarnpkg/parsers@workspace:^2.0.0-rc.6, @yarnpkg/parsers@workspace:packages/yarnpkg-parsers":
  version: 0.0.0-use.local
  resolution: "@yarnpkg/parsers@workspace:packages/yarnpkg-parsers"
  dependencies:
    js-yaml: ^3.10.0
    pegjs: ^0.10.0
  languageName: unknown
  linkType: soft

TypeScript代码库

尽管它可能不会直接影响您作为用户,但我们已经从Flow完全迁移到TypeScript。一个巨大的优势是我们的工具和贡献工作流程现在比以往任何时候都容易。并且由于我们现在允许构建Yarn插件,因此您将能够直接使用我们的类型,以确保您的插件在两次更新之间是安全的。

export interface Package extends Locator {
  version: string | null,
  languageName: string,
  linkType: LinkType,
  dependencies: Map<IdentHash, Descriptor>,
  peerDependencies: Map<IdentHash, Descriptor>,
  dependenciesMeta: Map<string, Map<string | null, DependencyMeta>>,
  peerDependenciesMeta: Map<string, PeerDependencyMeta>,
};

模块化架构

我最近写了一篇有关该主题的完整博客文章,因此我不会对此进行过多研究,但是Yarn现在采用了非常模块化的体系结构。

特别是,这意味着两件有趣的事情:

  • 您可以编写可以在运行时加载Yarn的插件,并且可以按照Yarn的观点访问真正的依赖关系树。这使您可以轻松构建Lerna,Femto,Patch-Package等工具。

  • 您可以依赖于Yarn核心本身并自己实例化类(请注意,这一部分仍处于实验阶段,因为我们在此模式下操作时会找出包括内置插件的最佳方法)。

为了给您一个想法,我们构建了一个打字稿插件,该插件会自动添加相关的 @types/ 每次运行时打包 yarn add。插件易于编写-我们甚至提供了教程-因此,请随时试一下

规范化配置

我们收到的有关纱线1的非常普遍的反馈是关于我们的配置管道。当Yarn发布时,我们试图与npm尽可能兼容,这促使我们尝试读取npm配置文件等。这使我们的用户很难理解应该在哪里配置设置。

initScope: yarnpkg
npmPublishAccess: public
yarnPath: scripts/run-yarn.js

在Yarn 2中,整个配置已进行了修改,现在所有内容都保存在一个名为 .yarnrc.yml。设置名称也进行了更改,以变得统一(不再 experimental-pack-script-packages-in-mirrorworkspaces-experimental),因此请务必查看我们崭新的文档。

严格的盘点边界

除非实际在其依赖项中列出了其他程序包,否则不允许它们使用其他程序包。这与一年多前我们引入Plug’n’Play时所做的更改是一致的,我们很高兴地说,我们与生态系统顶级维护者所做的工作取得了丰硕的成果。如今,很少有软件包仍然存在与此规则的兼容性问题。

// Error: Something that got detected as your top-level application
// (because it doesn't seem to belong to any package) tried to access
// a package that is not declared in your dependencies
// 
// Required package: not-a-dependency (via "not-a-dependency")
// Required by: /Users/mael/my-app/
require(`not-a-dependency`);

弃用捆绑包依赖项

捆绑包依赖是另一个时代的人工制品,对它们的所有支持都已删除。安装将正常降级并下载软件包,如依赖字段中最初列出的那样。

{
  "bundleDependencies": [
    "not-supported-anymore"
  ]
}

如果您使用捆绑包依赖项,请查看《迁移指南》以获取建议的替代方案。

只读包

软件包现在保留在其缓存档案中。为了安全起见并防止缓存损坏,这些归档文件被安装为只读驱动器,并且在正常情况下不能修改:

const {writeFileSync} = require(`fs`);
const lodash = require.resolve(`lodash`);

// Error: EROFS: read-only filesystem, open '/node_modules/lodash/lodash.js'
writeFileSync(lodash, `module.exports = 42;`);

如果某个软件包需要修改其自身的源代码,则需要将其拔出-明确地在 dependenciesMeta 字段,或通过列出安装后脚本来隐式表示。

结论

哇。这是很多材料,不是吗?我希望您喜欢这次更新,这是多年准备和固执的结晶。

我认为软件包管理应有的一切,都可以在这里找到。结果肯定是过去的观点,但我相信这是前进的道路-仔细规划我们要提供的长期用户体验,而不是没有方向的工具箱。

对于我来说,从事Yarn的工作真是令人难以置信。我同时是项目经理,人员工程师,首席设计师,开发人员关系和用户支持。跌宕起伏,但是每当我听到有人分享他们的纱线成功故事时,我的内心都会为之欢呼。因此,请这样做:告诉我您喜欢什么,并帮助您解决不喜欢的问题。

2020年快乐 ?

资讯来源:由0x资讯编译自DEV,原文:https://dev.to/arcanis/introducing-yarn-2-4eh1 ,版权归作者所有,未经许可,不得转载
你可能还喜欢