Coworking Full Flutter App. Complete Solution of your virtual office

Coworking Full Flutter App. Complete Solution of your virtual office booking. https://bit.ly/coworking_env #flutter #flutterdev #flutterapp #coworking #virtualoffice #workspace #booking #bookingoffice

Coworking - Workspace Booking Flutter App. v.1.0.6

Update version Coworking - Workspace Booking Flutter App. v.1.0.6. Compatible with Flutter v.3.7.5. Multipayments coming soon. Link: https://bit.ly/coworking_env #flutter #flutterdev #coworking #workspace #hotdesk #officebook #virtualoffice #flutterdeveloperindonesia #flutterapp 

Lawrence  Lesch

Lawrence Lesch

1677720000

Nextjs-monorepo-example: Collection Of Monorepo Tips & Tricks

NextJs Monorepo

Monorepo concepts, tips and tricks oriented around NextJs

Howtos for monorepo. New to monorepos ? check this FAQ. This example is managed by Yarn 3.2+ / typescript path aliases. Not the only way to do.

Useful to

  • Establish a structure and present a lifecycle perspective (dx, ci/cd, deployments...)
  • How to create and consume shared packages, locales, assets, api types...
  • Integrate tools & configs (eslint, jest, playwright, storybook, changelogs, versioning, codecov, codeclimate...).
  • Clarify some advantages of monorepos (team cohesion, consistency, duplication, refactorings, atomic commits...).
  • Create nextjs/vercel/prisma... bug reports with reproducible examples (initial goal of this repo).

Structure

Open in Gitpod

.
├── apps
│   ├── nextjs-app  (i18n, ssr, api, vitest)
│   ├── remix-app   (csr, ssr, api, jest)
│   └── vite-app
└── packages
    ├── api-gateway         (graphql mesh)
    ├── common-i18n         (locales...)
    ├── core-lib
    ├── db-main-prisma
    ├── eslint-config-bases (to shared eslint configs)
    └── ui-lib              (emotion, storybook)

Example apps

Apps should not depend on apps, they can depend on packages

Example shared packages

Apps can depend on packages, packages can depend on each others...

Shared static assets

If needed static resources like images,... can be shared by using symlinks in the repo.

Folder overview

Detailed folder structure

.
├── apps
│   ├── remix-app                (Remix.run app as an example)
│   │   ├── app/
│   │   ├── package.json         (define package workspace:package deps)
│   │   └── tsconfig.json        (define path to packages)
│   │
│   ├── vite-app                 (Vite app as an example)
│   │   ├── src/
│   │   ├── package.json         (define package workspace:package deps)
│   │   └── tsconfig.json        (define path to packages)
│   │
│   └── nextjs-app                  (NextJS app with api-routes)
│       ├── e2e/                 (E2E tests with playwright)
│       ├── public/
│       │   ├── shared-assets/   (possible symlink to global assets)
│       │   └── shared-locales/  (possible symlink to global locales)
│       ├── src/
│       │   └── pages/api        (api routes)
│       ├── CHANGELOG.md
│       ├── next.config.mjs
│       ├── package.json         (define package workspace:package deps)
│       ├── tsconfig.json        (define path to packages)
│       └── vitest.config.ts
│
├── packages
│   ├── core-lib                 (basic ts libs)
│   │   ├── src/
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   └── tsconfig.json
│   │
│   ├── db-main-prisma          (basic db layer with prisma)
│   │   ├── e2e/                (E2E tests)
│   │   ├── prisma/
│   │   ├── src/
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   └── tsconfig.json
│   │
│   ├── eslint-config-bases
│   │   ├── src/
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   └── tsconfig.json
│   │
│   └── ui-lib                  (basic design-system in react)
│       ├── src/
│       ├── CHANGELOG.md
│       ├── package.json
│       └── tsconfig.json
│
├── static                       (no code: images, json, locales,...)
│   ├── assets
│   └── locales
├── .yarnrc.yml
├── .dockerignore
├── docker-compose.nextjs-app.yml   (compose specific for nextjs-app)
├── docker-compose.yml           (general services like postgresql...)
├── Dockerfile                   (multistage build for nextjs-app)
├── package.json                 (the workspace config)
└── tsconfig.base.json           (base typescript config)

Howto

1. Enable workspace support

Root package.json with workspace directories

{
  "name": "nextjs-monorepo-example",
  // Set the directories where your apps, packages will be placed
  "workspaces": ["apps/*", "packages/*"],
  //...
}

The package manager will scan those directories and look for children package.json. Their content is used to define the workspace topology (apps, libs, dependencies...).

2. Create a new package

Create a folder in ./packages/ directory with the name of your package.

Create the package folder

mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poney

Initialize a package.json with the name of your package.

Rather than typing yarn init, prefer to take the ./packages/ui-lib/package.json as a working example and edit its values.

Example of package.json

{
  "name": "@your-org/magnificent-poney",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "clean": "rimraf ./tsconfig.tsbuildinfo",
    "lint": "eslint . --ext .ts,.tsx,.js,.jsx",
    "typecheck": "tsc --project ./tsconfig.json --noEmit",
    "test": "run-s 'test:*'",
    "test:unit": "echo \"No tests yet\"",
    "fix:staged-files": "lint-staged --allow-empty",
    "fix:all-files": "eslint . --ext .ts,.tsx,.js,.jsx --fix",
  },
  "devDependencies": {
    "@your-org/eslint-config-bases": "workspace:^",
  },
}

3. Using the package in app

Step 3.1: package.json

First add the package to the app package.json. The recommended way is to use the workspace protocol supported by yarn and pnpm.

cd apps/my-app
yarn add @your-org/magnificent-poney@'workspace:^'

Inspiration can be found in apps/nextjs-app/package.json.

package.json

{
  "name": "my-app",
  "dependencies": {
    "@your-org/magnificient-poney": "workspace:^",
  },
}

Step 3.2: In tsconfig.json

Then add a typescript path alias in the app tsconfig.json. This will allow you to import it directly (no build needed)

Inspiration can be found in apps/nextjs-app/tsconfig.json.

Example of tsonfig.json

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      // regular app aliases
      "@/components/*": ["./components/*"],
      // packages aliases, relative to app_directory/baseUrl
      "@your-org/magnificent-poney/*": [
        "../../../packages/magnificent-poney/src/*",
      ],
      "@your-org/magnificent-poney": [
        "../../../packages/magnificent-poney/src/index",
      ],
    },
  },
}

PS:

  • Don't try to set aliases in the global tsonfig.base.json to keep strict with graph dependencies.
  • The star in @your-org/magnificent-poney/* allows you to import subfolders. If you use a barrel file (index.ts), the alias with star can be removed.

Step 3.3: Next config

Edit your next.config.mjs and enable the experimental.externalDir option. Feedbacks here.

const nextConfig = {
  experimental: {
    externalDir: true,
  },
};

Using a NextJs version prior to 10.2.0 ?

If you're using an older NextJs version and don't have the experimental flag, you can simply override your webpack config.

const nextConfig = {
  webpack: (config, { defaultLoaders }) => {
    // Will allow transpilation of shared packages through tsonfig paths
    // @link https://github.com/vercel/next.js/pull/13542
    const resolvedBaseUrl = path.resolve(config.context, "../../");
    config.module.rules = [
      ...config.module.rules,
      {
        test: /\.(tsx|ts|js|jsx|json)$/,
        include: [resolvedBaseUrl],
        use: defaultLoaders.babel,
        exclude: (excludePath) => {
          return /node_modules/.test(excludePath);
        },
      },
    ];
    return config;
  },
};

PS: If your shared package make use of scss bundler... A custom webpack configuration will be necessary or use next-transpile-modules, see FAQ below.

Step 3.4: Using the package

The packages are now linked to your app, just import them like regular packages: import { poney } from '@your-org/magnificent-poney'.

4. Publishing

Optional

If you need to share some packages outside of the monorepo, you can publish them to npm or private repositories. An example based on microbundle is present in each package. Versioning and publishing can be done with atlassian/changeset, and it's simple as typing:

$ yarn g:changeset

Follow the instructions... and commit the changeset file. A "Version Packages" P/R will appear after CI checks. When merging it, a github action will publish the packages with resulting semver version and generate CHANGELOGS for you.

PS:

  • Even if you don't need to publish, changeset can maintain an automated changelog for your apps. Nice !
  • To disable automatic publishing of some packages, just set "private": "true" in their package.json.
  • Want to tune the behaviour, see .changeset/config.json.

4. Monorepo essentials

Monorepo scripts

Some convenience scripts can be run in any folder of this repo and will call their counterparts defined in packages and apps.

NameDescription
yarn g:changesetAdd a changeset to declare a new version
yarn g:typecheckRun typechecks in all workspaces
yarn g:lintDisplay linter issues in all workspaces
yarn g:lint --fixAttempt to run linter auto-fix in all workspaces
yarn g:lint-stylesDisplay css stylelint issues in all workspaces
yarn g:lint-styles --fixAttempt to run stylelint auto-fix issues in all workspaces
yarn g:testRun unit and e2e tests in all workspaces
yarn g:test-unitRun unit tests in all workspaces
yarn g:test-e2eRun e2e tests in all workspaces
yarn g:buildRun build in all workspaces
yarn g:cleanClean builds in all workspaces
yarn g:check-distEnsure build dist files passes es2017 (run g:build first).
yarn g:check-sizeEnsure browser dist files are within size limit (run g:build first).
yarn clean:global-cacheClean tooling caches (eslint, jest...)
yarn deps:check --dep devWill print what packages can be upgraded globally (see also .ncurc.yml)
yarn deps:update --dep devApply possible updates (run yarn install && yarn dedupe after)
yarn check:installVerify if there's no peer-deps missing in packages
yarn install:playwrightInstall playwright for e2e
yarn dedupeBuilt-in yarn deduplication of the lock file

Why using : to prefix scripts names ? It's convenient in yarn 3+, we can call those scripts from any folder in the monorepo. g: is a shortcut for global:. See the complete list in root package.json.

Maintaining deps updated

The global commands yarn deps:check and yarn deps:update will help to maintain the same versions across the entire monorepo. They are based on the excellent npm-check-updates (see options, i.e: yarn check:deps -t minor).

After running yarn deps:update, a yarn install is required. To prevent having duplicates in the yarn.lock, you can run yarn dedupe --check and yarn dedupe to apply deduplication. The duplicate check is enforced in the example github actions.

5. Quality

5.1 Linters

See an example in ./apps/nextjs-app/.eslintrc.js and our eslint-config-bases.

5.2 Hooks / Lint-staged

Check the .husky folder content to see what hooks are enabled. Lint-staged is used to guarantee that lint and prettier are applied automatically on commit and/or pushes.

5.3 Tests

Tests relies on ts-jest or vitest depending on the app. All setups supports typescript path aliases. React-testing-library is enabled whenever react is involved.

Configuration lives in the root folder of each apps/packages. As an example see

5.4 CI

You'll find some example workflows for github action in .github/workflows. By default, they will ensure that

  • You don't have package duplicates.
  • You don't have typecheck errors.
  • You don't have linter / code-style errors.
  • Your test suite is successful.
  • Your apps (nextjs) or packages can be successfully built.
  • Basic check-size example in nextjs-app.

Each of those steps can be opted-out.

To ensure decent performance, those features are present in the example actions:

Caching of packages (node_modules...) - install around 25s

Caching of nextjs previous build - built around 20s

Triggered when changed using actions paths, ie:

 paths:
   - "apps/nextjs-app/**"
   - "packages/**"
   - "package.json"
   - "tsconfig.base.json"
   - "yarn.lock"
   - ".yarnrc.yml"
   - ".github/workflows/**"
   - ".eslintrc.base.json"
   - ".eslintignore"

6. Editor support

6.1 VSCode

The ESLint plugin requires that the eslint.workingDirectories setting is set:

"eslint.workingDirectories": [
    {
        "pattern": "./apps/*/"
    },
    {
        "pattern": "./packages/*/"
    }
],

More info here

7. Deploy

Vercel

Vercel support natively monorepos, see the vercel-monorepo-deploy document.

Docker

There's a basic example for building a docker image, read the docker doc.

Others

Netlify, aws-amplify, k8s-docker, serverless-nextjs recipes might be added in the future. PR's welcome too.

FAQ

Monorepo

Benefits

  •  Ease of code reuse. You can easily extract shared libraries (like api, shared ui, locales, images...) and use them across apps without the need of handling them in separate git repos (removing the need to publish, version, test separately...). This limit the tendency to create code duplication amongst developers when time is short.
  •  Atomic commits. When projects that work together are contained in separate repositories, releases need to sync which versions of one project work with the other. In monorepo CI, sandboxes and releases are much easier to reason about (ie: dependency hell...). A pull-request contains all changes at once, no need to coordinate multiple packages versions to test it integrally (multiple published canary versions...).
  •  Code refactoring. Changes made on a library will immediately propagate to all consuming apps / packages. Typescript / typechecks, tests, ci, sandboxes... will improve the confidence to make a change (or the right one thanks to improved discoverability of possible side effects). It also limits the tendency to create tech debt as it invites the dev to refactor all the code that depends on a change.
  •  Collaboration across teams. Consistency, linters, discoverability, duplication... helps to maintain cohesion and collaboration across teams.

Drawbacks

  •  Increased build time. Generally a concern but not relevant in this context thanks to the combination of nextjs/webpack5, typescript path aliases and yarn. Deps does not need to be build... modified files are included as needed and properly cached (nextjs webpack5, ci, deploy, docker/buildkit...).
  •  Versioning and publishing. Sometimes a concern when you want to use the shared libraries outside of the monorepo. See the notes about atlassian changeset. Not relevant here.
  •  Git repo size. All packages and apps and history will fit in the same git repository increasing its size and checkout time. Generally when you reach size problems, check for assets like images first and extract packages that don't churn anymore.
  •  Multi-languages. Setting up a monorepo containing code in multiple languages (php, ruby, java, node) is extremely difficult to handle due to nonexistence of mature tooling (bazel...).The general idea is to create a monorepo with the same stack (node, typescript...) and managed by the same package manager (yarn, pnpm,...)

Exact vs semver dependencies

Apps dependencies and devDependencies are pinned to exact versions. Packages deps will use semver compatible ones. For more info about this change see reasoning here and our renovabot.json5 configuration file.

To help keeping deps up-to-date, see the yarn deps:check && yarn deps:update scripts and / or use the renovatebot.

When adding a dep through yarn cli (i.e.: yarn add something), it's possible to set the save-exact behaviour automatically by setting defaultSemverRangePrefix: "" in yarnrc.yml. But this would make the default for packages/* as well. Better to handle yarn add something --exact on per-case basis.


Sponsors ❤️

If you are enjoying some this guide in your company, I'd really appreciate a sponsorship, a coffee or a dropped star. That gives me some more time to improve it to the next level.


Download Details:

Author: Belgattitude
Source Code: https://github.com/belgattitude/nextjs-monorepo-example 
License: MIT license

#typescript #yarn #nextjs #workspace 

Nextjs-monorepo-example: Collection Of Monorepo Tips & Tricks
Lawrence  Lesch

Lawrence Lesch

1677672805

How to Build TypeScript Mono-repo Project with Yarn and Lerna

How to build TypeScript mono-repo project

Tools

Directory Structure

Put each package under the packages directory.

.
├── README.md
├── lerna.json
├── package.json
├── packages
│   ├── x-cli
│   │   ├── lib
│   │   │   ├── main.d.ts
│   │   │   ├── main.js
│   │   │   └── main.js.map
│   │   ├── package.json
│   │   ├── src
│   │   │   └── main.ts
│   │   └── tsconfig.json
│   └── x-core
│       ├── lib
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   └── index.js.map
│       ├── package.json
│       ├── src
│       │   └── index.ts
│       └── tsconfig.json
├── tsconfig.json
└── yarn.lock

Workspaces

Using yarn workspace feature, configure the following files:

  • /package.json

Append the workspaces key.

{
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}
  • lerna.json

Set npmClient "yarn" and turn useWorkspaces on.

{
  "lerna": "2.2.0",
  "packages": [
    "packages/*"
  ],
  "npmClient": "yarn",
  "useWorkspaces": true,
  "version": "1.0.0"
}

Exec yarn install(or lerna bootstrap). After successful running, all dependency packages are downloaded under the repository root node_modules directory.

Dependencies between packages

In this example, the x-cli package depends on another package, x-core. So to execute (or test) x-cli, x-core packages should be installed. But in development the x-core package is not published so you can't install it.

yarn solves this problem. This command creates sim-links of each package into the top-level node_modules dir.

Resolve Dependencies as TypeScript Modules

As mentioned above, Lerna resolves dependencies between packages. It's enough for "runtime". However considering TypeScript sources, in other words "static", it's not.

For example, the following code depends a module x-core located at other package.

/* packages/x-cli/src/main.ts */
import { awesomeFn } from "@quramy/x-core";

export function cli() {
  awesomeFn();
  return Promise.resolve(true);
}

If you compile this code, TypeScript compiler emits a "Cannot find module" error until building x-core package and creating x-core/index.d.ts. And it's silly to compile dependent packages(e.g. x-core) in the same repository after each editing them.

TypeScript's path mapping is the best solution. Path mappings are declared such as:

/* tsconfig.json */
{
  "compilerOptions": {
    /* other options */
    "baseUrl": "./packages",
    "paths": {
      "@quramy/*": ["./*/src"]
    }
  }
}

The above setting means import { awesomeFn } from "@quramy/x-core" is mapped to import { awesomeFn } from "../../x-core/src"(it's relative from "packages/x-cli/src/main.ts"). In other words, path mapping allows to treat developing packages' sources as published(compiled) modules.

References between packages

TypeScript 3.0 supports Project reference feature. You can tell tsc that x-cli depends on x-core project using this.

/* packages/x-cli/tsconfig.json */
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib"
  },
  "references": [
    { "path": "../x-core" }
  ]
}

In the above json, the key references means the dependency.

Compile all packages

Our repository has multiple tsconfig.json files. We can compile all packages with "-b" option:

$ tsc -b packages/x-core packages/x-cli

Download Details:

Author: Quramy
Source Code: https://github.com/Quramy/lerna-yarn-workspaces-example 
License: MIT license

#typescript #yarn #guide #workspace 

How to Build TypeScript Mono-repo Project with Yarn and Lerna
Gordon  Matlala

Gordon Matlala

1671629164

How to Shared Cypress Assets in an Nx Workspace

tldr;

Many times Nx workspaces have multiple applications, and being able to share custom Cypress commands between the end to end test projects. I spent several months manually copying these commands between the different projects, and would inevitably forget to update one when a change was made. Finally I decided to solve the problem and find a way to share the Cypress assets among the projects. This article will cover one way to do this.

To follow along, you'll need an Nx workspace with at least one end to end project.

Create the Shared Assets Library

Let's get started by creating a shared end to end assets library. This will be similar to creating any other library in an Nx workspace. The only potential difference will be the type of library you create. Nx provides a way to create Angular specific libraries, for example. In this case, we don't want to create a framework specific library. That can be accomplished with the following command:

$ nx g @nrwl/workspace:library e2e-assets --directory shared

This command creates a generic Nx workspace library called e2e-assets and puts it in the libs/shared directory. In this library we'll add custom Cypress commands which we can then use in all our end to end projects.

Create Custom Command File

Let's now add a file that contains a custom Cypress command in our new shared library. This custom command will make it easier to select elements by the data-cy HTML attribute. Create a file in the e2e-assets/src/lib folder called data-cy.commands.ts. Here are the contents of that file:

// data-cy.commands.ts

// load the global Cypress types
/// <reference types="cypress" />

declare namespace Cypress {
  interface Chainable {
    /**
     * Custom command to get elements by data-cy attribute.
     * @example cy.dataCy('greeting')
     */
    dataCy(selector: string): Chainable<Element>;
  }
}

Cypress.Commands.add('dataCy', (value) => cy.get(`[data-cy=${value}]`));

The first two lines of the file load the types for Cypress and prevent errors from showing in your IDE. The next portion of the file essentially extends the Cypress object for your tests by declaring the new custom command. If you leave this out and try to use the dataCy command you will get an error and the command will not work. The last line of the file is the code to actually add the custom command. The first argument to the Cypress.Commands.add method is the name of the new command, and the second argument is a callback function that provides the functionality for the custom command.

This custom command returns the cy.get method and selects an element by the data-cy HTML attribute. We'll look at how it's used later.

Importing the Custom Command

The next step is to import the new custom command so it can be used in our Cypress tests. The first import belongs in the e2e-assets/src/index.ts file:

// e2e-assets/src/index.ts

import './lib/data-cy.commands';

This makes the new command available when we import this library into our Cypress tests, which we'll do next. The second import belongs in the app-e2e/src/support/index.ts file. By importing the library here, this new command will be available in the app-e2e Cypress tests.

// app-e2e/src/support/index.ts
import '@my-org/shared/e2e-assets';

Now that you have imported your shared e2e assets library, you can use the new command.

Using The New Custom Command

Here's an example of using the new custom command in a Cypress test:

// app-e2e/src/integration/test.ts

it('should show the homepage', () => {
  cy.dataCy('homepage').should('be.visible');
});

If you didn't use this custom command, your test would like this:

// app-e2e/src/integration/test.ts

it('should show the homepage', () => {
  cy.get('[data-cy=homepage]').should('be.visible');
});

There's not a big difference here, but speaking from experience it gets tiresome to repeat the attribute selector each time you need access to an element based on the data-cy attribute. This simple custom command is much easier to use.

Conclusion

One of the biggest benefits of Nx workspaces is the ability to share code between projects. It's natural to share code between Angular or React apps, but the same process can be used to share code for your Cypress end to end tests. It becomes especially useful the more apps you have in your workspace, and for more complicated Cypress commands.

Original article source at: https://www.prestonlamb.com/

#cypress #nx #workspace 

How to Shared Cypress Assets in an Nx Workspace
Hoang  Kim

Hoang Kim

1661170810

Cách Xây Dựng Thư Viện Bằng JavaScript, Webpack Và Workspaces

Hướng dẫn xây dựng thư viện bằng cách sử dụng không gian làm việc Webpack và Yarn. 

Yêu cầu

Đây là những yêu cầu. Nhưng nếu bạn kiểm tra kho lưu trữ, có tài liệu tham khảo và giải thích. Tôi đã cố gắng cung cấp lời giải thích tốt nhất có thể, nhưng nó hiếm khi hoàn hảo hoặc chung chung cho tất cả mọi người. Có các bước để xây dựng và kiểm tra mã để bạn có thể thử nghiệm với nó. Rất nhiều tài nguyên để đào và tìm hiểu cách thức hoạt động của nó.

  • Làm quen với JavaScript.
  • Một số quen thuộc với Webpack. Mã sử ​​dụng cấu hình tối thiểu khoảng 15 dòng mã.
  • Một số quen thuộc với không gian làm việc của Yarn.

Mục đích

Xây dựng một ứng dụng trình bày các gói xây dựng bằng JavaScript và monorepo.

Phân tách logic bằng cách sử dụng monorepo

Sử dụng gói mô-đun để tạo một gói phụ thuộc vào một gói khác chưa được xuất bản lên NPM.

Thông số kỹ thuật

Để ngắn gọn, chúng ta hãy làm một chiếc máy tính bỏ túi.

Chúng tôi sẽ xây dựng một ứng dụng máy tính có bốn hoạt động:

+    add
-    subtract
*    multiply
/    divide

Chúng tôi đang xây dựng một máy tính. Chúng tôi chia logic thành bốn gói.

Máy tính của chúng tôi sẽ sử dụng bốn gói. Chúng tôi sử dụng webpack để xây dựng gói máy tính của mình.

Khởi tạo kho lưu trữ

Run (Lệnh sau là viết tắt của yarn install) :

yarn

Gói xây dựng

Phát triển và sản xuất

yarn build

Chạy thử nghiệm

Đầu tiên xây dựng gói.

Để kiểm tra trong trình duyệt:

  1. Đi tới __tests__thư mục
  2. Mở useDevBuild.htmltrong trình duyệt
  3. Mở useProdBuild.htmltrong trình duyệt
  4. Mở bảng điều khiển dành cho nhà phát triển và xác minh rằng đầu ra ở đó

Để kiểm tra trong chạy nodejs:

kiểm tra sợi

Người giới thiệu

Kết quả

Sử dụng không gian làm việc sợi, mọi gói sẽ được cài đặt trong thư mục gốc node_modules. Điều đó cho phép nhiều nhóm làm việc trên từng gói riêng lẻ. Hoặc một nhóm làm việc trên mỗi gói. Việc chuyển từ monorepo sang multirepo dễ dàng hơn so với cách khác. Hãy tra cứu điều này trên internet, đừng nghe lời tôi.

Sử dụng webpack, điểm nhập là một máy tính. Nó sẽ tra cứu mã máy tính đang sử dụng và tạo ra một bản dựng.

Chúng tôi thử nghiệm bản dựng sau đó. Bản dựng là mô-đun UMD có nghĩa là chúng ta có thể sử dụng nó trong môi trường trình duyệt và NodeJS. Tra cứu trên internet về các gói cho NodeJS và Trình duyệt. Họ yêu cầu shimming .

Chúng tôi kiểm tra các bản xuất được đặt tên và mặc định trong NodeJS, bằng cách in kết quả. Trong trình duyệt, chúng tôi cũng làm như vậy.

Khai báo một thư mục dưới dạng thư mục không gian làm việc:

{
  "name": "calculator-demo",
  "version": "0.1.0",
  "workspaces": ["packages/*"]
}

Chìa khóa ở đây là workspacestài sản. Khai báo tất cả các thư mục trong packagesdưới dạng không gian làm việc. Mỗi người trong số họ cần phải có package.json.

Liên kết: https://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8

#javascript #webpack  #workspace 

Cách Xây Dựng Thư Viện Bằng JavaScript, Webpack Và Workspaces

Как создать библиотеку с помощью JavaScript, Webpack и Workspaces

Руководство по созданию библиотеки с использованием рабочих пространств Webpack и Yarn. 

Требования

Это требования. Но если вы заглянете в репозиторий, там есть ссылки и пояснения. Я пытался дать объяснение настолько хорошо, насколько мог, но оно редко бывает идеальным или универсальным для всех. Существуют шаги для создания и тестирования кода, чтобы вы могли поиграть с ним. Много ресурсов, чтобы покопаться и узнать, как это работает.

  • Знакомство с JavaScript.
  • Некоторое знакомство с Webpack. Код использует минимальную конфигурацию около 15 строк кода.
  • Некоторое знакомство с рабочими пространствами Yarn.

Цель

Создайте приложение, демонстрирующее сборку пакетов с использованием JavaScript и монорепозитория.

Разделить логику с помощью монорепозитория

Используйте сборщик модулей для создания пакета, который зависит от другого пакета, не опубликованного в NPM.

Спецификации

Для краткости сделаем калькулятор.

Мы создадим приложение-калькулятор, которое будет выполнять четыре операции:

+    add
-    subtract
*    multiply
/    divide

Делаем калькулятор. Мы разделяем логику на четыре пакета.

Наш калькулятор будет использовать четыре пакета. Мы используем webpack для сборки нашего пакета калькулятора.

Инициировать репозиторий

Выполнить (следующая команда является сокращением для yarn install) :

yarn

Сборка пакета

Разработка и производство

yarn build

Запустить тесты

Сначала соберите пакет.

Для проверки в браузере:

  1. Перейти в __tests__каталог
  2. Открыть useDevBuild.htmlв браузере
  3. Открыть useProdBuild.htmlв браузере
  4. Откройте консоль разработчика и убедитесь, что вывод есть

Для тестирования в nodejs запустите:

тест пряжи

использованная литература

Исход

Используя рабочие области пряжи, каждый пакет будет установлен в корневой node_modulesкаталог. Это позволяет нескольким командам работать над каждым отдельным пакетом. Или одна команда для работы над каждым пакетом. Мигрировать с монорепозитория на мультирепо проще, чем наоборот. Поищите в инете, не верьте мне на слово.

При использовании webpack точкой входа является калькулятор. Он найдет используемый калькулятор кода и произведет сборку.

После этого мы тестируем сборку. Сборка представляет собой модуль UMD, что означает, что мы можем использовать его в среде браузера и NodeJS. Поищите в Интернете информацию о пакетах для NodeJS и браузеров. Они требуют шимминга .

Мы тестируем именованный экспорт и экспорт по умолчанию в NodeJS, распечатывая результаты. В браузере делаем то же самое.

Объявление каталога в качестве каталога рабочей области:

{
  "name": "calculator-demo",
  "version": "0.1.0",
  "workspaces": ["packages/*"]
}

Главное здесь — workspacesсобственность. Объявляет все каталоги в packagesкачестве рабочей области. У каждого из них должен быть package.json.

Ссылка: https://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8

#javascript #webpack  #workspace 

Как создать библиотеку с помощью JavaScript, Webpack и Workspaces
田辺  亮介

田辺 亮介

1661156340

如何使用 JavaScript、Webpack 和 Workspaces 構建庫

使用 Webpack 和 Yarn 工作區構建庫的指南。 

要求

這些是要求。但是,如果您確實查看了存儲庫,則會有參考資料和解釋。我試圖提供盡可能好的解釋,但它很少對每個人都是完美或普遍的。有一些步驟可以構建和測試代碼,以便您可以使用它。大量的資源可以挖掘和學習它是如何工作的。

  • 熟悉JavaScript。
  • 對 Webpack 有一定的了解。該代碼使用大約 15 行代碼的最小配置。
  • 熟悉 Yarn 工作區。

目標

構建一個演示使用 JavaScript 和 monorepo 構建包的應用程序。

使用 monorepo 拆分邏輯

使用模塊捆綁器創建一個依賴於另一個未發佈到 NPM 的包的包。

眼鏡

為了簡潔起見,讓我們做一個計算器。

我們將構建一個具有四個操作的計算器應用程序:

+    add
-    subtract
*    multiply
/    divide

我們正在構建一個計算器。我們將邏輯拆分為四個包。

我們的計算器將使用四個包。我們使用 webpack 來構建我們的計算器包。

啟動存儲庫

運行(以下命令是 的簡寫yarn install

yarn

構建包

開發與生產

yarn build

運行測試

首先構建包。

在瀏覽器中測試:

  1. 轉到__tests__目錄
  2. useDevBuild.html在瀏覽器中打開
  3. useProdBuild.html在瀏覽器中打開
  4. 打開開發者控制台並驗證輸出是否存在

要在 nodejs 中進行測試,請運行:

紗線測試

參考

結果

使用 yarn 工作區,每個包都將安裝在根node_modules目錄中。這允許多個團隊處理每個單獨的包。或者一個團隊來處理每個包。從 monorepo 遷移到 multirepo 比其他方式更容易。在網上查一下,不要相信我的話。

使用 webpack,入口點是一個計算器。它將查找計算器正在使用的代碼並生成構建。

之後我們測試構建。該構建是 UMD 模塊,這意味著我們可以在瀏覽器和 NodeJS 環境中使用它。在 Internet 上查找有關 NodeJS 和瀏覽器的軟件包。他們需要勻場

我們通過打印結果來測試 NodeJS 中的命名和默認導出。在瀏覽器中我們也這樣做。

將目錄聲明為工作區目錄:

{
  "name": "calculator-demo",
  "version": "0.1.0",
  "workspaces": ["packages/*"]
}

這裡的關鍵是workspaces財產。將所有目錄聲明packages為工作空間。他們每個人都需要有 package.json。

鏈接:https ://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8

#javascript #webpack  #workspace 

如何使用 JavaScript、Webpack 和 Workspaces 構建庫
Hans  Marvin

Hans Marvin

1661149080

How to Build Library using JavaScript, Webpack and Yarn Workspaces

A guide on building library using Webpack and Yarn workspaces. 

Requirements

These are the requirements. But if you do check out the repository, there are references and explanation. I tried to provide explanation as good as I could, but it’s rarely perfect or univeral for everyone. There are steps to build and test the code so you can play around with it. Plenty of resources to dig and learn how it works.

  • Familiarity with JavaScript.
  • Some familiarity with Webpack. The code is using minimal configuration of around 15 lines of code.
  • Some familiarity with Yarn workspaces.

See more at: https://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8

#javascript #webpack  #workspace 

How to Build Library using JavaScript, Webpack and Yarn Workspaces
Thierry  Perret

Thierry Perret

1661141728

Création D'une Bibliothèque à L'aide De JS, Webpack Et Workspaces

Un guide sur la construction d'une bibliothèque à l'aide des espaces de travail Webpack et Yarn. 

Conditions

Ce sont les exigences. Mais si vous consultez le référentiel, il y a des références et des explications. J'ai essayé de fournir des explications aussi bonnes que possible, mais c'est rarement parfait ou universel pour tout le monde. Il y a des étapes pour construire et tester le code afin que vous puissiez jouer avec. Beaucoup de ressources pour creuser et apprendre comment cela fonctionne.

  • Familiarité avec JavaScript.
  • Une certaine familiarité avec Webpack. Le code utilise une configuration minimale d'environ 15 lignes de code.
  • Une certaine familiarité avec les espaces de travail Yarn.

Le but

Créez une application qui illustre la création de packages à l'aide de JavaScript et de monorepo.

Logique fractionnée à l'aide de monorepo

Utilisez module bundler pour créer un package qui dépend d'un autre package qui n'est pas publié sur NPM.

Spécifications

Par souci de brièveté, faisons une calculatrice.

Nous allons créer une application de calculatrice comportant quatre opérations :

+    add
-    subtract
*    multiply
/    divide

Nous construisons une calculatrice. Nous avons divisé la logique en quatre packages.

Notre calculatrice utilisera quatre packages. Nous utilisons webpack pour créer notre package de calculatrice.

Lancer le référentiel

Exécuter (La commande suivante est un raccourci pour yarn install) :

yarn

Construire le paquet

Développement et fabrication

yarn build

Exécuter des tests

Construisez d'abord le package.

Pour tester dans le navigateur :

  1. Aller au __tests__répertoire
  2. Ouvrir useDevBuild.htmldans le navigateur
  3. Ouvrir useProdBuild.htmldans le navigateur
  4. Ouvrez la console du développeur et vérifiez que la sortie est là

Pour tester dans nodejs, exécutez :

test de fil

Références

Résultat

En utilisant les espaces de travail yarn, chaque package sera installé dans le node_modulesrépertoire racine. Cela permet à plusieurs équipes de travailler sur chaque package individuel. Ou une équipe pour travailler sur chaque paquet. Il est plus facile de migrer de monorepo vers multirepo que l'inverse. Regardez ça sur internet, ne me croyez pas sur parole.

En utilisant Webpack, le point d'entrée est une calculatrice. Il recherchera le calculateur de code utilisé et produira une construction.

Nous testons la construction par la suite. La construction est un module UMD, ce qui signifie que nous pouvons l'utiliser dans les environnements de navigateur et NodeJS. Recherchez sur Internet des packages pour NodeJS et les navigateurs. Ils nécessitent un calage .

Nous testons les exportations nommées et par défaut dans NodeJS, en imprimant les résultats. Dans le navigateur, nous faisons la même chose.

Déclarer un répertoire comme répertoire de l'espace de travail :

{
  "name": "calculator-demo",
  "version": "0.1.0",
  "workspaces": ["packages/*"]
}

La clé ici est workspacesla propriété. Déclare tous les répertoires en packagestant qu'espace de travail. Chacun d'eux doit avoir package.json.

Lien : https://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8

#javascript #webpack  #workspace 

Création D'une Bibliothèque à L'aide De JS, Webpack Et Workspaces
Hermann  Frami

Hermann Frami

1657222080

Serverless Workspaces Plugin

serverless-workspaces-plugin

resolve and link hoisted dependencies when packaging

table of contents

  • install
  • usage
  • license

install

yarn add serverless-workspaces-plugin -W

usage

plugins:
  - serverless-workspaces-plugin

check out the example for more

Author: Sergioramos
Source Code: https://github.com/sergioramos/serverless-workspaces-plugin 
License: BSD-3-Clause license

#serverless #plugin #workspace 

Serverless Workspaces Plugin
Reid  Rohan

Reid Rohan

1654054260

A Jest Watch Plugin to Select Yarn Workspaces To Test

jest-watch-yarn-workspaces 

A Jest watch plugin to select Yarn workspaces to test

Usage

Install

Install jest (it needs Jest 23+) and jest-watch-yarn-workspaces

yarn add --dev jest jest-watch-yarn-workspaces

# or with NPM

npm install --save-dev jest jest-watch-yarn-workspaces

Add it to your Jest config

In your package.json

{
  "jest": {
    "watchPlugins": ["jest-watch-yarn-workspaces"]
  }
}

Or in jest.config.js

module.exports = {
  watchPlugins: ['jest-watch-yarn-workspaces']
};

Run Jest in watch mode

yarn jest --watch

FAQ

Why is this not filtering my workspaces?

Make certain that you're using the SPACE key to toggle the selected state of workspaces and the ENTER key to confirm your settings.

Author: Cameronhunter
Source Code: https://github.com/cameronhunter/jest-watch-directories/tree/master/packages/jest-watch-yarn-workspaces 
License: 

#javascript #jest #workspace 

A Jest Watch Plugin to Select Yarn Workspaces To Test
渚  直樹

渚 直樹

1650052800

ワークスペースおよびその他の高度なパッケージマネージャー機能の調査

この記事は、開発者が適切なパフォーマンスと優れたDXを備えた大規模なモノレポプロジェクトを管理できるようにするなど、開発者のニーズをサポートするためにパッケージマネージャーが将来どこに向かっているのかを印象付けることを目的としています。

以前の記事で、npm、Yarn、およびpnpm間の依存関係解決戦略のトピックについて書きました。前回の記事ではコアの概念と構造の比較に焦点を当てていましたが、この記事では、ワークスペースを通じて、モノリポジトリを含む最新のパッケージマネージャーの高度な機能について説明します。

この記事の目的は、Yarnとpnpmが、開発者がワークスペースを介してモノリポジトリを構築できるようにし、セキュリティとパフォーマンスを向上させるためのより高度なアプローチを提供することに、どのように注力してきたかを伝えることです。 

コンパニオンプロジェクト

この記事では、いくつかのパッケージマネージャー機能について説明します。したがって、例を示すために、GitHubで2つのコンパニオンプロジェクトを作成しました。

  1. ワークスペース機能をデモンストレーションするmonorepoプロジェクト
  2. さまざまな依存関係解決戦略を示す別のプロジェクト

代替の依存関係解決戦略

デフォルト構成を使用する場合、pnpmとYarn Berryは、npmとYarn Classicと同じ依存関係解決アルゴリズムを使用しません。これには、node_modulesフォルダーのフラット化が含まれます。これらの最新のパッケージマネージャーは、依存関係を処理および保存するための従来のアプローチとは別の方法を試みます。

この理由は、大量の依存関係をますます利用する最新のソフトウェアプロジェクトの要件に対処するには、革新的な解決アプローチが必要であるためです。従来の戦略は、パフォーマンスとディスクスペース効率の点で限界に達しています。

従来のnode_modulesアプローチの問題

node_modulesフォルダをフラット化する従来の依存関係解決戦略では、いくつかの異なる問題が発生します。

  • モジュールは(偶然に)依存していないパッケージにアクセスする可能性があり、バグにつながる可能性があります
  • 平坦化アルゴリズムは時間のかかるI/Oプロセスです

このフラットレイアウトの根本的な問題は、v3のnpmによって導入された巻き上げnode_modules呼ばれる概念です。これと同じ依存関係解決アルゴリズムは、最初はYarnClassicでも使用されていました。

簡単に言えば、巻き上げるとnode_modules、依存関係の依存関係も含めて、すべての依存関係がルートレベルの。になるようにフォルダーがフラット化されますnode_modules。すべてを1つのフォルダーレベルに持ち上げる理由は、ネストによって生じる冗長性を減らすためです。次の画像は、これがどのように機能するかを示しています。

 

npmv2とnpmv3のnode_moduleアルゴリズムの違い

巻き上げは、特に大規模なプロジェクトでは、深刻で検出が困難なエラーにつながる可能性があります。Jonathan Creamerは、巻き上げアルゴリズムが失敗して生産エラーが発生するモノレポプロジェクトで何がうまくいかないかについて詳細に説明しています。このような状況では、巻き上げは幻の依存関係ドッペルゲンガーにつながる可能性があります。

ヤーンベリーのプラグアンドプレイアプローチ

ヤーンベリーは、プラグアンドプレイアプローチnode_modulesを使用して、完全に捨てようとしました。Yarn Berryの駆除の動機について読むことができますが、その理由はpnpmの場合と同様です。node_modules

requirePnPは、Nodeの新しく革新的なインストール戦略であり、その非効率性の多くに取り組む確立された(そして唯一の)Common、jsワークフローとは対照的に開発されました。従来の方法とは対照的に、Yarn Berryは、誰がパッケージを見つけるかについて責任を負います。

以前は、Nodeはnode_modulesフォルダー内でパッケージを見つける必要がありました。PnPモードのYarnBerryは、必要なすべての情報をすでに手元に持っており、代わりに、それらを見つける場所をNodeに指示します。これにより、パッケージのインストール時間が大幅に短縮されます。

Yarn Berry.pnp.cjsは、ネストされたnode_modulesフォルダーの代わりにファイルを生成することでこれを実現します。依存関係の場所についてノードに通知するためのルックアップテーブルが含まれています。利点の1つとして、Yarn Berryは、ファイルの1つで定義したパッケージの場所のみを共有するようにすることができpackage.jsonます。これにより、セキュリティが向上し、エラーが減少します。ドッペルゲンガーやファントムの依存関係について心配する必要がなくなります。他の種類の違法アクセス。

ただし、主な利点はインストール速度が速いことです。1つのファイル、つまりファイルのみを処理.pnp.cjsしているため、I/O操作が少なくなります。ノード解決アルゴリズムの作業量が少なくて済むため、起動時間も改善できます。

node_modulesしかし、フォルダがない場合、パッケージはどこに保存されますか?すべてのパッケージは、フォルダ内にzipファイルとして保存され.yarn/cache/ます。これが機能するのは、Yarn BerryがノードのファイルシステムAPIにパッチを適用して、内部の依存関係の要求をnode_modulesキャッシュ内のzipアーカイブの内容から解決する必要があるためです。node_modulesこれらのzipアーカイブは、フォルダーよりも少ないディスク容量を使用します。

PnPはYarnBerryのデフォルトモードですが、内で明示的に有効にすることもできます.yarnrc.yml

# .yarnrc.yml
# alternatively, remove the next two lines, PnP strict is the default
nodeLinker: "pnp"
pnpMode: "strict"

典型的なPnPプロジェクトの構造は次のようになります。node_modulesフォルダはありません。依存関係はのzipファイルに保存されます.yarn/cache/

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

YarnBerryPnPの依存関係に関する問題のデバッグ

依存関係の問題をデバッグするには、zipファイルの「内部を調べる」必要があるため、追加のツールサポート( VS Code Extensionなど)が必要です。このような機能は組み込まれていないため、執筆時点では、エディターSDKサポートを追加して手動の手順を実行する必要があります。次のコマンドは、VSCodeのサポートを追加します

$ yarn dlx @yarnpkg/sdks vscode

SDK CLIは、サポートされているテクノロジーについてルートpackage.jsonを分析し、に保存される構成ファイルを生成します。.yarn/sdk/

SDKCLIのファイル変更

デモプロジェクトの場合、ESLintPrettierを検出します。Gitブランチをチェックして、PnPおよびSDKサポートyarn-berry-pnpの例を確認してください。

ヤーンベリーゼロインストール戦略

.pnp.cjsPnPの良いところは、ファイルサイズが適切であるため、ファイルと.yarn/cache/フォルダーをバージョン管理下に置くことができることです。これから得られるのは、ゼロインストール戦略です。チームメイトがGitからコードをプルする場合(この戦略を使用すると少し時間がかかる場合があります)、すべてのパッケージとルックアップテーブルが手元にあり、アプリケーションを開始する前にインストール手順は必要ありません。ゼロインストールの動作を示す短いデモビデオをご覧ください。

.gitignoreファイルがYarnBerryPnPゼロインストールブランチのように見えることがわかります。依存関係を追加、更新、または削除する場合はyarn install、もちろん、、、およびフォルダーを更新するyarn.lockため.pnp.cjs.yarn/cache/実行する必要があります。

PnPのオプトアウト:ルーズモード

PnPは制限があり、互換性のない一部のパッケージ(React Nativeなど)では機能しない場合があります。さらに、PnPへの移行はスムーズな方法ではない可能性があります。したがって、YarnBerryはルーズモードを提供します。それに応じてプロパティ.yarnrc.ymlを設定することにより、それをアクティブにすることができます。nodeLinker

# .yarnrc.yml
nodeLinker: "pnp"
pnpMode: "loose"

ルーズモードは、PnPストリクトモードと従来のnode_modules依存関係解決メカニズムの間の妥協点です。違いは、Yarn Berryは、エラーで中止するのではなく、安全でない依存関係アクセスについてのみ警告することです。

内部的には、Yarn Berryは従来の巻き上げアルゴリズムを実行し、それをすべての不特定の依存関係のフォールバックとして使用します。これは、Yarn Berryの基準では依然として安全でないと見なされていますが、時間を節約できる可能性があります。受信した警告を分析し、根本的な問題を修正し、必要に応じてPnPstrictにすばやく戻ることができます。

node_modulesYarn Classicはレガシーと見なされており、いくつかの改善の恩恵を受けていますが、を使用した従来のインストールモードに固執しているため、YarnBerryに切り替えることをお勧めしますnode-modules nodeLinker

# .yarnrc.yml
nodeLinker: "node-modules"

これにより、古き良きnode_modulesフォルダが再び生成されます。

Yarn Berryチームは、pnpmのコンテンツアドレス可能なストレージ戦略にも触発されました。これについては以下で説明し、同じ名前のモードを追加しました。これはその原型に似ており、依存関係をハードドライブに一度だけ保存することを目的としています。

# .yarnrc.yml
nodeLinker: "pnpm"

デモプロジェクトの対応するGitブランチをチェックして、さまざまなモードを自由にテストしてください。

pnpmの最適化されnode_modulesた戦略

pnpmは、依存関係をnode_modulesnpmのようにネストされたフォルダーに格納しますが、コンテンツアドレス可能なストレージを実装しているため、パフォーマンスとディスクスペースの効率が向上します。これについては、パッケージマネージャーに関する以前の記事で詳しく読むことができます。

pnpmのプラグアンドプレイ戦略

2020年の終わりから、pnpm v5.9はPnPもサポートし、 Yarnのプラグアンドプレイとも呼ばれます。この機能に関するドキュメントはまばらです。pnpmのリード開発者は、YarnBerryのドキュメントを参照しています。

pnpm PnPブランチは、このモードの使用方法を示しています。でPnPモードをアクティブにする必要があります.npmrc

# .npmrc
node-linker=pnp
symlink=false

を実行するpnpm iと、プロジェクトの構造は次のようになります。

.
├── node_modules/
│   ├── .bin/
│   └── .pnpm/
├── .npmrc
├── .pnp.cjs
├── package.json
└── pnpm-lock.yaml

巻き上げなしのアプローチの結果

pnpmとYarnBerryは、巻き上げは悪い習慣だと考えています。すでに述べたように、JavaScriptエコシステムの多くのプロジェクトは、npmおよび以前のバージョンのYarnで使用されていたものに基づいて巻き上げの実装を行っています。このセクションでは、巻き上げなしのアプローチに伴ういくつかの問題に焦点を当てます。

pnpmデモブランチで、バイナリの実行で問題が発生しましたntl。pnpmのフラットでないレイアウトのために機能しませんでした。そのため、同様の問題node_modulesについてpnpmのリード開発者と話し合い、ホイストの解決策を示しました。ntl

# .npmrc
hoist-pattern[]=*ntl*

Yarn Berry PnPアプローチでは、ほとんどの場合、同様の状況に遭遇します。PnPデモブランチの開発中に、起動時にこのエラーが発生しました。

起動時のPnPstrictのエラー

スタックトレースで、react-is実行時にという名前のパッケージが見つからなかったことがわかりました。上のスクリーンショットの左側にあるエラーメッセージは、これが私ので指定したstyled-componentsパッケージpackage.jsonに関係していることを示しています。にすべての依存関係がリストされてstyled-componentsいるわけではないようです。 package.json

このようなPnP問題の典型的な解決策があります:packageExtensionsプロパティ.yarnrc.yml不足している依存関係をインストールするために追加を更新して実行するとyarn install、問題が修正されます。

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

上記のように、プロジェクトでPnPのセキュリティ上の利点を放棄しても問題がない場合は、制限の少ないYarnBerryアプローチに切り替えることもできます。

pnpm PnPは、Yarn Berryバリアントと同様に機能するため、そのより厳密な性質にも対処する必要があります。pnpm PnPブランチpackage.jsonでわかるように、不足している依存関係をで指定する必要があります。

// package.json
{
  "name": "package-manager-playground",
  "version": "1.0.0",
  "packageManager": "pnpm@6.24.4",
  "pnpm": {
    "packageExtensions": {
      "styled-components": {
        "dependencies": {
          "react-is": "*"
        }
      },
      "autoprefixer": {
        "dependencies": {
          "postcss": "*"
        }
      }
    }
  },
  // ...
}

改善されたバージョン管理

複数のプロジェクトで作業するには、異なるバージョンのノードまたはパッケージマネージャーが必要になる場合があります。たとえば、私のReactNativeプロジェクトはYarnClassicを使用していますが、私のReactプロジェクトでは、より新しいバージョンのYarnBerryを使用したいと思います。

パッケージマネージャーは、バージョンを簡単に切り替えることができるようにする必要があります。また、パッケージマネージャーの特定のバージョンを(理想的には自動的に)適用できるメカニズムを導入する必要があります。これにより、異なるバージョンのパッケージマネージャーを使用することによって発生するバグが減少します。すぐにわかるように、Yarn Berryは現在、特定のバージョンに自動的に切り替える機能を提供する唯一のパッケージマネージャーです。

npm

npmのバンドルバージョンに付属するノードバージョンを切り替える最も簡単な方法は、nvmを使用することです。次に、npm自体を最新バージョンに更新することもできます。下記は用例です。

    $ nvm use 17.40
    $ npm -v # 8.1.2
    $ nvm install-latest-npm
    $ npm -v # 8.3.2

pnpm

pnpmは、ノードのバージョンを管理するための独自のツールである、最近追加されたpnpm envコマンドを提供します。これは、 Voltaや前述のnvmなどのツールの代替として機能します。npmまたはCorepackを使用して、ノードのバージョンを切り替えてから、特定のpnpmバージョンをインストールできます。Corepackを活用する例を次に示します。

$ pnpm env use --global lts
$ node -v # 16.13.2
$ pnpm -v # 6.24.2
$ corepack prepare pnpm@6.25.1 --activate
$ pnpm -v # 6.25.1

ヤーンベリー

特にプロのチーム向けの強力なYarnBerry機能は、特定のYarnBerryバージョンをプロジェクトにバンドルすることです。プロジェクトのルートで実行すると、コマンドはダウンロードされたバージョンと更新をyarn set version追加して、プロパティを使用して現在のリリースを設定します。.yarn/releases/.yarnrc.ymlyarnPath

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

この設定では、ローカルにインストールされyarnたバイナリは、にあるバイナリバージョンに実行を延期しますyarnPath。この構成をフォルダーとともにコミットすると、すべてのチームメートが同じバージョンのバイナリ.yarn/releasesを自動的に使用します。yarnこれにより、すべてのシステムで決定論的な依存関係のインストールが実行され、「自分のマシンで実行」の問題が発生しなくなります。

次のデモは、Gitからコードをチェックアウトした後、このバージョンが自動的に使用される方法を示しています。

yarn set version動作中

Corepackを使用する場合、このコマンドは、インストールされているyarnバイナリバージョンもファイルのpackageManagerプロパティに追加しpackage.jsonます。

packageManagerプロパティがファイルに追加されますpackage.json

これを構成の上に追加の「レイヤー」として使用してyarnPath、他の開発者が適切なパッケージマネージャーを使用できるようにすることができます。

別のパッケージマネージャーバージョンでトリガーされるCorepack使用エラー

Corepackはまだ新しいテクノロジーであり、すべての開発者はそれを使用することを選択する必要があります。したがって、すべての開発者が同じバージョンの同じパッケージマネージャーを使用することを確実に保証することはできません。

全体として、Yarn Berry'syarn set versionは、チーム全体に正しいyarnバイナリバージョンを適用するための堅牢な方法です。このメカニズムは、他のパッケージマネージャーのメカニズムよりも優れています。

高度なCI/CDインストール戦略

このセクションでは、CI/CDコンテキストで特に役立つインストールワークフローの追加機能に焦点を当てます。多くの開発プロジェクトでは、キャッシング戦略など、パイプライン実行の処理時間を短縮するための効率的な戦略が必要です。

npm

npm ciはと同様のコマンドですnpm installが、package-lock.jsonファイルが存在する必要があります。それはあなたを捨てて、node_modulesそれを最初から作り直すことによって機能します。

ci「継続的インテグレーション」の略で、CI/CD環境で使用することを目的としています。を実行する$ npm ciと、既存のフォルダはpackage-lock.json更新されませんが、node_modulesフォルダが削除されて再作成されます。とは対照的にnpm install、このアプローチは通常、速度の向上とより信頼性の高いパイプライン実行につながります。これは、で定義されたまったく同じ依存関係バージョンpackage-lock.jsonが開発者によってバージョン管理にプッシュされるためです。

さらに、npmはパッケージをローカルキャッシュにインストールして、再インストールの速度を上げます。これにより、オフラインパッケージの解決$ npm i --prefer-offlineにより、オフラインインストールが可能になります。たとえば、インターネット接続がないか不安定な場合などのコマンドを使用します。キャッシュをクリーンアップする場合は、を使用できます$ npm cache clean

ヤーンベリー

CI /CDコンテキストに依存関係をインストールするためのYarnBerryに対応するものはありませんが、。を使用して同様のことnpm ci行うことができます。yarn install --frozen-lockfile

Yarn Berryには、高度なオフラインキャッシュ機能があります。すべてのパッケージを単一のzipファイルとして.yarn/cache/フォルダにキャッシュします。cacheFolderデフォルトのキャッシュフォルダの場所は、プロパティで変更できます。

# .yarnrc.yml
cacheFolder: "./berry-cache"

次のコマンドを使用してキャッシュをクリーンアップできます。

# manual clean is optional
$ yarn cache clean
# global mirror needs to be cleaned manually
$ yarn cache clean --mirror

デフォルトでは、YarnBerryはプロジェクトごとにキャッシュフォルダーを作成します。enableGlobalCacheキャッシュを複数のプロジェクトと共有する場合は、プロパティを使用する代わりにグローバルキャッシュを使用できます。これと同じ設定のすべてのプロジェクトは、グローバルキャッシュを共有します。

# .yarnrc.yml
enableGlobalCache: true

pnpm

インターネットに接続されていない場合、パッケージはストアからインストールされます。を使用して、ストアからすべてのパッケージを取得するようにpnpmに明示的に指示することもできます$ pnpm i --offline。1つ以上のパッケージがストアの一部でない場合、エラーが発生します。

のようなコマンドはありませんがnpm ci、そのメンテナによると、pnpmはCI/CDコンテキストでうまく機能します

プライベートレジストリへのアクセス

すべてのパッケージマネージャーは、パブリックnpmレジストリですぐに使用できます。共有ライブラリを使用する企業のコンテキストでは、パッケージを公開せずに再利用することをお勧めします。そこで、プライベートレジストリが登場します。

npm

.npmrc次の構成は、プロジェクトのルートフォルダーにあるファイルの一部です。プライベートGitLabレジストリにアクセスする方法を示します。

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/<project-id>/packages/npm/

機密データは.npmrc、プロジェクトの外部にあるファイルに入ります。

# ~/.npmrc
//gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

pnpm

pnpmはnpmと同じ構成メカニズムを使用するため、構成を.npmrcファイルに保存できます。プライベートレジストリの設定は、npmの場合と同じように機能します。

ヤーンベリー

プライベートレジストリの設定はnpmに似ていますが、設定がYAMLファイルに保存されるため、構文が異なります。

# .yarnrc.yml
npmScopes:
  doppelmutzi:
    npmRegistryServer: 'https://gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/'

繰り返しますが、認証トークンはプロジェクトの外部に保存する必要があります。

# ~/.yarnrc.yml
npmRegistries:
  //gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

ワークスペースでのmonorepoサポートの追加

monorepoは、複数のプロジェクトを格納するGitリポジトリです。Googleは、かなり長い間、ほとんどのプロジェクトをモノレポで管理してきました。いくつかの利点が含まれます:

  • 大規模なリファクタリング
  • コードの再利用
  • 簡素化された依存関係管理

最新のパッケージマネージャーは、ワークスペースと呼ばれる機能を通じてモノリポジトリをサポートしています。このようなプロジェクトでは、すべてのワークスペースがサブプロジェクトを構成package.jsonし、独自の依存関係ツリーを定義するを含みます。各実装の背後にある概念は、すべての代表者にとって非常に似ています。CLIは、monorepoの依存関係管理を簡素化し、パッケージマネージャーは、ワークスペース間の共有依存関係を処理して、ファイルシステムストレージの効率を向上させることもできます。

ただし、詳細には違いがあるため、すべてのパッケージマネージャーのワークスペース機能を見ていきます。

npmワークスペース

npmは、 2020年10月にリリースされたv7にワークスペース機能を追加しました。ワークスペースプロジェクトを設定するには、数ステップと、ワークスペースの場所をnpmに指示するワークスペースpackage.jsonプロパティを含むルートフォルダーにが必要です。

// root package.json  
// ...
"workspaces": [
  "workspaces/a",
  "workspaces/b",
  "packages/*"
],
// ...

この例は、すべてのパッケージ(workspaces/aworkspaces/b)を明示的にリストするか、glob(packages/*)を使用できることを示しています。すべてのパッケージまたはワークスペースには、それぞれ独自のが必要package.jsonです。

これらの手順を自動化することもできます。ルートフォルダ内で、次のコマンドを実行して、必要な構成とともにワークスペースを作成します。

$ npm init -w ./packages/a-workspace

これにより、フォルダa-workspace内にpackagesフォルダが作成されます。さらに、ルートフォルダworkspaces内のプロパティpackage.jsonは、を含むように作成または更新されますa-workspace

ルートフォルダで実行するnpm iと、すべてのパッケージのすべての依存関係がインストールされます。これは、 installを実行した後のnpmデモブランチのフォルダー構造です。この例では、packagesフォルダーに3つのワークスペースがあります。このsrcフォルダーは、ルートでワークスペースを参照することでワークスペースを使用するReactアプリのソースを保持しますpackage.json

.
├── node_modules/
│   ├── @doppelmutzi/
│   │   └── eslint-config/ # sym-link to packages/eslint-config
│   │   └── hooks/ # sym-link to packages/hooks
│   │   └── server/ # sym-link to packages/server
│   ├── # other (shared) dependencies
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── src/
├── package-lock.json
└── package.json

上記のように、npmはすべての依存関係をフラットnode_modulesフォルダーに引き上げます。ワークスペースプロジェクトでは、このnode_modulesフォルダーはルートフォルダーに配置されます。

ただし、この例では、すべてのワークスペース(、、@doppelmutzi/eslint-config)がソースフォルダー()へのシンボリックリンクとして格納されています。@doppelmutzi/hooks@doppelmutzi/servernode_modules/@doppelmutzi/packages/

共有サードパーティライブラリはどうなりますか?それを考慮して、同じReact依存関係(17.0.2)package.jsonを指定しましょう。hooks/package.json結果は次のようになります。

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── package-lock.json
└── package.json

パッケージに追加react@17.0.1するとどうなりますか?server

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/
│   │   │   └── react/ # 17.0.1
│   │   └── package.json
├── package-lock.json
└── package.json

これは、さまざまな依存関係バージョンがどのように保存されるかを示しています。package-lock.jsonルートフォルダにはまだ1つのファイルしかありません。

npm v7では、多くのCLIコマンドで使用できるフラグ--workspaces(エイリアス-ws)と--workspace(エイリアス)も導入されました。-wいくつかの例を見てみましょう。

// package.json of root folder
"scripts": {
  // ...
  "start-server": "npm run serve -w @doppelmutzi/server",
  "publish-eslint-config": "npm publish --workspace @doppelmutzi/eslint-config",
  "lint-packages": "npm run lint -ws --if-present",
  "lint-packages:parallel": "npm run lint -w @doppelmutzi/hooks & npm run lint -w @doppelmutzi/server"
}

スクリプトは、ワークスペースのstart-serverルートフォルダーからパッケージ内でスクリプトを実行する方法を示しています。

npm run <script> -w <package-name>

package-namenameパッケージのpackage.jsonファイルのプロパティを参照します。このスクリプトpublish-eslint-configは、パッケージのファイルで明示的に定義されていない別のパッケージでnpmコマンドpackage.json(つまり、組み込みコマンド)を実行する方法を示しています。lint-packagesすべてのパッケージでスクリプトを実行する方法の例です。パッケージでスクリプト--is-presentが指定されていない場合にエラーを防ぐフラグに注意してください。lint

-wsYarn Berryとは対照的に、npmはフラグを使用した並列スクリプト実行をサポートしていません。lint-packages:parallelは、すべてのパッケージを指定することでこれを実現するための回避策を示しています。

-wフラグが付いたパッケージまたはフラグが付いたすべてのパッケージの依存関係をインストールすることもできます-ws

$ npm i http-server -w @doppelmutzi/server
$ npm i ntl -ws

monoreposの主な利点の1つは、共有ライブラリを使用することです。例として、Reactデモアプリは、で依存関係を指定することにより、すべてのワークスペースを使用しますpackage.json

// package.json
"dependencies": {
    "@doppelmutzi/eslint-config": "file:./packages/eslint-config",
    "@doppelmutzi/hooks": "file:./packages/hooks",
    "@doppelmutzi/server": "file:./packages/server",
    // ...
}

ヤーンベリーワークスペース

Yarn Berryワークスペースプロジェクトは、で初期化できますyarn init -wpackagesフォルダ、、、.gitignoreおよびを作成しますpackage.json。には、作成されたフォルダーpackage.jsonを指すワークスペース構成が含まれています。packages例として、mkdir yarn-demo; cd yarn-demo; yarn init -w;以下package.jsonが生成されます。

{
  "name": "yarn-demo",
  "packageManager": "yarn@3.2.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

このルートレベルpackage.jsonはプライベートである必要がありworkspaces、ワークスペースが配置されている場所を指定する配列を持っている必要があります。グロブ(例packages/*)または明示的(例)を使用してワークスペースを指定できますpackages/hooks

デモプロジェクトブランチyarnのルートフォルダでコマンドを実行した後の典型的なプロジェクト構造を見てみましょう。すべてのワークスペースはフォルダー内にあり、を格納します。packagespackage.json

.
├── .yarn/
│   ├── cache/
│   ├── plugins/
│   ├── releases/
│   ├── sdk/
│   └── unplugged/
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

興味深い点はyarn.lock、ルートレベルにファイルが1つしかないことです。さらに、ワークスペースの依存関係を含むすべての依存関係は、ルートレベルにある1つの.pnp.cjsファイルと1つのフォルダーに保存されます。.yarn/cache/

package.jsonワークスペースは、特別な要件のないを含むフォルダーです。次に説明するように、ワークスペースワークフローを改善するためのプラグインはに保存され.yarn/plugins/ます。

Yarn Berryはyarn workspace、ワークスペースのコンテキストでコマンドを実行するためのCLIコマンドを提供します。例として、ルートレベルから、開発依存関係をフックワークスペースに追加できます。

$ yarn workspace @doppelmutzi/hooks add -D @babel/runtime

workspace-toolsプラグインをインストールした後、複数のワークスペースでスクリプトを実行できるyarn workspace foreachコマンドを利用できます。

$ yarn plugin import workspace-tools
$ yarn workspaces foreach -p run lint

上記のforeachコマンドは、lintこの名前のスクリプトを使用して、すべてのワークスペースでスクリプトを実行します。の-p略であるフラグは、--parallelすべてのスクリプトを並行して実行します。

yarn runこのコマンドの便利な機能は、:ワークスペースプロジェクトのすべてのフォルダーからコロン()を含むスクリプトを実行できることです。パッケージ名を出力するroot:name、ルートに名前が含まれるスクリプトについて考えてみます。package.json

// root package.json
{
  // ...
  "scripts": {
    "root:name": "cat package.json | grep name"
  }
} 

どのフォルダyarn root:nameを実行しても、ルートフォルダと同じ名前でスクリプトを実行します。この機能は、いくつかの「グローバル」スクリプトを定義するために使用できます。

ワークスペースの1つからのリモートレジストリからパッケージが解決されないようにする場合は、ワークスペース解決プロトコルを使用する必要があります。package.jsondev依存関係または依存関係ファイルのプロパティ内でsemver値を使用する代わりに、以下を使用する必要があります。

"dependencies": {
    "@doppelmutzi/eslint-config": "workspace:*"
}

これにより、Yarn Berryは、フォルダー内@doppelmutzi/eslint-configにあるローカルワークスペースからパッケージを解決する必要があることを通知します。packagesYarn Berryは、すべてのpackage.jsonファイルをスキャンnameして、値が。のプロパティを探します@doppelmutzi/eslint-config

Yarn Berryは、Gitプロトコルを介した任意のプロジェクトからのワークスペースのクローン作成もサポートしています。

"dependencies": {
    "@doppelmutzi/eslint-config": "git@github.com:doppelmutzi/companion-project-mono-repo-2022.git#workspace=@doppelmutzi/eslint-config"
}    

この例では、@doppelmutzi/eslint-configYarnBerryワークスペースプロジェクトを構成する指定されたGitリポジトリからワークスペースを直接取得します。

制約は、満たす必要のあるワークスペースルールを作成するための低レベルのメカニズムです。ESLintforのようなものですpackage.json。たとえば、すべてのワークスペースのにライセンスフィールドを含める必要がありますpackage.json

JavaScript開発者にとって、これらの制約を論理プログラミング言語Prologで記述しているため、これらの制約を定義することは珍しいかもしれません。constraints.proプロジェクトのルートフォルダにファイルを提供する必要があります。

% Ensure all workspaces are using packageManager field with version 3.2.0
gen_enforced_field(WorkspaceCwd, 'packageManager', 'yarn@3.2.0').

簡単な例では、すべてのワークスペースに、packageManagerパッケージマネージャーとしてYarnBerryv3.2.0を適用するフィールドがあることを確認します。$ yarn constraintsCI / CDワークフローの一部として、制約が満たされていない場合にパイプラインを実行および中断できます。

pnpmワークスペース

pnpmは最初からワークスペースのサポートを提供してきました。pnpm-workspace.yamlこの機能を使用するには、プロジェクトのルートフォルダに必須ファイルが必要です。

# pnpm-workspace.yaml
packages:
  - 'packages/**'

この設定例は、すべてのワークスペースがフォルダー内にあることをpnpmに通知しpackagesます。ルートフォルダで実行pnpm iすると、ルートで定義された依存関係と、ワークスペースのファイルpackage.jsonに指定されたすべての依存関係がインストールされます。package.jsonデモプロジェクトのpnpmGitブランチの次のフォルダー構造は、インストールプロセスの結果です。

.
├── node_modules/
│   ├── # dependencies defined in package.json
├── packages/
│   ├── eslint-config/
│   │   └── package.json # no dependencies defined
│   ├── hooks/
│   │   ├── node_modules/ # dependencies defined in hooks/package.json
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/ # dependencies defined in server/package.json
│   │   └── package.json
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

ご覧のとおり、ロックファイル(pnpm-lock.yaml)は1つだけですが、複数のnode_modulesフォルダがあります。npmワークスペースとは対照的に、pnpmは、node_modulesワークスペースのに依存関係が指定されている場合は常に、すべてのワークスペースにフォルダーを作成しますpackage.json

前のセクションで説明したように、npmワークスペースを使用したReact依存関係と状況を比較するには、この依存関係が両方のファイルで指定されているためreact@17.0.2、ルートフォルダーとワークスペースにインストールされnode_modulesます。hookspackage.json

npmとは対照的に、node_modulesフォルダーはフラットではありません。上記のように、コンテンツアドレス可能なストレージアプローチにより、これらの依存関係は、中央ストアのハードドライブに物理的に1回だけインストールされます。

ルートpackage.jsonは、複数の有用なフラグが存在し、ワークスペースのコンテキストで使用できることを示しています。

{
  // ...  
  "start-server": "pnpm serve --filter @doppelmutzi/server",
  "publish-eslint-config": "pnpm publish -F @doppelmutzi/eslint*",
  "lint-packages": "pnpm lint -r --parallel",
}

フィルタフラグ--filterまたは)は-F、コマンドを1つ以上のワークスペースに制限します。このstart-serverスクリプトは、特定の1つのワークスペースでスクリプトを実行する方法を示しています(@doppelmutzi/server)。スクリプトで示されているように、パターン(*)を使用してワークスペースを一致させることもできます。publish-eslint-config

再帰フラグ--recursiveまたは)を使用-rすると、すべてのワークスペースでコマンドを再帰的に実行できます。このスクリプトは、すべてのワークスペースでスクリプトを実行するrunコマンドlint-packagesの例を示しています。lint

npmとは対照的に、pnpmはそのようなスクリプトを提供しないすべてのワークスペースを無視します。並列フラグを使用すると、スクリプトが同時に実行されます。

pnpmは、モノリポジトリの依存関係としてワークスペースを使用するYarn Berryと同様のワークスペースプロトコル( )をサポートしています。workspace:このプロトコルを使用すると、pnpmがリモートレジストリからローカルワークスペースの依存関係を解決できなくなります。ルートからの抜粋は、package.jsonこのプロトコルの使用方法を示しています。

// package.json
{
  // ...
  dependencies: {
    "@doppelmutzi/eslint-config": "workspace:1.0.2",
    "@doppelmutzi/hooks": "workspace:*",
    "@doppelmutzi/server": "workspace:./packages/server",
  // ...
  }
}

を使用workspace:すると、ローカルワークスペースを構成する依存関係をインストールすることがpnpmに通知されます。その中のバージョンは1.0.2であるため"@doppelmutzi/eslint-config": "workspace:1.0.2"、ローカルワークスペースをインストールします。**別のバージョンをインストールしようとすると、インストールプロセスは失敗します。@doppelmutzi/eslint-configpackage.json

ワークスペースのバージョンが一致しません

ほとんどの場合、ワークスペースプロジェクトに存在するワークスペースの現在の状態を使用することをお勧めします。workspace:*したがって、依存関係で示されているように使用できます@doppelmutzi/hooks@doppelmutzi/serverは、相対パスを使用してワークスペースを参照することもできることを示しています。と同じ効果がありworkspace:*ます。

Yarn Berryと同様に、リモートのモノリポジトリからワークスペースを参照することもできますpnpm add

ワークスペース関連のCLIコマンド

次の表は、ワークスペースのコンテキストでnpm、Yarn Berry、およびpnpmで使用できるさまざまなCLIコマンドの精選されたセットを比較しています。これは完全なリストではありませんが、チートシートを構成します。次の表は、ワークスペース関連の例を使用して、前回の記事のコマンドを完了したものです。

依存関係の管理

package.jsonこの表は、で指定されたすべての依存関係、またはコマンドで指定することによる複数の依存関係をインストールまたは更新するための依存関係管理コマンドについて説明しています。すべてのコマンドは、1つ以上のワークスペースのコンテキストで実行できます。すべてのコマンドは、ワークスペースプロジェクトのルートフォルダーから実行されます。

アクションnpmヤーンベリーpnpm
すべてのワークスペースのdepsをインストールします
  • npm install
  • エイリアス:i
  • yarn install
  • エイリアス:yarn
  • pnpm install
  • エイリアス:i
単一のワークスペースの部門をインストールする
  • npm i --workspace server
  • エイリアス:-w
  • pnpm i --filter server
  • エイリアス:-F
ルートレベルの依存関係を追加する
  • npm i eslint
  • yarn add eslint
  • pnpm i eslint
ワークスペースに依存関係を追加する
  • npm i -D react -w hooks
  • yarn workspace hooks add -D react
  • pnpm i -D -F hooks react
  • pnpm add -D -F hooks react
ワークスペースの依存関係をワークスペースに追加する
  • 該当なし
  • yarn workspace app add hooks@'workspace:*'
  • pnpm i -F app hooks@'workspace:*'
ワークスペースのすべての依存関係を更新します
  • npm update -w hooks
  • yarn workspace hooks up
  • pnpm up -F hooks
  • pnpm up --latest -F hooks
  • エイリアス:-L
ワークスペースの依存関係を更新する
  • npm update react -w hooks
  • yarn workspace hooks up react
  • pnpm up -F hooks react
  • pnpm up -L -F hooks react
ワークスペースから依存関係を削除する
  • npm uninstall react -w hooks
  • yarn workspace hooks remove react
  • pnpm remove --filter hooks react

スクリプトの実行

この表は、1つまたは複数のワークスペースでスクリプトを実行するためのコマンドを示しています。

アクションnpmヤーンベリーpnpm
ワークスペースでスクリプトを実行する
  • npm run build -w hooks
  • yarn workspace hooks build
  • pnpm run build -F hooks
  • pnpm build -F hooks
複数のワークスペースでスクリプトを実行する
  • npm run lint -w server -w hooks
  • 該当なし
  • 回避策:yarn workspace hooks lint && yarn workspace server lint
  • pnpm -F server -F hooks lint
すべてのワークスペースでスクリプトを順番に実行する
  • npm run lint --workspaces
  • エイリアス:-ws
  • pnpm run --recursive lint
  • エイリアス:-r
可能な場合は、すべてのワークスペースでスクリプトを順番に実行します
  • npm run lint -ws --if-present
  • yarn workspaces foreach run lint
  • pnpm run -r lint
すべてのワークスペースでスクリプトを並行して実行する
  • 該当なし
  • 回避策:npm run lint -w p1 & npm run lint -w p2
  • yarn workspaces foreach --parallel run lint
  • エイリアス:-p
  • pnpm run -r lint --parallel

その他

この表では、便利な組み込みコマンドについて説明します。公式コマンドがない場合は、多くの場合、npmパッケージまたはYarn Berryプラグインを介して、サードパーティのコマンドを使用して同様のことを実行できます。

 npmヤーンベリーpnpm
initワークスペースプロジェクト
  • npm init -w ./packages/server(指定されたワークスペースとともに構成を作成します)
  • yarn init --workspace
  • エイリアス:

-w

  • 該当なし
initワークスペース
  • npm init -w ./packages/server
  • 該当なし
  • 該当なし
ワークスペースを一覧表示します
  • 該当なし
  • yarn workspaces list
  • yarn workspaces list --json
  • 該当なし
ワークスペースの制約を確認する
  • 該当なし
  • 該当なし

これらすべてのイノベーションが将来に何を意味するか

フロントエンドプロジェクトはますます複雑になっています。それらを構築するには、ますます多くの依存関係が必要になります。特にモノリポジトリの場合、インストールプロセスは時間がかかり、部分的にエラーが発生しやすくなります。パッケージマネージャーの現状は多くの問題に取り組んでいますが、まだ改善の余地があります。

たとえば、 tnpmはAlibabaのエンタープライズサービスであり、クローズドエンタープライズ環境でのパッケージマネージャーの水準を引き上げたようです。それらの依存関係解決戦略は、上記のパッケージマネージャーと比較してHTTPリクエストを減らします。

さらに、マルチレベルのキャッシュ戦略に関連して、tnpmの依存関係グラフがサーバー上に生成されます。現在、これはnpm、pnpm、Yarnなどの非エンタープライズソリューションでは達成が困難ですが、それは確かに可能なことの基準を設定します。

tnpmは、パッケージマネージャースペースにまだ改善の余地があることを示しています。出典:Dev.toのtnpm

パブリックパッケージマネージャーは、パフォーマンスを改善し、既知の問題点(たとえば、ここで説明した非効率的な依存関係ストレージ)に対処する方法を独自に調査しています。npmでさえ、pnpmに触発されたシンボリックリンクを作成する「分離モード」に取り組んでいます。node_modulesこの変更により、npmは現在の長期的な解決戦略を「ホイストモード」と呼んでいます。

pnpmはまた、 FUSEを使用して調査を行って、Yarn BerryのPnPモードに代わるものを提供しています。これは、有望と思われます(また、現時点でpnpm PnPに関する情報がほとんど見つからない理由も説明しています)。

最終的には、パッケージマネージャーが互いに刺激し合い、知識を共有するという点で、パッケージマネージャーがどれほどうまく連携しているかを高く評価することはできません。これは、tnpmに関するこの記事のコメントセクションなど、多くの場所で見ることができます。

結論

将来的には複数のパッケージマネージャーが存在するようです。彼らは、さまざまなユーザーが直面する無数の問題により適切に対処するために、同等の機能セットと概念を持ちたくない場合があります。

一方では、これは、プロジェクトに最適なワークフローを選択するためのオプションがあることを意味するため、素晴らしいことです。また、同じような概念に基づいているため、さまざまなプロジェクトのチーム設定でさまざまなパッケージマネージャーを使用することを妨げるものは何もありません。

一方、ライブラリベンダーがこれらすべてのパッケージマネージャーとそれぞれの違いをサポートすることはますます困難になっています。例として、私の現在のプロジェクトでは、セットツールがロックファイル形式をサポートしていないため、YarnBerryを使用できません。これらの違いのサポートが克服されるかどうかはまだ分からない。

ソース:https ://blog.logrocket.com/exploring-workspaces-other-advanced-package-manager-features/

 #packaging  #workspace #pnpm #npm 

ワークスペースおよびその他の高度なパッケージマネージャー機能の調査

Cómo Yarn Y Pnpm Han Centrado Sus Esfuerzos Más De Cerca

Este artículo tiene como objetivo dejarle una impresión de hacia dónde se dirigen los administradores de paquetes en el futuro para satisfacer las necesidades de los desarrolladores, por ejemplo, permitiéndoles administrar grandes proyectos monorepo con un rendimiento adecuado y un buen DX.

Escribí en un artículo anterior sobre el tema de las estrategias de resolución de dependencias entre npm, Yarn y pnpm. Si bien el enfoque en el artículo anterior fue comparar conceptos y estructuras centrales, este artículo cubrirá las características avanzadas de los administradores de paquetes modernos, incluidos los monorepos, a través de espacios de trabajo.

El objetivo de este artículo es transmitir cómo Yarn y pnpm han centrado sus esfuerzos más de cerca en permitir a los desarrolladores crear monorepos a través de espacios de trabajo y proporcionar enfoques más avanzados para mejorar la seguridad y el rendimiento. 

Proyectos complementarios

Este artículo cubre varias características del administrador de paquetes. Por lo tanto, creé dos proyectos complementarios en GitHub para brindar ejemplos:

  1. Un proyecto monorepo para demostrar las características del espacio de trabajo
  2. Un proyecto separado para demostrar diferentes estrategias de resolución de dependencia

Estrategias alternativas de resolución de dependencia

Cuando se usa la configuración predeterminada, pnpm y Yarn Berry no usan los mismos algoritmos de resolución de dependencias que npm y Yarn Classic, lo que implica aplanar node_modulescarpetas. Estos administradores de paquetes modernos intentan separarse de los enfoques tradicionales para procesar y almacenar dependencias.

La razón de esto es que se requieren enfoques de resolución innovadores para hacer frente a los requisitos de los proyectos de software modernos, que utilizan cada vez más grandes cantidades de dependencias. Las estrategias tradicionales han llegado a sus límites en términos de rendimiento y eficiencia del espacio en disco.

El problema con el enfoque tradicionalnode_modules

La estrategia tradicional de resolución de dependencias para aplanar node_modulescarpetas genera varios problemas diferentes :

  • Los módulos pueden (accidentalmente) acceder a paquetes de los que no dependen, lo que puede generar errores
  • El algoritmo de aplanamiento es un proceso de E/S que requiere mucho tiempo.

El problema raíz de este diseño plano node_moduleses un concepto llamado elevación , que fue introducido por npm en v3 . Este mismo algoritmo de resolución de dependencia también fue utilizado por Yarn Classic al principio.

En pocas palabras, la elevación aplana la node_modulescarpeta de tal manera que todas las dependencias, incluso las dependencias de dependencias, terminan en el nivel raíz de node_modules. La razón para subir todo a un nivel de carpeta es reducir la redundancia que provoca el anidamiento. La siguiente imagen muestra cómo funciona esto:

 

Las diferencias entre los algoritmos node_module de npm v2 y npm v3

La elevación puede provocar errores graves y difíciles de detectar, especialmente en proyectos grandes. Jonathan Creamer brinda una visión detallada de lo que puede salir mal en un proyecto monorepo donde el algoritmo de elevación falla y provoca errores de producción. En tales situaciones, el levantamiento puede conducir a dependencias fantasmas y doppelgangers .

El enfoque Plug'n'Play de Yarn Berry

Yarn Berry trató de deshacerse por node_modulescompleto, utilizando un enfoque Plug'n'Play . Puede leer acerca de la motivación de Yarn Berry para deshacerse de node_modules, pero las razones son similares a las de pnpm.

PnP es una estrategia de instalación nueva e innovadora para Node, desarrollada en contraste con el requireflujo de trabajo establecido (y único) Common, js que aborda muchas de sus ineficiencias. A diferencia de la forma tradicional, Yarn Berry invierte la responsabilidad en quién encuentra los paquetes.

Anteriormente, Node tenía que encontrar sus paquetes dentro de las node_modulescarpetas. Yarn Berry en modo PnP ya tiene toda la información que necesita a mano y, en cambio, le dice a Node dónde encontrarla. Esto reduce drásticamente el tiempo de instalación del paquete.

Yarn Berry logra esto generando un archivo en lugar de una carpeta .pnp.cjsanidada . node_modulesContiene tablas de búsqueda para informar a Node sobre las ubicaciones de dependencia. Como uno de los beneficios, Yarn Berry puede asegurarse de compartir solo las ubicaciones de los paquetes que ha definido en uno de sus package.jsonarchivos, lo que mejora la seguridad y reduce los errores: ya no tiene que preocuparse por los duplicados, las dependencias fantasmas o otros tipos de acceso ilegal.

Sin embargo, los principales beneficios son velocidades de instalación más rápidas; solo estamos procesando un archivo, nuestro .pnp.cjsarchivo, por lo que tenemos menos operaciones de E/S. Los tiempos de inicio también se pueden mejorar porque el algoritmo de resolución de Node tiene que hacer menos trabajo.

Pero si no hay ninguna node_modulescarpeta, ¿dónde se almacenan los paquetes? Cada paquete se almacena como un archivo zip dentro de una .yarn/cache/carpeta. Esto funciona porque Yarn Berry mono parchea la API del sistema de archivos de Node de tal manera que las solicitudes de dependencias internas node_modulesdeben resolverse a partir del contenido de los archivos comprimidos dentro de la memoria caché. Estos archivos zip ocupan menos espacio en disco que la node_modulescarpeta.

PnP es el modo predeterminado de Yarn Berry, pero también puede habilitarlo explícitamente dentro de .yarnrc.yml.

# .yarnrc.yml
# alternatively, remove the next two lines, PnP strict is the default
nodeLinker: "pnp"
pnpMode: "strict"

La estructura típica de un proyecto PnP se parece a la siguiente. No hay node_modulescarpetas; las dependencias se almacenan en archivos zip en formato .yarn/cache/.

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

Problemas de depuración con dependencias en Yarn Berry PnP

Para depurar problemas con las dependencias, necesita compatibilidad con herramientas adicionales (p. ej., la extensión VS Code ), ya que debe "mirar dentro" de los archivos zip. Al momento de escribir, debe realizar pasos manuales agregando compatibilidad con SDK del editor porque dicha funcionalidad no está incorporada. El siguiente comando agrega soporte para VS Code :

$ yarn dlx @yarnpkg/sdks vscode

La CLI del SDK analiza su raíz package.jsonen busca de tecnologías compatibles y genera archivos de configuración que se almacenan en formato .yarn/sdk/.

Cambios de archivo de la CLI del SDK

En el caso de nuestro proyecto de demostración, detecta ESLint y Prettier . Consulte la rama de Git yarn-berry-pnppara ver un ejemplo de compatibilidad con PnP y SDK.

Estrategia de instalación cero de Yarn Berry

Lo bueno de PnP es que puede poner el .pnp.cjsarchivo y la .yarn/cache/carpeta bajo control de versión debido a sus tamaños de archivo justificables. Lo que obtienes de esto es una estrategia de instalación cero . Si su compañero de equipo extrae su código de Git, lo que puede llevar un poco más de tiempo usando esta estrategia, todos los paquetes y tablas de búsqueda estarán disponibles y no se requiere ningún paso de instalación antes de iniciar la aplicación. Eche un vistazo a un breve video de demostración que muestra la instalación cero en acción.

Puede ver cómo el .gitignorearchivo se parece a la rama de instalación cero de Yarn Berry PnP . Si agrega, actualiza o elimina dependencias, debe ejecutar yarn install, por supuesto, para actualizar yarn.lock, .pnp.cjsy las .yarn/cache/carpetas.

Optar por no participar en PnP: modo suelto

PnP es restrictivo y es posible que no funcione con algunos paquetes incompatibles (p. ej., React Native). Además, la migración a PnP podría no ser un camino fácil; por lo tanto, Yarn Berry proporciona un modo suelto . Puede activarlo .yarnrc.ymlconfigurando la nodeLinkerpropiedad en consecuencia.

# .yarnrc.yml
nodeLinker: "pnp"
pnpMode: "loose"

El modo suelto es un compromiso entre el modo estricto PnP y el node_modulesmecanismo tradicional de resolución de dependencias. La diferencia es que Yarn Berry solo advierte sobre el acceso de dependencia inseguro, en lugar de abortar con errores.

Debajo del capó, Yarn Berry realiza el algoritmo de elevación tradicional y lo usa como respaldo para cada dependencia no especificada. Esto todavía se considera inseguro según los estándares de Yarn Berry, pero puede ahorrar algo de tiempo: podrá analizar mejor las advertencias que recibe, solucionar sus problemas de raíz y volver a PnP estricto nuevamente rápidamente, si es necesario.

Es posible que desee cambiar a Yarn Berry porque Yarn Classic se considera heredado y, aunque se beneficia de algunas mejoras, se mantiene en el node_modulesmodo de instalación tradicional con node-modules nodeLinker.

# .yarnrc.yml
nodeLinker: "node-modules"

Con esto, la buena vieja node_modulescarpeta se vuelve a generar.

El equipo de Yarn Berry también se inspiró en la estrategia de almacenamiento direccionable por contenido de pnpm, que analizaremos a continuación, y agregó un modo con el mismo nombre. Es similar a su arquetipo y tiene como objetivo almacenar dependencias solo una vez, en su disco duro.

# .yarnrc.yml
nodeLinker: "pnpm"

Siéntase libre de probar los diferentes modos revisando las ramas de Git correspondientes de mi proyecto de demostración:

estrategia optimizada de pnpmnode_modules

pnpm almacena las dependencias en una node_modulescarpeta anidada, como npm, pero proporciona un mejor rendimiento y eficiencia del espacio en disco debido a su implementación de almacenamiento direccionable por contenido . Puede leer más sobre esto en mi artículo anterior sobre administradores de paquetes.

La estrategia Plug'n'Play de pnpm

Desde finales de 2020, pnpm v5.9 también es compatible con PnP e incluso se refiere a él como Plug'n'Play de Yarn . La documentación sobre esta función es escasa; El desarrollador principal de pnpm hace referencia a los documentos de Yarn Berry .

La rama pnpm PnP muestra cómo usar este modo. Tienes que activar el modo PnP en .npmrc.

# .npmrc
node-linker=pnp
symlink=false

Después de ejecutar pnpm i, la estructura del proyecto se ve así.

.
├── node_modules/
│   ├── .bin/
│   └── .pnpm/
├── .npmrc
├── .pnp.cjs
├── package.json
└── pnpm-lock.yaml

Consecuencias de los enfoques sin elevación

pnpm y Yarn Berry consideran que izar es una mala práctica. Como ya se mencionó, muchos proyectos en el ecosistema de JavaScript han basado sus implementaciones de elevación en la utilizada por npm y versiones anteriores de Yarn. Esta sección destaca algunos problemas que vienen con el enfoque sin elevación.

Con la rama de demostración de pnpm , tuve un problema al ejecutar un binario, ntl. No funcionaba debido al diseño no plano de pnpm node_modules, lo que me llevó a una discusión con el desarrollador principal de pnpm sobre un problema similar y me señaló la solución para hoistntl .

# .npmrc
hoist-pattern[]=*ntl*

Con el enfoque PnP de Yarn Berry, lo más probable es que te encuentres con situaciones similares. Durante el desarrollo de la rama de demostración de PnP , recibí este error al iniciar.

Error estricto de PnP al iniciar

En el seguimiento de la pila, descubrí que no react-isse encontró un paquete llamado en tiempo de ejecución. El mensaje de error en el lado izquierdo de la captura de pantalla anterior indica que esto tiene que ver con el styled-componentspaquete que especifiqué en mi archivo package.json. Parece que styled-componentsno enumera todas sus dependencias en su package.json archivo .

Hay una solución típica para tal problema PnP: la packageExtensionspropiedad . Actualizar .yarnrc.ymly ejecutar un adicional yarn installpara instalar la dependencia faltante soluciona el problema:

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

Como se describió anteriormente, también puede cambiar a un enfoque de Yarn Berry menos restrictivo si está bien renunciar a los beneficios de seguridad de PnP en su proyecto.

pnpm PnP funciona de manera similar a la variante Yarn Berry y, como tal, también debe lidiar con su naturaleza más estricta. Debe especificar las dependencias que faltan en el package.json, como puede ver en la rama pnpm PnP .

// package.json
{
  "name": "package-manager-playground",
  "version": "1.0.0",
  "packageManager": "pnpm@6.24.4",
  "pnpm": {
    "packageExtensions": {
      "styled-components": {
        "dependencies": {
          "react-is": "*"
        }
      },
      "autoprefixer": {
        "dependencies": {
          "postcss": "*"
        }
      }
    }
  },
  // ...
}

Gestión de versiones mejorada

Trabajar en múltiples proyectos puede requerir diferentes versiones de Node o su administrador de paquetes. Por ejemplo, mi proyecto React Native usa Yarn Classic, pero para mi proyecto React, quiero usar una versión más reciente de Yarn Berry.

Un administrador de paquetes debería facilitar el cambio entre versiones. También debe contar con mecanismos que le permitan aplicar ciertas versiones de un administrador de paquetes, idealmente de forma automática. Esto reduce los errores causados ​​por el uso de diferentes versiones del administrador de paquetes. Como verá en un minuto, Yarn Berry es actualmente el único administrador de paquetes que ofrece una función para cambiar automáticamente a una versión en particular.

sobre el nivel del mar

La forma más fácil de cambiar una versión de Node que viene con una versión integrada de npm es usar nvm . Luego, también puede actualizar npm a la versión más reciente. Aquí hay unos ejemplos.

    $ nvm use 17.40
    $ npm -v # 8.1.2
    $ nvm install-latest-npm
    $ npm -v # 8.3.2

pnpm

pnpm proporciona su propia herramienta para administrar las versiones de Node: el pnpm envcomando agregado recientemente . Sirve como alternativa a herramientas como Volta o el mencionado nvm. Puede cambiar las versiones de Node y luego instalar versiones particulares de pnpm, ya sea con la ayuda de npm o Corepack . Aquí hay un ejemplo que aprovecha Corepack:

$ pnpm env use --global lts
$ node -v # 16.13.2
$ pnpm -v # 6.24.2
$ corepack prepare pnpm@6.25.1 --activate
$ pnpm -v # 6.25.1

Baya de hilo

Una característica poderosa de Yarn Berry, especialmente para equipos profesionales, es incluir una versión particular de Yarn Berry con su proyecto. Cuando se ejecuta en la raíz de su proyecto, el comando yarn set versionagrega la versión descargada .yarn/releases/y se actualiza .yarnrc.ymlpara establecer la versión actual con la yarnPathpropiedad .

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

Con esta configuración, su binario instalado localmente yarndifiere la ejecución a la versión binaria ubicada en yarnPath. Si confirma esta configuración, junto con la .yarn/releasescarpeta, todos los compañeros de equipo usarán automáticamente la misma versión del yarnbinario. Esto lleva a que la instalación de dependencia determinista se ejecute en todos los sistemas, no más problemas de "ejecuciones en mi máquina".

La siguiente demostración muestra cómo esta versión se usa automáticamente después de verificar el código de Git.

yarn set versionen acción

Si usa Corepack, el comando también agrega la yarnversión binaria instalada a la packageManagerpropiedad en su package.jsonarchivo.

La packageManagerpropiedad se agrega a nuestro package.jsonarchivo.

Esto se puede usar como una "capa" adicional en la parte superior de la yarnPathconfiguración para asegurarse de que sus compañeros desarrolladores usen el administrador de paquetes correcto.

El error de uso de Corepack que se activa con una versión diferente del administrador de paquetes

Corepack sigue siendo una tecnología completamente nueva y todos los desarrolladores deben optar por usarla. Por lo tanto, no se puede garantizar de manera confiable que todos los desarrolladores usen el mismo administrador de paquetes con la misma versión.

En general, Yarn Berry's yarn set versiones un método sólido para aplicar la yarnversión binaria correcta en todo su equipo. Este mecanismo es superior a los mecanismos de otros administradores de paquetes.

Estrategias avanzadas de instalación de CI/CD

Esta sección se centra en las características adicionales del flujo de trabajo de instalación que son especialmente útiles en contextos de CI/CD. Muchos proyectos de desarrollo requieren estrategias eficientes para reducir el tiempo de procesamiento de las ejecuciones de canalización, como las estrategias de almacenamiento en caché.

sobre el nivel del mar

npm cies un comando similar a npm install, pero package-lock.jsondebe existir un archivo. Funciona tirando el tuyo node_modulesy recreándolo desde cero.

cisignifica "integración continua" y está destinado a ser utilizado en entornos CI/CD. Al ejecutar , no se actualizará $ npm ciuna preexistente , pero la carpeta se eliminará y se volverá a crear. En contraste con , este enfoque generalmente conduce a mejoras en la velocidad y ejecuciones de canalización más confiables porque un desarrollador envía al control de versiones exactamente las mismas versiones de dependencia definidas.package-lock.jsonnode_modulesnpm installpackage-lock.json

Además, npm instala paquetes en un caché local para aumentar la velocidad de reinstalación. Esto permite instalaciones fuera de línea debido a la resolución de paquetes fuera de línea , por ejemplo, usando un comando como $ npm i --prefer-offlinesi no tuviera conexión a Internet o si tuviera una conexión inestable. Si desea limpiar el caché, puede usar $ npm cache clean.

Baya de hilo

No existe una contrapartida de Yarn Berry npm cipara instalar dependencias en un contexto de CI/CD, pero puede hacer cosas similares con yarn install --frozen-lockfile.

Yarn Berry tiene una función avanzada de caché fuera de línea . Almacena en caché cada paquete como un único archivo zip en su .yarn/cache/carpeta. La ubicación de la carpeta de caché predeterminada se puede cambiar con la cacheFolderpropiedad .

# .yarnrc.yml
cacheFolder: "./berry-cache"

Puede limpiar el caché con los siguientes comandos.

# manual clean is optional
$ yarn cache clean
# global mirror needs to be cleaned manually
$ yarn cache clean --mirror

De forma predeterminada, Yarn Berry crea una carpeta de caché para cada proyecto. Si desea compartir el caché con varios proyectos, puede usar un caché global en su lugar usando la enableGlobalCachepropiedad . Cada proyecto con esta misma configuración comparte el caché global.

# .yarnrc.yml
enableGlobalCache: true

pnpm

Sin conexión a Internet, los paquetes se instalan desde la tienda. También puede decirle explícitamente a pnpm que recupere todos los paquetes de la tienda con $ pnpm i --offline. Si uno o más paquetes no son parte de la tienda, obtiene un error.

No hay un comando como npm ci, pero según sus mantenedores, pnpm funciona bien en un contexto de CI/CD .

Acceso a registros privados

Cada administrador de paquetes funciona de forma inmediata con el registro público de npm . En el contexto de una empresa con bibliotecas compartidas, lo más probable es que desee reutilizar paquetes sin publicarlos públicamente. Ahí es donde entran en juego los registros privados.

sobre el nivel del mar

La siguiente configuración es parte del .npmrcarchivo ubicado en la carpeta raíz del proyecto. Indica cómo acceder a un registro privado de GitLab .

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/<project-id>/packages/npm/

Los datos confidenciales van al .npmrcarchivo ubicado fuera del proyecto.

# ~/.npmrc
//gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

pnpm

pnpm usa el mismo mecanismo de configuración que npm , por lo que puede almacenar su configuración en un .npmrcarchivo. La configuración de un registro privado funciona de la misma manera que con npm.

Baya de hilo

La configuración de registros privados es similar a npm, pero la sintaxis difiere porque la configuración se almacena en un archivo YAML.

# .yarnrc.yml
npmScopes:
  doppelmutzi:
    npmRegistryServer: 'https://gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/'

Nuevamente, su token de autenticación debe almacenarse fuera de su proyecto.

# ~/.yarnrc.yml
npmRegistries:
  //gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

Agregar soporte monorepo con espacios de trabajo

Un monorepo es un repositorio de Git que alberga múltiples proyectos. Google gestiona la mayoría de sus proyectos en un monorepo desde hace bastante tiempo. Algunos beneficios incluyen:

  • Refactorización a gran escala
  • reutilización de código
  • Gestión de dependencia simplificada

Los administradores de paquetes modernos admiten monorepos a través de una característica llamada espacios de trabajo. En dichos proyectos, cada espacio de trabajo constituye un subproyecto y contiene un package.jsonque define su propio árbol de dependencia. Los conceptos detrás de cada implementación son bastante similares para todos los representantes: la CLI simplifica la administración de dependencias del monorepo, y los administradores de paquetes pueden incluso encargarse de las dependencias compartidas entre espacios de trabajo para mejorar la eficiencia del almacenamiento de su sistema de archivos.

Pero hay diferencias en los detalles y, por lo tanto, veremos la función de espacios de trabajo para cada administrador de paquetes.

espacios de trabajo sobre el nivel del mar

npm agregó una función de espacios de trabajo en v7, lanzada en octubre de 2020. La configuración de un proyecto de espacios de trabajo requiere solo unos pocos pasos y una package.jsonen su carpeta raíz que contiene una propiedad de espacios de trabajo que le dice a npm dónde encontrar sus espacios de trabajo.

// root package.json  
// ...
"workspaces": [
  "workspaces/a",
  "workspaces/b",
  "packages/*"
],
// ...

Este ejemplo muestra que puede enumerar explícitamente todos los paquetes ( workspaces/a, workspaces/b) o puede usar un glob ( packages/*). Cada paquete o espacio de trabajo, respectivamente, necesita su propio archivo package.json.

También puede automatizar estos pasos. Dentro de la carpeta raíz, simplemente ejecute el siguiente comando para crear un espacio de trabajo junto con la configuración requerida:

$ npm init -w ./packages/a-workspace

Esto crea la carpeta a-workspacedentro de la packagescarpeta. Además, se crea o actualiza una workspacespropiedad dentro de la carpeta raíz para que contenga archivos .package.jsona-workspace

Cuando se ejecuta npm ien la carpeta raíz, se instalan todas las dependencias de todos los paquetes. Esta es la estructura de carpetas de la rama de demostración de npm después de ejecutar install. En este ejemplo, hay tres espacios de trabajo ubicados en la packagescarpeta. La srccarpeta contiene la fuente de una aplicación React que usa los espacios de trabajo al hacer referencia a ellos en la raíz package.json.

.
├── node_modules/
│   ├── @doppelmutzi/
│   │   └── eslint-config/ # sym-link to packages/eslint-config
│   │   └── hooks/ # sym-link to packages/hooks
│   │   └── server/ # sym-link to packages/server
│   ├── # other (shared) dependencies
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── src/
├── package-lock.json
└── package.json

Como se describió anteriormente, npm eleva todas las dependencias a una node_modulescarpeta plana. En un proyecto de espacios de trabajo, esta node_modulescarpeta estaría ubicada en la carpeta raíz.

Pero en este ejemplo, todos los espacios de trabajo ( @doppelmutzi/eslint-config, @doppelmutzi/hooks, @doppelmutzi/server) se almacenan node_modules/@doppelmutzi/como enlaces simbólicos a las carpetas de origen ( packages/).

¿Qué sucede con las bibliotecas compartidas de terceros? Consideremos eso package.jsony hooks/package.jsonespecifiquemos la misma dependencia de React (17.0.2). El resultado se ve así:

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── package-lock.json
└── package.json

¿Qué pasa si añadimos react@17.0.1al serverpaquete?

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/
│   │   │   └── react/ # 17.0.1
│   │   └── package.json
├── package-lock.json
└── package.json

Esto demuestra cómo se almacenan las diferentes versiones de dependencia. Todavía hay un solo package-lock.jsonarchivo en la carpeta raíz.

npm v7 también introdujo los indicadores --workspaces(alias -ws) y --workspace(alias -w) que se pueden usar con muchos comandos CLI. Echemos un vistazo a algunos ejemplos.

// package.json of root folder
"scripts": {
  // ...
  "start-server": "npm run serve -w @doppelmutzi/server",
  "publish-eslint-config": "npm publish --workspace @doppelmutzi/eslint-config",
  "lint-packages": "npm run lint -ws --if-present",
  "lint-packages:parallel": "npm run lint -w @doppelmutzi/hooks & npm run lint -w @doppelmutzi/server"
}

El start-serverscript muestra cómo ejecutar un script dentro de un paquete desde la carpeta raíz de los espacios de trabajo:

npm run <script> -w <package-name>

package-namese refiere a la propiedad del archivo namedel paquete . package.jsonEl script publish-eslint-configdemuestra cómo ejecutar un comando npm en otro paquete que no está definido explícitamente en el package.jsonarchivo del paquete (es decir, un comando incorporado). lint-packageses un ejemplo de cómo ejecutar un script en todos los paquetes. Tenga en cuenta la --is-presentbandera que evita un error si un paquete no especifica el lintscript.

A diferencia de Yarn Berry, npm no admite la ejecución de scripts en paralelo con la -wsbandera. lint-packages:parallelmuestra una solución para lograr esto especificando cada paquete.

También puede instalar dependencias para un paquete con la -wbandera o para todos los paquetes con la -wsbandera:

$ npm i http-server -w @doppelmutzi/server
$ npm i ntl -ws

Una de las principales ventajas de monorepos es usar bibliotecas compartidas. Como ejemplo, la aplicación de demostración de React utiliza todos los espacios de trabajo especificando las dependencias en su archivo package.json.

// package.json
"dependencies": {
    "@doppelmutzi/eslint-config": "file:./packages/eslint-config",
    "@doppelmutzi/hooks": "file:./packages/hooks",
    "@doppelmutzi/server": "file:./packages/server",
    // ...
}

Espacios de trabajo de Yarn Berry

Un proyecto de espacios de trabajo de Yarn Berry se puede inicializar con yarn init -w. Crea una packagescarpeta, un .gitignore, y un package.json. contiene la package.jsonconfiguración de los espacios de trabajo que apunta a la packagescarpeta creada. Como ejemplo, con mkdir yarn-demo; cd yarn-demo; yarn init -w;lo siguiente package.jsonse genera.

{
  "name": "yarn-demo",
  "packageManager": "yarn@3.2.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Este nivel de raíz package.jsondebe ser privado y tener una workspacesmatriz que especifique dónde se ubican los espacios de trabajo. Puede especificar espacios de trabajo con el uso de globos (p. ej., packages/*) o explícitamente (p. ej., packages/hooks).

Echemos un vistazo a cómo se ve una estructura de proyecto típica después de ejecutar el yarncomando en la carpeta raíz de la rama del proyecto de demostración . Cada espacio de trabajo se encuentra en la packagescarpeta y alberga un archivo package.json.

.
├── .yarn/
│   ├── cache/
│   ├── plugins/
│   ├── releases/
│   ├── sdk/
│   └── unplugged/
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

El aspecto interesante es que solo hay un yarn.lockarchivo en el nivel raíz. Además, todas las dependencias, incluidas las de los espacios de trabajo, se almacenan en un .pnp.cjsarchivo y una .yarn/cache/carpeta, también ubicados en el nivel raíz.

Un espacio de trabajo es una carpeta que contiene un package.jsonsin requisitos especiales. Como verá a continuación, los complementos para mejorar el flujo de trabajo de los espacios de trabajo se almacenan en archivos .yarn/plugins/.

Yarn Berry proporciona un comando CLI, yarn workspace, para ejecutar comandos en el contexto de un espacio de trabajo. Como ejemplo, desde el nivel raíz puede agregar una dependencia de desarrollo al espacio de trabajo de Hooks:

$ yarn workspace @doppelmutzi/hooks add -D @babel/runtime

Después de instalar el workspace-toolscomplemento , puede utilizar el yarn workspace foreachcomando que le permite ejecutar un script en múltiples espacios de trabajo.

$ yarn plugin import workspace-tools
$ yarn workspaces foreach -p run lint

El foreachcomando anterior ejecuta el lintscript en cada espacio de trabajo con un script con este nombre. La -pbandera, abreviatura de --parallel, ejecuta todos los scripts en paralelo.

Una característica útil del yarn runcomando es que puede ejecutar secuencias de comandos que contengan dos puntos ( :) desde cada carpeta de su proyecto de espacios de trabajo. Considere un script con el nombre root:nameen la raíz package.jsonque imprime el nombre del paquete.

// root package.json
{
  // ...
  "scripts": {
    "root:name": "cat package.json | grep name"
  }
} 

No importa qué carpeta yarn root:namese ejecute, ejecuta el script con el mismo nombre de la carpeta raíz. Esta función se puede utilizar para definir algunos scripts "globales".

Si desea evitar que un paquete se resuelva desde un registro remoto desde uno de sus espacios de trabajo, debe usar el protocolo de resolución de espacios de trabajo . En lugar de usar valores de semver dentro de las propiedades de sus dependencias de desarrollo o package.jsonarchivos de dependencias, debe usar lo siguiente:

"dependencies": {
    "@doppelmutzi/eslint-config": "workspace:*"
}

Esto le dice a Yarn Berry que el paquete @doppelmutzi/eslint-configdebe resolverse desde un espacio de trabajo local que se encuentra en la packagescarpeta. Yarn Berry escanea todos los package.jsonarchivos en busca de una namepropiedad con el valor de @doppelmutzi/eslint-config.

Yarn Berry también admite la clonación de espacios de trabajo de cualquier proyecto a través del protocolo Git.

"dependencies": {
    "@doppelmutzi/eslint-config": "git@github.com:doppelmutzi/companion-project-mono-repo-2022.git#workspace=@doppelmutzi/eslint-config"
}    

En este ejemplo, recupero directamente el espacio @doppelmutzi/eslint-configde trabajo del repositorio de Git especificado que constituye un proyecto de espacios de trabajo de Yarn Berry.

Las restricciones son un mecanismo de bajo nivel para escribir reglas de espacio de trabajo que deben cumplirse. Es un poco como ESLint para package.json; por ejemplo, cada espacio de trabajo debe incluir un campo de licencia en su archivo package.json.

Para los desarrolladores de JavaScript, puede ser inusual definir estas restricciones porque las escribe con el lenguaje de programación lógica Prolog . Debe proporcionar un constraints.proarchivo en la carpeta raíz del proyecto.

% Ensure all workspaces are using packageManager field with version 3.2.0
gen_enforced_field(WorkspaceCwd, 'packageManager', 'yarn@3.2.0').

El ejemplo simple asegura que todos los espacios de trabajo tengan un packageManagercampo que aplique Yarn Berry v3.2.0 como administrador de paquetes. Como parte de un flujo de trabajo de CI/CD, puede ejecutar $ yarn constraintsy interrumpir la canalización si no se cumplen las restricciones.

espacios de trabajo pnpm

pnpm ha ofrecido soporte para espacios de trabajo desde el principio. Necesita un pnpm-workspace.yamlarchivo obligatorio en la carpeta raíz del proyecto para usar esta función.

# pnpm-workspace.yaml
packages:
  - 'packages/**'

Esta configuración de ejemplo le dice a pnpm que todos los espacios de trabajo están ubicados dentro de la packagescarpeta. Al ejecutarse pnpm ien la carpeta raíz, se instalan las dependencias definidas en la raíz package.json, así como todas las dependencias especificadas en los package.jsonarchivos de los espacios de trabajo. La siguiente estructura de carpetas de la rama pnpm Git del proyecto de demostración es el resultado del proceso de instalación.

.
├── node_modules/
│   ├── # dependencies defined in package.json
├── packages/
│   ├── eslint-config/
│   │   └── package.json # no dependencies defined
│   ├── hooks/
│   │   ├── node_modules/ # dependencies defined in hooks/package.json
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/ # dependencies defined in server/package.json
│   │   └── package.json
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

Como puede ver, solo hay un archivo de bloqueo ( pnpm-lock.yaml) pero varias node_modulescarpetas. A diferencia de los espacios de trabajo de npm, pnpm crea una node_modulescarpeta en cada espacio de trabajo, siempre que haya dependencias especificadas en el archivo package.json.

Para comparar la situación con la dependencia de React con espacios de trabajo de npm, como se describe en la sección anterior, react@17.0.2se instala en la carpeta raíz node_modulesy en el espacio de hookstrabajo porque esta dependencia se especifica en ambos package.jsonarchivos.

A diferencia de npm, las node_modulescarpetas no son planas. Como se describió anteriormente, debido al enfoque de almacenamiento direccionable por contenido, estas dependencias se instalan físicamente solo una vez en el disco duro en el almacén central.

La raíz package.jsonrevela que existen múltiples indicadores útiles y que se pueden usar en el contexto de los espacios de trabajo.

{
  // ...  
  "start-server": "pnpm serve --filter @doppelmutzi/server",
  "publish-eslint-config": "pnpm publish -F @doppelmutzi/eslint*",
  "lint-packages": "pnpm lint -r --parallel",
}

El indicador de filtro ( --filtero -F) restringe un comando a uno o más espacios de trabajo. El start-serverscript demuestra cómo ejecutar un script en un espacio de trabajo en particular ( @doppelmutzi/server). También puede usar un patrón ( *) para hacer coincidir los espacios de trabajo, como se muestra en el publish-eslint-configscript.

Con el indicador recursivo ( --recursiveo -r), puede ejecutar un comando recursivamente en todos los espacios de trabajo. El lint-packagesscript muestra un ejemplo con el comando de ejecución que ejecuta el lintscript en todos los espacios de trabajo.

A diferencia de npm, pnpm ignora todos los espacios de trabajo que no proporcionan dicho script. Con el indicador paralelo , el script se ejecuta simultáneamente.

pnpm admite un protocolo de espacio de trabajo ( workspace:) similar al de Yarn Berry para usar espacios de trabajo como dependencias en su monorepo. El uso de este protocolo evita que pnpm resuelva las dependencias del espacio de trabajo local desde un registro remoto. El extracto de la raíz package.jsondemuestra cómo usar este protocolo.

// package.json
{
  // ...
  dependencies: {
    "@doppelmutzi/eslint-config": "workspace:1.0.2",
    "@doppelmutzi/hooks": "workspace:*",
    "@doppelmutzi/server": "workspace:./packages/server",
  // ...
  }
}

El uso workspace:le dice a pnpm que desea instalar dependencias que constituyen espacios de trabajo locales. "@doppelmutzi/eslint-config": "workspace:1.0.2"instala el espacio de trabajo local @doppelmutzi/eslint-configporque su versión package.jsones 1.0.2. **Si intenta instalar otra versión, el proceso de instalación falla.

La versión en el espacio de trabajo no coincide

Lo más probable es que desee utilizar el estado actual de un espacio de trabajo tal como existe en su proyecto de espacios de trabajo. Por lo tanto, puede usar workspace:*como se demostró con la dependencia @doppelmutzi/hooks. @doppelmutzi/servermuestra que también puede hacer referencia a un espacio de trabajo con una ruta relativa. Tiene el mismo efecto que workspace:*.

Similar a Yarn Berry, también es posible hacer referencia a espacios de trabajo desde un monorepo remoto con pnpm add.

Comandos CLI relacionados con el espacio de trabajo

Las siguientes tablas comparan un conjunto seleccionado de diferentes comandos CLI disponibles en npm, Yarn Berry y pnpm en el contexto de los espacios de trabajo. Esta no es una lista completa, pero constituye una hoja de trucos. Las siguientes tablas completan los comandos de mi último artículo con ejemplos relacionados con el espacio de trabajo.

Gestión de dependencias

Esta tabla cubre los comandos de administración de dependencias para instalar o actualizar todas las dependencias especificadas en package.json, o múltiples dependencias especificándolas en los comandos. Todos los comandos se pueden ejecutar en el contexto de uno o más espacios de trabajo. y todos los comandos se ejecutan desde la carpeta raíz del proyecto de espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
instalar deps de todos los espacios de trabajo
  • npm install
  • alias:i
  • yarn install
  • alias:yarn
  • pnpm install
  • alias:i
instalar dependencias de un solo espacio de trabajo
  • npm i --workspace server
  • alias:-w
  • pnpm i --filter server
  • alias:-F
Agregar dependencias de nivel raíz
  • npm i eslint
  • yarn add eslint
  • pnpm i eslint
Agregar dependencias al espacio de trabajo
  • npm i -D react -w hooks
  • yarn workspace hooks add -D react
  • pnpm i -D -F hooks react
  • pnpm add -D -F hooks react
Agregar dependencia del espacio de trabajo al espacio de trabajo
  • N / A
  • yarn workspace app add hooks@'workspace:*'
  • pnpm i -F app hooks@'workspace:*'
actualizar todas las dependencias del espacio de trabajo
  • npm update -w hooks
  • yarn workspace hooks up
  • pnpm up -F hooks
  • pnpm up --latest -F hooks
  • alias:-L
actualizar la dependencia del espacio de trabajo
  • npm update react -w hooks
  • yarn workspace hooks up react
  • pnpm up -F hooks react
  • pnpm up -L -F hooks react
Eliminar dependencias del espacio de trabajo
  • npm uninstall react -w hooks
  • yarn workspace hooks remove react
  • pnpm remove --filter hooks react

Ejecución de guiones

Esta tabla muestra comandos para ejecutar scripts en uno o varios espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
ejecutar script en un espacio de trabajo
  • npm run build -w hooks
  • yarn workspace hooks build
  • pnpm run build -F hooks
  • pnpm build -F hooks
ejecutar script en múltiples espacios de trabajo
  • npm run lint -w server -w hooks
  • N / A
  • solución alterna:yarn workspace hooks lint && yarn workspace server lint
  • pnpm -F server -F hooks lint
ejecutar secuencias de comandos en todos los espacios de trabajo secuencialmente
  • npm run lint --workspaces
  • alias:-ws
  • pnpm run --recursive lint
  • alias:-r
ejecutar script en todos los espacios de trabajo secuencialmente si está disponible
  • npm run lint -ws --if-present
  • yarn workspaces foreach run lint
  • pnpm run -r lint
ejecutar script en todos los espacios de trabajo en paralelo
  • N / A
  • solución alterna:npm run lint -w p1 & npm run lint -w p2
  • yarn workspaces foreach --parallel run lint
  • alias:-p
  • pnpm run -r lint --parallel

Varios

Esta tabla cubre útiles comandos incorporados. Si no hay un comando oficial, a menudo se puede usar un comando de terceros para lograr cosas similares, a través de un paquete npm o un complemento de Yarn Berry.

 sobre el nivel del marBaya de hilopnpm
proyecto de espacios de trabajo init
  • npm init -w ./packages/server(crea la configuración junto con el espacio de trabajo especificado)
  • yarn init --workspace
  • alias:

-w

  • N / A
espacio de trabajo de inicio
  • npm init -w ./packages/server
  • N / A
  • N / A
enumerar espacios de trabajo
  • N / A
  • yarn workspaces list
  • yarn workspaces list --json
  • N / A
Comprobar las restricciones del espacio de trabajo
  • N / A
  • N / A

Qué significan todas estas innovaciones para el futuro

Los proyectos frontend son cada vez más complejos; se requieren más y más dependencias para construirlos. El proceso de instalación, especialmente para monorepos, requiere mucho tiempo y en parte es propenso a errores. El estado actual de los administradores de paquetes ha solucionado muchos problemas, pero todavía hay espacio para mejoras.

tnpm , por ejemplo, es un servicio empresarial de Alibaba que parece haber subido el listón para los administradores de paquetes en el entorno empresarial cerrado. Su estrategia de resolución de dependencias reduce las solicitudes HTTP, en comparación con los administradores de paquetes descritos anteriormente.

Además, el gráfico de dependencia de tnpm se genera en el servidor, en conexión con una estrategia de almacenamiento en caché de varios niveles. Actualmente, esto es difícil de lograr con una solución no empresarial como npm, pnpm o Yarn, pero ciertamente establece el estándar de lo que es posible.

tnpm demuestra que todavía hay potencial de mejora en el espacio del administrador de paquetes. Fuente: tnpm en Dev.to

Los administradores de paquetes públicos todavía están investigando de forma independiente formas de mejorar el rendimiento y abordar los puntos débiles conocidos (por ejemplo, el almacenamiento de dependencia ineficiente, que discutimos aquí). Incluso npm está trabajando en un "modo aislado" que creará enlaces simbólicos node_modules, inspirados en pnpm. Con este cambio, npm se ha referido a su actual estrategia de resolución a largo plazo como "modo elevado".

pnpm también está realizando investigaciones con FUSE para proporcionar una alternativa al modo PnP de Yarn Berry, que parece prometedor (y probablemente también explique por qué casi no puede encontrar información sobre pnpm PnP en línea en este momento).

En última instancia, no se puede elogiar más lo bien que trabajan juntos los administradores de paquetes en términos de inspirarse mutuamente y compartir conocimientos. Puede ver esto en muchos lugares, como la sección de comentarios de este artículo en tnpm .

Conclusión

Parece que habrá múltiples administradores de paquetes en el futuro. Es posible que no quieran tener conjuntos de características y conceptos iguales para abordar mejor la miríada de problemas que enfrentan los diferentes usuarios.

Por un lado, esto es maravilloso porque significa que habrá opciones para elegir el flujo de trabajo óptimo para un proyecto. Tampoco hay nada que nos impida usar diferentes administradores de paquetes en un entorno de equipo para diferentes proyectos, ya que se basan en conceptos similares.

Por otro lado, cada vez es más difícil para los proveedores de bibliotecas admitir todos estos administradores de paquetes y sus respectivas diferencias. Como ejemplo, en mi proyecto actual no puedo usar Yarn Berry porque una herramienta establecida no admite su formato de archivo de bloqueo. Queda por ver si se superará o no el apoyo a estas diferencias.

Fuente: https://blog.logrocket.com/exploring-workspaces-other-advanced-package-manager-features/ 

 #packaging  #workspace #pnpm #npm 

Cómo Yarn Y Pnpm Han Centrado Sus Esfuerzos Más De Cerca
Zac Efron

Zac Efron

1648213909

6 Best Office Chairs for Lower Back Pain!

What is Ergonomics? 

Ergonomic is the branch of science that deals with the workplace furniture, infrastructure, and environment and its effects on human health. From an office point of view, sitting on a chair for long period can cause low back pain and aggregate the previously existing low back pain. Continuous sitting on a chair increases the pressure and stress on shoulders and arms that ultimately put pressure on your back and spinal muscles. Stiffness and spasm in back muscles can also cause disc slip, one of the major reasons for back pain. An ergonomic chair is a tool that reduces the risk of back problems and helps in maintaining a good and correct posture. Most people sit in the decline position or in overstretch position, which affects the muscle ligaments and causes stiffness in the surrounding structures of the disc. It is not only about the office chair, wrong sitting posture or static position also contributes to low back pain. Buying an ergonomic chair is one part, adjusting the chair according to your body and type of work has equal importance as the body structure varies from person to person. Make sure the office chair has back support according to the lower back curve, enough space for thighs and knees that enhance the comfort level and reduce pain aggregation. The angle between hips and low back must be 90 degrees and fully supported with backrest as it put less pressure on back muscles. There are 6 best back-supported chairs that are written below that you must consider before buying your office chair.               

 

  • Ergohuman LE9ERG Office Chair

Ergohuman is one of the highly recommended chairs in low back pain. The design to support the lumbar region is impressive. As the lumber region is, the main part of the back is exposed to the chair so the chair should be comfortable from the lumbar region. The protruding upper part of the chair makes the upper backrest as well which is an exceptional feature. LE9ERG has a height-adjustable backrest that allows full support and movement on the lumbar region. It also contains an automatic depth adjusting feature depending upon, how much weight or pressure you put on the chair. You can twist or move your back, as the chair will move accordingly, which gives more flexibility and elasticity to the low back. There is no spreading of lower structure as it supports a certain area of lumber and does not occupy extra space that made this chair user-friendly.       

  • Herman Miller Mirra 2

It is a butterfly-shaped chair with fantastic back support. If you are looking for an office chair that allows you to work for long hours at a particular table then Herman miller is the best choice. It is one of the expensive chairs but highly recommended and effective. The features like effortless movement, resting feeling at spine, prevention from slouching, and fully supported back made this chair the go-to choice. There are height-adjusted and arm-adjusted features as well alongside excellent low back support. The seat supported by cushions can divide your weight equally on the chair as the chair can bear the weight up to 350kg. The network of thread is so beautiful and durable that even on warm days, it provides a cooling effect. Although it is expensive, still one of the best ergonomic chairs for low back pain and found worth investment.          

  • Gabrylly Mesh Office Chair

Gabrylly mesh office chair is a commonly used chair with all the four general supports that a chair contains. It has lumber support, head support, hand supports, and back support that is comfortable enough in long hours of working. The mesh and backrest of the chair help in reducing the pain and allow air circulation that enhances the comfort level. This chair is enough comfortable for eight hours of duty in the office without body fatigue and sweating on your back. These features made this chair a bestselling product for a furniture manufacturer.  

  • Steelcase Leap Office Chair

This chair is ranked no 4 in this article as it provides medium-strong lumber support. The lumbar support is strong enough to allow the movement in a multi-direction. The design of the backrest is traditionally padded but the support is strong enough for low back depending on how you rate or customize your lumber region. Technically Steelcase leap is not a working chair but used in-office meetings and office drawing rooms. You can adjust the lumbar support, as the chair is height adjustable. The adjustment should be precise as it increases or decreases tension on the spine that ultimately affects the back curve. The pressure or weight of the body is absorbed by mesh and allows you easy up and down movement of your back. The feature that made this chair user-friendly is reclining, you can recline up to 50% on this chair even beyond this point it provides medium support to your back with a backrest.           

  • SHIOO Office Chair

SHIOO ergonomic office chair has five adjustable features that made him super comfortable. It includes height-adjustable armrests, headrest, back support, stepless seat, and tilting capability. If you are going to work on a computer for a longer period, this chair can provide you with the most comfortable and pleasant experience. This ergonomic office chair offers a great assistant in back pain and found one of the quality office chairs. The chair can bear up to 150 kg weight and is easy to gather and place anywhere. This SHIOO office chair contains a three-year warranty and is not as expensive as it seems which made this chair a common office product and easy to buy.       

  • Comhoma Office Desk Chair

If you have a small amount or looking for a less costly office chair then Comhoma office desk chair is the best choice. It chair lies in the affordable furniture in Kent category but still has the appropriate structural feature to support your low back pain and is kind enough to your spine. It is one of the common chairs with fewer advanced features but you can still adjust the height of the seat manually. The armrest can be moved in the upward and downward direction to increase the comfort level. The mesh is breathable and padded which allows working throughout the day easy and comfortable. The mesh does not make the seat warm, it remains cool even on warm days and gives calmness to you while working. At such an affordable price, you can still have an ergonomically spine-supported chair with an overall attractive design, which is impressive. If you are looking for one of these chairs or any other customized chair then you are at the right place. We are the best in the town in making customized and friendly furniture for our customers. 

#furniture #office #officefurniture #onlineshopping #desk #table #workspace         

6 Best Office Chairs for Lower Back Pain!