吉田  加奈

吉田 加奈

1598609280

pnpm: スペース効率に優れたJavaScriptパッケージマネージャ

pnpmはJavaScripr用のパッケージマネージャである。npmとの互換性を持つと同時に、速度とディスクスペース使用量が大幅に改善されている。今回バージョン5.0がリリースされたので、競合製品との違いを詳しく比較してみよう。

npm、Yarn、pnpmの3つは、JavaScriptエコシステムでは最も一般的なパッケージマネージャである。中核的な部分では、これらのパッケージ部分の動作は極めてよく似ている。いずれも依存性管理にはpackage.jsonファイルを使用し、ロックファイルを使って複数のマシン/インストール勘の一貫性を保証している。

pnpmが他と違うのはパッケージの管理方法だ。npmとYarnがプロジェクト毎に別々のパッケージのコピーをインストールするのに対して、pnpmはすべてのパッケージについて単一コピーを維持し、オリジナルインストレーションの参照にはハードリンクやシンボリックリンクを使用している。

このアプローチには大きなメリットが2つある — ディスクスペースの使用量の削減と、インストールプロセスの高速化だ。

多くの企業や開発者は、複数のプロジェクトで作業する上で、少なくともいくつかの依存関係を共有している。パッケージの重複はディスクスペースを浪費する結果になり、それが原因で大型のCI/CDビルドマシンの使用が必要になることも少なくない。さらには、開発者のローカルラップトップで使用可能なストレージスペースの総量を制限することにもなる。

#package managers #javascript #デベロップメント #pnpm #programming

What is GEEK

Buddha Community

pnpm: スペース効率に優れたJavaScriptパッケージマネージャ
吉田  加奈

吉田 加奈

1598609280

pnpm: スペース効率に優れたJavaScriptパッケージマネージャ

pnpmはJavaScripr用のパッケージマネージャである。npmとの互換性を持つと同時に、速度とディスクスペース使用量が大幅に改善されている。今回バージョン5.0がリリースされたので、競合製品との違いを詳しく比較してみよう。

npm、Yarn、pnpmの3つは、JavaScriptエコシステムでは最も一般的なパッケージマネージャである。中核的な部分では、これらのパッケージ部分の動作は極めてよく似ている。いずれも依存性管理にはpackage.jsonファイルを使用し、ロックファイルを使って複数のマシン/インストール勘の一貫性を保証している。

pnpmが他と違うのはパッケージの管理方法だ。npmとYarnがプロジェクト毎に別々のパッケージのコピーをインストールするのに対して、pnpmはすべてのパッケージについて単一コピーを維持し、オリジナルインストレーションの参照にはハードリンクやシンボリックリンクを使用している。

このアプローチには大きなメリットが2つある — ディスクスペースの使用量の削減と、インストールプロセスの高速化だ。

多くの企業や開発者は、複数のプロジェクトで作業する上で、少なくともいくつかの依存関係を共有している。パッケージの重複はディスクスペースを浪費する結果になり、それが原因で大型のCI/CDビルドマシンの使用が必要になることも少なくない。さらには、開発者のローカルラップトップで使用可能なストレージスペースの総量を制限することにもなる。

#package managers #javascript #デベロップメント #pnpm #programming

Alfie Mellor

Alfie Mellor

1651718538

What the heck is PNPM | Exploring PNPM!!

What the heck is PNPM?

In this video we talk about new package manager called as pnpm for node js. We will compare both managers and see who is better?

PNPM: https://pnpm.io/


Fast, disk space efficient package manager:

  • Fast. Up to 2x faster than the alternatives (see benchmark).
  • Efficient. Files inside node_modules are linked from a single content-addressable storage.
  • Great for monorepos.
  • Strict. A package can access only dependencies that are specified in its package.json.
  • Deterministic. Has a lockfile called pnpm-lock.yaml.
  • Works as a Node.js version manager. See pnpm env use.
  • Works everywhere. Supports Windows, Linux, and macOS.
  • Battle-tested. Used in production by teams of all sizes since 2016.

To quote the Rush team:

Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day, and we’ve found it to be very fast and reliable.

Background

pnpm uses a content-addressable filesystem to store all files from all module directories on a disk. When using npm or Yarn, if you have 100 projects using lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be stored in a content-addressable storage, so:

  1. If you depend on different versions of lodash, only the files that differ are added to the store. If lodash has 100 files, and a new version has a change only in one of those files, pnpm update will only add 1 new file to the storage.
  2. All the files are saved in a single place on the disk. When packages are installed, their files are linked from that single place consuming no additional disk space. Linking is performed using either hard-links or reflinks (copy-on-write).

As a result, you save gigabytes of space on your disk and you have a lot faster installations! If you'd like more details about the unique node_modules structure that pnpm creates and why it works fine with the Node.js ecosystem, read this small article: Flat node_modules is not the only way.

Getting Started

Benchmark

pnpm is up to 2x faster than npm and Yarn classic. See all benchmarks here.

Download Details: 
Author: pnpm
Source Code: https://github.com/pnpm/pnpm 
License: MIT
#pnpm #node 

Daisy Rees

Daisy Rees

1634173975

What Is pnpm?

Fast, disk space efficient package manager:

  • Fast. Up to 2x faster than the alternatives.
  • Efficient. Files inside node_modules are linked from a single content-addressable storage.
  • Great for monorepos.
  • Strict. A package can access only dependencies that are specified in its package.json.
  • Deterministic. Has a lockfile called pnpm-lock.yaml.
  • Works everywhere. Supports Windows, Linux, and macOS.
  • Battle-tested. Used in production by teams of all sizes since 2016.

To quote the Rush team:

Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day, and we’ve found it to be very fast and reliable.

Background

pnpm uses a content-addressable filesystem to store all files from all module directories on a disk. When using npm or Yarn, if you have 100 projects using lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be stored in a content-addressable storage, so:

  1. If you depend on different versions of lodash, only the files that differ are added to the store. If lodash has 100 files, and a new version has a change only in one of those files, pnpm update will only add 1 new file to the storage.
  2. All the files are saved in a single place on the disk. When packages are installed, their files are linked from that single place consuming no additional disk space. Linking is performed using either hard-links or reflinks (copy-on-write).

As a result, you save gigabytes of space on your disk and you have a lot faster installations! If you'd like more details about the unique node_modules structure that pnpm creates and why it works fine with the Node.js ecosystem, read this small article: Flat node_modules is not the only way.

Installation

On macOS, Linux, or Windows Subsystem for Linux:

curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

On Windows (using PowerShell):

(Invoke-WebRequest 'https://get.pnpm.io/v6.16.js' -UseBasicParsing).Content | node - add --global pnpm

Using npm:

npx pnpm add -g pnpm

For other installation options visit our website.

We also ship an experimental new version of pnpm that may be used even with no Node.js installed on the system, see @pnpm/exe.

Usage

Just use pnpm in place of npm/Yarn. E.g., install dependencies via:

pnpm install

Also, pnpm dlx instead of npx:

pnpm dlx create-react-app my-cool-new-app

For more advanced usage, read pnpm CLI on our website, or run pnpm help.


Introduction to pnpm, the drop in npm replacement that saves you disk space

I recently wrote about how we have huge node_modules folders and why this is not necessarily a bad thing, but it would be reduce that hard drive consumption, right?

Every byte saved on disk can be used for something else than libraries code, I have a 512GB SSD on my MacBook Pro I bought in 2010 but some brand new computers in 2019 ship with a 128GB SSD (something went wrong with Moore’s Law when it comes to hard disk space).

In particular, one way would be to centralize the libraries code storage into a central place, and share it with all the projects you work on.

This is the main value proposition of pnpm, a very cool project you can check out at https://pnpm.js.org.

It is basically a drop-in replacement for npm, which means that once you install it, you can invoke pnpm install to download a project dependencies, and all will work transparently for you.

If you have 10 projects that use React, at the same version, pnpm will install it once, and then reference that first install across all your other projects.

This also means that the project initialization part takes much less time than if it had to download resources using the standard npm procedure. It’s faster even if npm cached the package, because pnpm makes a hard link to the central local repository, while npm makes a copy of the package from the cache.

You install pnpm using npm, of course 😁

npm install -g pnpm

Then being pnpm a drop-in replacement, you can use all the npm commands:

pnpm install react
pnpm update react
pnpm uninstall react

and so on.

pnpm is especially appreciated in those companies where there is a need to maintain a large number of projects with the same dependencies.

For example Glitch is one of those companies, as they host a gazillion Node.js projects.

pnpm gives them, in addition to the npm usual commands, some utilities including pnpm recursive, which is used to run the same command across all the projects in a folder. For example you can initialize 100 projects stored in the current folder by running pnpm recursive install. Handy.

If you use npx, which is a handy (and the recommended) way to run utilities like create-react-app, you’ll get the benefits of pnpm by using the pnpx command which comes with pnpm:

pnpx create-react-app my-cool-new-app

Where are the packages installed? In macOS, in the ~/.pnpm-store/ folder (where ~ means your home folder). I installed lodash as an example and this was the resulting folder structure:

➜  ~ tree .pnpm-store/
.pnpm-store/
└── 2
    ├── _locks
    ├── registry.npmjs.org
    │   └── lodash
    │       ├── 4.17.11
    │       │   ├── integrity.json
    │       │   ├── node_modules
    │       │   │   └── lodash
    │       │   │       ├── ...
    │       │   ├── package -> node_modules/lodash
    │       │   └── packed.tgz
    │       └── index.json
    └── store.json

There are many more advanced things to learn about the tool, but I hope this helps getting you started with pnpm!

Should you use it for a day-to-day use? Probably not, just stick to npm unless you have needs that this tool solves for you - lack of disk space being one of them.

#node #pnpm #npm 

Eliseo  Kutch

Eliseo Kutch

1651932120

What is PNPM?

In this video we talk about new package manager called as pnpm for node js. We will compare both managers and see who is better?

PNPM: https://pnpm.io/

#pnpm #node #nodejs 

顾 静

顾 静

1658390400

使用 pnpm 管理全栈、多包 monorepo

pnpm。有什么大惊小怪的?

pnpm 中的“p”代表“性能”——哇,它确实提供了性能!

我对使用 npm 感到非常沮丧。似乎越来越慢了。使用越来越多的代码仓库意味着进行更频繁的 npm 安装。我花了这么多时间坐着等待它完成并思考,一定有更好的方法!

然后,在同事的坚持下,我开始使用 pnpm 并且没有回去。对于大多数新的(甚至是一些旧的)项目,我已经用 pnpm 替换了 npm,我的工作生活也因此变得更好了。

虽然我开始使用 pnpm 是因为它著名的性能(我并没有失望),但我很快发现 pnpm 具有许多用于工作区的特殊功能,非常适合管理多包monorepo(甚至是多包元 repo) .

在这篇博文中,我们将探讨如何使用 pnpm 来管理我们的全栈、多包 monorepo。

如果您只关心 pnpm 与 npm 的比较,请直接跳至第 5 节

1.什么是全栈、多包的monorepo?

那么我们到底在说什么?让我分解一下。

它是一个repo,因为它是一个代码存储库。在这种情况下,我们谈论的是 Git 代码存储库,Git 是卓越的主流版本控制软件。

这是一个monorepo,因为我们将多个(子)项目打包到一个代码存储库中,通常是因为它们出于某种原因属于一起,并且我们同时处理它们。

 

除了 monorepo,它也可以是meta repo,一旦它变得太大和复杂,这对于你的 monorepo 来说是一个很好的下一步——或者,例如,你想将它拆分并为每个单独的 CI/CD 管道项目。

我们可以通过将每个子项目拆分到其自己的存储库中,从 monorepo 转到元存储库,然后使用元工具将它们重新组合在一起。元存储库具有单存储库的便利性,但允许我们为每个子项目拥有单独的代码存储库。

它是多包的,因为我们在 repo 中有一个或多个包。Node.js 包是一个项目,ackage.json其根目录中有 ap 元数据文件。通常,要在多个项目之间共享一个包,我们必须将它发布到npm,但如果该包只在少数项目之间共享,这将是矫枉过正,尤其是对于专有或闭源项目。

它是全栈的,因为我们的 repo 包含一个全栈项目。monorepo 包含前端和后端组件、基于浏览器的 UI 和 REST API。我认为这是展示 pnpm 工作空间优势的最佳方式,因为我可以向您展示如何在前端和后端项目之间共享 monorepo 中的包。

下图显示了典型的全栈、多包 monorepo 的布局:

描述典型 monorepo 布局的图表当然,pnpm 非常灵活,这些工作空间可以以多种不同的方式使用。

其他一些例子:

  • 我现在将 pnpm 用于我公司的闭源微服务元存储库
  • 我还用它来管理我的开源Data-Forge Notebook项目,该项目有用于浏览器和 Electron 的项目,它们在它们之间共享包,所有这些都包含在一个 monorepo 中

2.创建一个基本的多包monorepo

这篇博文附带了工作代码,您可以在 GitHub 上亲自试用。您也可以在此处下载 zip 文件,或使用 Git 克隆代码存储库:

git clone git@github.com:ashleydavis/pnpm-workspace-examples.git

现在,打开一个终端并导航到目录:

cd pnpm-workspace-examples

让我们从使用 pnpm 创建一个简单的多包 monorepo 开始,只是为了学习基础知识。

如果这看起来太简单,请直接跳到第 3 节,看看更真实的全栈 monorepo。

这是我们将创建的简单结构:

根工作区依赖于包 a 和 b 的图

我们有一个带有根包和子包 A 和 B 的工作区。为了演示 monorepo 中的依赖关系:

  • 根工作区依赖于包 A 和 B
  • 包 B 依赖于包 A

让我们学习如何为我们的项目创建这个结构。

安装 Node.js 和 pnpm

要尝试其中的任何代码,您首先需要安装 Node.js。如果您还没有 Node.js,请按照他们网页上的说明进行操作。

在我们可以用 pnpm 做任何事情之前,我们还必须安装它:

npm install -g pnpm

根据您的操作系统,还有许多其他方法可以安装 pnpm 。

创建根项目

现在让我们创建我们的根项目。我们将我们的项目称为basic,它与您可以在 GitHub 中找到的代码对齐。第一步是为项目创建一个目录:

mkdir basic

或在 Windows 上:

md basic

从现在开始我就用mkdir;如果您在 Windows 上,请记住md改用。

现在,切换到该目录并package.json为我们的根项目创建文件:

cd basic
pnpm init

在许多情况下,pnpm 的使用与常规的旧 npm 一样。例如,我们将包添加到我们的项目中:

pnpm install dayjs

请注意,这会生成一个pnpm-lock.yaml文件,而不是 npm 的 package-lock.json 文件。您需要将此生成的文件提交给版本控制。

然后我们可以在我们的代码中使用这些包:

const dayjs = require("dayjs");

console.log(dayjs().format());

然后我们可以使用 Node.js 运行我们的代码:

node index.js

到目前为止,pnpm 与 npm 没有什么不同,除了(在这个小例子中你可能不会注意到)它比 npm 快得多。随着我们项目规模的增长和依赖项数量的增加,这一点将变得更加明显。

创建嵌套子包

pnpm 有一个“工作区”工具,我们可以使用它来在我们的 monorepo 中创建包之间的依赖关系。为了演示基本示例,我们将创建一个名为 A 的子包,并从根包创建对它的依赖项。

为了让 pnpm 知道它正在管理子包,我们在pnpm-workspace.yaml file根项目中添加一个:

packages:
- "packages/*"

这向 pnpm 表明该目录下的任何子目录packages都可以包含子包。

packages现在让我们为包 A创建目录和子目录:

cd packages
mkdir a
cd a 

现在我们可以package.json为 package 创建文件A

pnpm init

我们将为带有导出函数的包 a 创建一个简单的代码文件,我们可以从根包中调用它:

function getMessage() {
    return "Hello from package A";
}

module.exports = {
    getMessage,
};

接下来,更新package.json根包以添加对包 A 的依赖项。将此行添加到您的package.json

"a": "workspace:*",

更新后的package.json文件如下所示:

{
  "name": "basic",
    ...
  "dependencies": {
    "a": "workspace:*",
    "dayjs": "^1.11.2"
  }
}

现在我们已经将根包链接到子包 A,我们可以在根包中使用包 A 中的代码:

const dayjs = require("dayjs");
const a = require("a");

console.log(`Today's date: ${dayjs().format()}`);
console.log(`From package a: ${a.getMessage()}`);

注意我们是如何引用包 A 的。如果没有工作空间,我们可能会使用这样的相对路径:

const a = require("./packages/a");

相反,我们通过名称引用它,就好像它是node_modulesNode 包存储库中安装的一样:

const a = require("a");

通常,要实现这一点,我们必须将我们的包发布到 Node 包存储库(公开或私下)。被迫发布一个包以便方便地重用它会导致一个痛苦的工作流程,特别是如果你只在一个单一的monorepo中重用包。在第 5 节中,我们将讨论使共享这些包而不发布它们成为可能的魔力。

再次在我们的终端中,我们导航回根项目的目录并调用pnpm install以将根包链接到子包:

cd ...
pnpm install

现在我们可以运行我们的代码,看看效果:

node index.js

请注意如何从包 A 中检索消息并显示在输出中:

From package a: Hello from package A

这显示了根项目如何使用子包中的功能。

我们基本的monorepo的布局

我们可以像包A一样将包B添加到我们的monorepo中。您可以在示例代码的基本目录下看到最终结果。

此图显示了包含 A 和 B 包的基本项目的布局:

描述基本布局的图表我们已经学会了如何创建一个基本的 pnpm 工作区!让我们继续研究更高级的全栈 monorepo。

3. 在全栈 JavaScript monorepo 中共享代码

将 monorepo 用于全栈项目可能非常有用,因为它允许我们将后端和前端组件的代码放在一个存储库中。这很方便,因为后端和前端通常会紧密耦合并且应该一起更改。使用 monorepo,我们可以对两者进行代码更改并提交到单个代码存储库,同时更新两个组件。推送我们的提交然后触发我们的持续交付管道,该管道同时将前端和后端部署到我们的生产环境。

使用 pnpm 工作区会有所帮助,因为我们可以创建可以在前端和后端之间共享的嵌套包。我们将在这里讨论的示例共享包是一个验证代码库,前端和后端都使用它来验证用户的输入。

您可以在此图中看到,前端和后端都是包本身,并且都依赖于验证包:

前端和后端都依赖于“验证”包

请自己尝试全栈 repo:

cd fullstack
pnpm install
pnpm start

通过将浏览器导航到http://localhost:1234/.

您应该在待办事项列表中看到一些项目。尝试输入一些文本并单击添加待办事项以将项目添加到您的待办事项列表中。

看看如果您不输入文本并单击Add todo item会发生什么。尝试将空的待办事项添加到列表中会在浏览器中显示警报;前端的验证库阻止您添加无效的待办事项。

如果你愿意,你可以绕过前端,直接点击 REST API,在后端使用 VS Code REST Client 脚本,添加一个无效的待办事项。然后,后端的验证库做同样的事情:它拒绝无效的待办事项。

检查我们的项目结构

全栈项目中,该pnpm-workspace.yaml文件包括后端和前端项目作为子包:

packages:
  - backend
  - frontend
  - packages/*

packages子目录下,您可以找到在前端和后端之间共享的验证包。例如,这里package.json from the backend显示了它对验证包的依赖:

{
    "name": "backend",
    ...
    "dependencies": {
        "body-parser": "^1.20.0",
        "cors": "^2.8.5",
        "express": "^4.18.1",
        "validation": "workspace:*"
    }
}

前端使用验证包来验证新的待办事项是否有效,然后再将其发送到后端:

const validation = require("validation");
// ...

async function onAddNewTodoItem() {
    const newTodoItem = { text: newTodoItemText };
    const result = validation.validateTodo(newTodoItem);
    if (!result.valid) {
        alert(`Validation failed: ${result.message}`);
        return;
    }

    await axios.post(`${BASE_URL}/todo`, { todoItem: newTodoItem });
    setTodoList(todoList.concat([ newTodoItem ]));
    setNewTodoItemText("");
}

后端还使用了验证包。在前端和后端验证用户输入总是一个好主意,因为您永远不知道用户何时会绕过您的前端并直接访问您的 REST API。

如果你愿意,你可以自己试试。在fullstack/backend/test/backend.http下的示例代码存储库中查找VS Code REST 客户端脚本,该脚本允许您使用无效的待办事项触发 REST API。使用该脚本直接触发POST将项目添加到待办事项列表的 HTTP 路由。

您可以在后端代码中看到它如何使用验证包来拒绝无效的待办事项:

// ...

app.post("/todo", (req, res) => {

    const todoItem = req.body.todoItem;
    const result = validation.validateTodo(todoItem)
    if (!result.valid) {
        res.status(400).json(result);
        return;
    }

    //
    // The todo item is valid, add it to the todo list.
    //
    todoList.push(todoItem);
    res.sendStatus(200);
});

// ...

在 JavaScript 中的所有包上运行脚本

使 pnpm 对于管理多包 monorepo 如此有用的一件事是,您可以使用它在嵌套包中递归地运行脚本。

要了解这是如何设置的,请查看根工作区的 package.json 文件中的脚本部分:

{
    "name": "fullstack",
    ...
    "scripts": {
      "start": "pnpm --stream -r start",
      "start:dev": "pnpm --stream -r run start:dev",
      "clean": "rm -rf .parcel-cache && pnpm -r run clean"
    },
    ...
}

让我们看一下脚本start:dev,它用于在开发模式下启动应用程序。这是来自的完整命令package.json

pnpm --stream -r run start:dev

-r标志使 pnpmstart:dev在工作区中的所有包上运行脚本——好吧,至少所有有start:dev脚本的包!它不会在没有实现它的包上运行它,比如验证包,它不是一个可启动的包,所以它不需要那个脚本。

前端和后端包确实实现start:dev了,所以当你运行这个命令时,它们都会被启动。我们可以发出这个命令并同时启动我们的前端和后端!

国旗有什么作用--stream

--stream启用流输出模式。这只会导致 pnpm 连续显示终端中每个包的完整和交错的脚本输出。这是可选的,但我认为这是同时轻松查看前端和后端的所有输出的最佳方式。

不过,我们不必运行完整的命令,因为这是start:dev在工作区的package.json. 所以,在我们工作区的根目录,我们可以简单地调用这个命令来在开发模式下启动我们的后端和前端:

pnpm run start:dev

在特定包上运行脚本

有时能够在特定子包上运行一个脚本也很有用。您可以使用 pnpm 的--filter标志来执行此操作,它将脚本定位到请求的包。

例如,在根工作区中,我们可以start:dev只为前端调用,如下所示:

pnpm --filter frontend run start:dev

--filter我们可以使用该标志将任何脚本定位到任何子包。

4. 在全栈 TypeScript monorepo 中共享类型

在我们的 monorepo 中共享代码库的最佳示例之一是在 TypeScript 项目中共享类型。

栈 TypeScript 示例项目与之前的全栈 JavaScript 项目具有相同的结构,我只是将它从 JavaScript 转换为 TypeScript。TypeScript 项目还在前端和后端项目之间共享一个验证库。

不过,不同之处在于 TypeScript 项目也有类型定义。特别是在这种情况下,我们正在使用接口,我们希望在我们的前端和后端之间共享这些类型。然后,我们可以确定它们都在同一页面上,关于它们之间传递的数据结构。

请亲自尝试全栈 TypeScript 项目:

cd typescript
pnpm install
pnpm start

通过将浏览器导航到http://localhost:1234/.

现在,与全栈 JavaScript 示例一样,您应该会看到一个待办事项列表并能够向其中添加待办事项。

在项目之间共享类型定义

验证库的 TypeScript 版本包含定义前端和后端共享的通用数据结构的接口:

//
// Represents an item in the todo list.
//
export interface ITodoItem {
    //
    // The text of the todo item.
    //
    text: string;
}

//
// Payload to the REST API HTTP POST /todo.
//
export interface IAddTodoPayload {
    //
    // The todo item to be added to the list.
    //
    todoItem: ITodoItem;
}

//
// Response from the REST API GET /todos.
//
export interface IGetTodosResponse {
    //
    // The todo list that was retrieved.
    //
    todoList: ITodoItem[];
}

// ... validation code goes here ...

这些类型在index.ts file验证库中定义,并在前端用于验证我们在编译时通过 HTTP 发送到后端的数据结构POST

async function onAddNewTodoItem() {
    const newTodoItem: ITodoItem = { text: newTodoItemText };
    const result = validateTodo(newTodoItem);
    if (!result.valid) {
        alert(`Validation failed: ${result.message}`);
        return;
    }

    await axios.post<IAddTodoPayload>(
          `${BASE_URL}/todo`, 
          { todoItem: newTodoItem }
      );
    setTodoList(todoList.concat([ newTodoItem ]));
    setNewTodoItemText("");
}

这些类型还用于后端验证(同样,在编译时)我们通过 HTTP 从前端接收的数据的结构POST

app.post("/todo", (req, res) => {

    const payload = req.body as IAddTodoPayload;
    const todoItem = payload.todoItem;
    const result = validateTodo(todoItem)
    if (!result.valid) {
        res.status(400).json(result);
        return;
    }

    //
    // The todo item is valid, add it to the todo list.
    //
    todoList.push(todoItem);
    res.sendStatus(200);
});

我们现在对我们在前端和后端之间共享的数据结构进行了一些编译时验证。当然,这就是我们使用 TypeScript 的原因。编译时验证有助于防止编程错误——它为我们提供了一些自我保护。

但是,我们仍然需要运行时保护以防止我们的用户误用,无论是意外还是恶意,您可以看到validateTodo在之前的两个代码片段中仍然存在对的调用。

在 TypeScript 中的所有包上运行脚本

全栈 TypeScript 项目包含在所有子包上运行脚本的另一个很好的示例。

使用 TypeScript 时,我们经常需要构建我们的代码。这是在开发过程中发现错误的有用检查,也是将代码发布到生产环境的必要步骤。

在这个例子中,我们可以像这样在我们的 monorepo 中构建所有 TypeScript 项目(我们有三个独立的 TS 项目!):

pnpm run build

如果您查看 TypeScript 项目的package.json文件,您会看到build脚本实现如下:

pnpm --stream -r run build

这会build在每个嵌套的 TypeScript 项目上运行脚本,并为每个项目编译代码。

同样,该--stream标志从每个子脚本产生流式交错输出。我更喜欢默认选项,它分别显示每个脚本的输出,但有时它会折叠输出,这可能会导致我们错过重要信息。

另一个很好的例子是clean脚本:

pnpm run clean

没有什么比亲自尝试来建立理解更好的了。您应该尝试在您自己的全栈 TypeScript 项目副本中运行这些build和命令。clean

5. pnpm 是如何工作的?

在我们结束之前,这里简要总结一下 pnpm 与 npm 的工作方式。如果您正在寻找更完整的图片,请查看此帖子

pnpm 比 npm 快得多。多快?显然,根据基准,它快了 3 倍。我不知道。对我来说,pnpm 感觉快了 10 倍。这就是它对我的影响。

pnpm 有一种非常有效的方法来存储下载的包。通常,npm 将为您在计算机上安装的每个项目提供单独的包副本。当您的许多项目将共享依赖项时,这会浪费大量磁盘空间。

pnpm 还有一种完全不同的存储方法。它将所有下载的包存储在您的主目录中的单个.pnpm-store子目录下。从那里,它将包符号链接到需要它们的项目中,从而在所有项目之间共享包。他们制作这项工作的方式看似简单,但它产生了巨大的不同。

正如我们所见,pnpm 对在工作区中共享包和针对子包运行脚本的支持也很棒。npm 现在也提供工作空间,它们是可用的,但是使用 npm 对子包运行脚本似乎不像使用 pnpm 那样容易。如果我遗漏了什么,请告诉我!

pnpm 也支持在项目中共享包,同样使用符号链接。node_modules它为每个共享包创建符号链接。npm 做了类似的事情,所以它并不是那么令人兴奋,但我认为 pnpm 在这里获胜,因为它提供了更方便的方法来跨子包运行脚本。

结论

我一直在寻找成为更有效的开发人员的方法。采用支持我的工具并避免使用阻碍我的工具是成为快速开发人员的关键部分,也是我的新书《快速全栈开发》中的一个关键主题。这就是我选择 pnpm 而不是 npm 的原因——它快得多,对我的工作效率产生了重要影响。

感谢您的阅读,希望您在使用 pnpm 时玩得开心。 

来源:https ://blog.logrocket.com/managing-full-stack-monorepo-pnpm/

#pnpm