1679242566
Coworking Full Flutter App. Complete Solution of your virtual office booking. https://bit.ly/coworking_env #flutter #flutterdev #flutterapp #coworking #virtualoffice #workspace #booking #bookingoffice
1677751485
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
1677720000
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
.
├── 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)
Apps should not depend on apps, they can depend on packages
Apps can depend on packages, packages can depend on each others...
If needed static resources like images,... can be shared by using symlinks in the repo.
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)
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...).
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:^",
},
}
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:^",
},
}
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.
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.
The packages are now linked to your app, just import them like regular packages: import { poney } from '@your-org/magnificent-poney'
.
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.
Some convenience scripts can be run in any folder of this repo and will call their counterparts defined in packages and apps.
Name | Description |
---|---|
yarn g:changeset | Add a changeset to declare a new version |
yarn g:typecheck | Run typechecks in all workspaces |
yarn g:lint | Display linter issues in all workspaces |
yarn g:lint --fix | Attempt to run linter auto-fix in all workspaces |
yarn g:lint-styles | Display css stylelint issues in all workspaces |
yarn g:lint-styles --fix | Attempt to run stylelint auto-fix issues in all workspaces |
yarn g:test | Run unit and e2e tests in all workspaces |
yarn g:test-unit | Run unit tests in all workspaces |
yarn g:test-e2e | Run e2e tests in all workspaces |
yarn g:build | Run build in all workspaces |
yarn g:clean | Clean builds in all workspaces |
yarn g:check-dist | Ensure build dist files passes es2017 (run g:build first). |
yarn g:check-size | Ensure browser dist files are within size limit (run g:build first). |
yarn clean:global-cache | Clean tooling caches (eslint, jest...) |
yarn deps:check --dep dev | Will print what packages can be upgraded globally (see also .ncurc.yml) |
yarn deps:update --dep dev | Apply possible updates (run yarn install && yarn dedupe after) |
yarn check:install | Verify if there's no peer-deps missing in packages |
yarn install:playwright | Install playwright for e2e |
yarn dedupe | Built-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 forglobal:
. See the complete list in root package.json.
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
, ayarn install
is required. To prevent having duplicates in the yarn.lock, you can runyarn dedupe --check
andyarn dedupe
to apply deduplication. The duplicate check is enforced in the example github actions.
See an example in ./apps/nextjs-app/.eslintrc.js and our eslint-config-bases.
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.
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
You'll find some example workflows for github action in .github/workflows. By default, they will ensure that
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"
The ESLint plugin requires that the eslint.workingDirectories
setting is set:
"eslint.workingDirectories": [
{
"pattern": "./apps/*/"
},
{
"pattern": "./packages/*/"
}
],
More info here
Vercel support natively monorepos, see the vercel-monorepo-deploy document.
There's a basic example for building a docker image, read the docker doc.
Netlify, aws-amplify, k8s-docker, serverless-nextjs recipes might be added in the future. PR's welcome too.
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 handleyarn add something --exact
on per-case basis.
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.
Author: Belgattitude
Source Code: https://github.com/belgattitude/nextjs-monorepo-example
License: MIT license
1677672805
^3.0.0
supports project references.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
Using yarn workspace feature, configure the following files:
Append the workspaces
key.
{
"private": true,
"workspaces": [
"packages/*"
]
}
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.
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.
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.
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.
Our repository has multiple tsconfig.json
files. We can compile all packages with "-b" option:
$ tsc -b packages/x-core packages/x-cli
Author: Quramy
Source Code: https://github.com/Quramy/lerna-yarn-workspaces-example
License: MIT license
1671629164
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.
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.
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.
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.
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.
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/
1661170810
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ó.
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:
__tests__
thư mụcuseDevBuild.html
trong trình duyệtuseProdBuild.html
trong trình duyệtĐể 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à workspaces
tài sản. Khai báo tất cả các thư mục trong packages
dướ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
1661163565
Руководство по созданию библиотеки с использованием рабочих пространств Webpack и Yarn.
Требования
Это требования. Но если вы заглянете в репозиторий, там есть ссылки и пояснения. Я пытался дать объяснение настолько хорошо, насколько мог, но оно редко бывает идеальным или универсальным для всех. Существуют шаги для создания и тестирования кода, чтобы вы могли поиграть с ним. Много ресурсов, чтобы покопаться и узнать, как это работает.
Цель
Создайте приложение, демонстрирующее сборку пакетов с использованием JavaScript и монорепозитория.
Разделить логику с помощью монорепозитория
Используйте сборщик модулей для создания пакета, который зависит от другого пакета, не опубликованного в NPM.
Спецификации
Для краткости сделаем калькулятор.
Мы создадим приложение-калькулятор, которое будет выполнять четыре операции:
+ add
- subtract
* multiply
/ divide
Делаем калькулятор. Мы разделяем логику на четыре пакета.
Наш калькулятор будет использовать четыре пакета. Мы используем webpack для сборки нашего пакета калькулятора.
Инициировать репозиторий
Выполнить (следующая команда является сокращением для yarn install
) :
yarn
Сборка пакета
Разработка и производство
yarn build
Запустить тесты
Сначала соберите пакет.
Для проверки в браузере:
__tests__
каталогuseDevBuild.html
в браузереuseProdBuild.html
в браузереДля тестирования в 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
1661156340
使用 Webpack 和 Yarn 工作區構建庫的指南。
要求
這些是要求。但是,如果您確實查看了存儲庫,則會有參考資料和解釋。我試圖提供盡可能好的解釋,但它很少對每個人都是完美或普遍的。有一些步驟可以構建和測試代碼,以便您可以使用它。大量的資源可以挖掘和學習它是如何工作的。
目標
構建一個演示使用 JavaScript 和 monorepo 構建包的應用程序。
使用 monorepo 拆分邏輯
使用模塊捆綁器創建一個依賴於另一個未發佈到 NPM 的包的包。
眼鏡
為了簡潔起見,讓我們做一個計算器。
我們將構建一個具有四個操作的計算器應用程序:
+ add
- subtract
* multiply
/ divide
我們正在構建一個計算器。我們將邏輯拆分為四個包。
我們的計算器將使用四個包。我們使用 webpack 來構建我們的計算器包。
啟動存儲庫
運行(以下命令是 的簡寫yarn install
):
yarn
構建包
開發與生產
yarn build
運行測試
首先構建包。
在瀏覽器中測試:
__tests__
目錄useDevBuild.html
在瀏覽器中打開useProdBuild.html
在瀏覽器中打開要在 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
1661149080
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.
See more at: https://faun.pub/build-library-using-javascript-webpack-and-workspaces-e71310ad8db8
#javascript #webpack #workspace
1661141728
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.
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 :
__tests__
répertoireuseDevBuild.html
dans le navigateuruseProdBuild.html
dans le navigateurPour 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_modules
ré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 workspaces
la propriété. Déclare tous les répertoires en packages
tant 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
1657222080
serverless-workspaces-plugin
resolve and link hoisted dependencies when packaging
yarn add serverless-workspaces-plugin -W
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
1654054260
jest-watch-yarn-workspaces
A Jest watch plugin to select Yarn workspaces to test
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
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
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:
1650052800
この記事は、開発者が適切なパフォーマンスと優れたDXを備えた大規模なモノレポプロジェクトを管理できるようにするなど、開発者のニーズをサポートするためにパッケージマネージャーが将来どこに向かっているのかを印象付けることを目的としています。
以前の記事で、npm、Yarn、およびpnpm間の依存関係解決戦略のトピックについて書きました。前回の記事ではコアの概念と構造の比較に焦点を当てていましたが、この記事では、ワークスペースを通じて、モノリポジトリを含む最新のパッケージマネージャーの高度な機能について説明します。
この記事の目的は、Yarnとpnpmが、開発者がワークスペースを介してモノリポジトリを構築できるようにし、セキュリティとパフォーマンスを向上させるためのより高度なアプローチを提供することに、どのように注力してきたかを伝えることです。
この記事では、いくつかのパッケージマネージャー機能について説明します。したがって、例を示すために、GitHubで2つのコンパニオンプロジェクトを作成しました。
デフォルト構成を使用する場合、pnpmとYarn Berryは、npmとYarn Classicと同じ依存関係解決アルゴリズムを使用しません。これには、node_modules
フォルダーのフラット化が含まれます。これらの最新のパッケージマネージャーは、依存関係を処理および保存するための従来のアプローチとは別の方法を試みます。
この理由は、大量の依存関係をますます利用する最新のソフトウェアプロジェクトの要件に対処するには、革新的な解決アプローチが必要であるためです。従来の戦略は、パフォーマンスとディスクスペース効率の点で限界に達しています。
node_modules
アプローチの問題node_modules
フォルダをフラット化する従来の依存関係解決戦略では、いくつかの異なる問題が発生します。
このフラットレイアウトの根本的な問題は、v3のnpmによって導入された巻き上げとnode_modules
呼ばれる概念です。これと同じ依存関係解決アルゴリズムは、最初はYarnClassicでも使用されていました。
簡単に言えば、巻き上げるとnode_modules
、依存関係の依存関係も含めて、すべての依存関係がルートレベルの。になるようにフォルダーがフラット化されますnode_modules
。すべてを1つのフォルダーレベルに持ち上げる理由は、ネストによって生じる冗長性を減らすためです。次の画像は、これがどのように機能するかを示しています。
npmv2とnpmv3のnode_moduleアルゴリズムの違い
巻き上げは、特に大規模なプロジェクトでは、深刻で検出が困難なエラーにつながる可能性があります。Jonathan Creamerは、巻き上げアルゴリズムが失敗して生産エラーが発生するモノレポプロジェクトで何がうまくいかないかについて詳細に説明しています。このような状況では、巻き上げは幻の依存関係やドッペルゲンガーにつながる可能性があります。
ヤーンベリーは、プラグアンドプレイアプローチnode_modules
を使用して、完全に捨てようとしました。Yarn Berryの駆除の動機について読むことができますが、その理由はpnpmの場合と同様です。node_modules
require
PnPは、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
依存関係の問題をデバッグするには、zipファイルの「内部を調べる」必要があるため、追加のツールサポート( VS Code Extensionなど)が必要です。このような機能は組み込まれていないため、執筆時点では、エディターSDKサポートを追加して手動の手順を実行する必要があります。次のコマンドは、VSCodeのサポートを追加します。
$ yarn dlx @yarnpkg/sdks vscode
SDK CLIは、サポートされているテクノロジーについてルートpackage.json
を分析し、に保存される構成ファイルを生成します。.yarn/sdk/
SDKCLIのファイル変更
デモプロジェクトの場合、ESLintとPrettierを検出します。Gitブランチをチェックして、PnPおよびSDKサポートyarn-berry-pnp
の例を確認してください。
.pnp.cjs
PnPの良いところは、ファイルサイズが適切であるため、ファイルと.yarn/cache/
フォルダーをバージョン管理下に置くことができることです。これから得られるのは、ゼロインストール戦略です。チームメイトがGitからコードをプルする場合(この戦略を使用すると少し時間がかかる場合があります)、すべてのパッケージとルックアップテーブルが手元にあり、アプリケーションを開始する前にインストール手順は必要ありません。ゼロインストールの動作を示す短いデモビデオをご覧ください。
.gitignore
ファイルがYarnBerryPnPゼロインストールブランチのように見えることがわかります。依存関係を追加、更新、または削除する場合はyarn install
、もちろん、、、およびフォルダーを更新するyarn.lock
ため.pnp.cjs
に.yarn/cache/
実行する必要があります。
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_modules
Yarn Classicはレガシーと見なされており、いくつかの改善の恩恵を受けていますが、を使用した従来のインストールモードに固執しているため、YarnBerryに切り替えることをお勧めしますnode-modules nodeLinker
。
# .yarnrc.yml
nodeLinker: "node-modules"
これにより、古き良きnode_modules
フォルダが再び生成されます。
Yarn Berryチームは、pnpmのコンテンツアドレス可能なストレージ戦略にも触発されました。これについては以下で説明し、同じ名前のモードを追加しました。これはその原型に似ており、依存関係をハードドライブに一度だけ保存することを目的としています。
# .yarnrc.yml
nodeLinker: "pnpm"
デモプロジェクトの対応するGitブランチをチェックして、さまざまなモードを自由にテストしてください。
node_modules
とnodeLinker
nodeLinker
node_modules
た戦略pnpmは、依存関係をnode_modules
npmのようにネストされたフォルダーに格納しますが、コンテンツアドレス可能なストレージを実装しているため、パフォーマンスとディスクスペースの効率が向上します。これについては、パッケージマネージャーに関する以前の記事で詳しく読むことができます。
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のバンドルバージョンに付属するノードバージョンを切り替える最も簡単な方法は、nvmを使用することです。次に、npm自体を最新バージョンに更新することもできます。下記は用例です。
$ nvm use 17.40
$ npm -v # 8.1.2
$ nvm install-latest-npm
$ npm -v # 8.3.2
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.yml
yarnPath
# .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コンテキストで特に役立つインストールワークフローの追加機能に焦点を当てます。多くの開発プロジェクトでは、キャッシング戦略など、パイプライン実行の処理時間を短縮するための効率的な戦略が必要です。
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 i --offline
。1つ以上のパッケージがストアの一部でない場合、エラーが発生します。
のようなコマンドはありませんがnpm ci
、そのメンテナによると、pnpmはCI/CDコンテキストでうまく機能します。
すべてのパッケージマネージャーは、パブリック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は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は、複数のプロジェクトを格納するGitリポジトリです。Googleは、かなり長い間、ほとんどのプロジェクトをモノレポで管理してきました。いくつかの利点が含まれます:
最新のパッケージマネージャーは、ワークスペースと呼ばれる機能を通じてモノリポジトリをサポートしています。このようなプロジェクトでは、すべてのワークスペースがサブプロジェクトを構成package.json
し、独自の依存関係ツリーを定義するを含みます。各実装の背後にある概念は、すべての代表者にとって非常に似ています。CLIは、monorepoの依存関係管理を簡素化し、パッケージマネージャーは、ワークスペース間の共有依存関係を処理して、ファイルシステムストレージの効率を向上させることもできます。
ただし、詳細には違いがあるため、すべてのパッケージマネージャーのワークスペース機能を見ていきます。
npmは、 2020年10月にリリースされたv7にワークスペース機能を追加しました。ワークスペースプロジェクトを設定するには、数ステップと、ワークスペースの場所をnpmに指示するワークスペースpackage.json
プロパティを含むルートフォルダーにが必要です。
// root package.json
// ...
"workspaces": [
"workspaces/a",
"workspaces/b",
"packages/*"
],
// ...
この例は、すべてのパッケージ(workspaces/a
、workspaces/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
-ws
Yarn 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 -w
。packages
フォルダ、、、.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.json
dev依存関係または依存関係ファイルのプロパティ内でsemver値を使用する代わりに、以下を使用する必要があります。
"dependencies": {
"@doppelmutzi/eslint-config": "workspace:*"
}
これにより、Yarn Berryは、フォルダー内@doppelmutzi/eslint-config
にあるローカルワークスペースからパッケージを解決する必要があることを通知します。packages
Yarn 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-config
YarnBerryワークスペースプロジェクトを構成する指定された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 constraints
CI / CDワークフローの一部として、制約が満たされていない場合にパイプラインを実行および中断できます。
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
。
次の表は、ワークスペースのコンテキストでnpm、Yarn Berry、およびpnpmで使用できるさまざまなCLIコマンドの精選されたセットを比較しています。これは完全なリストではありませんが、チートシートを構成します。次の表は、ワークスペース関連の例を使用して、前回の記事のコマンドを完了したものです。
package.json
この表は、で指定されたすべての依存関係、またはコマンドで指定することによる複数の依存関係をインストールまたは更新するための依存関係管理コマンドについて説明しています。すべてのコマンドは、1つ以上のワークスペースのコンテキストで実行できます。すべてのコマンドは、ワークスペースプロジェクトのルートフォルダーから実行されます。
アクション | npm | ヤーンベリー | pnpm |
---|---|---|---|
すべてのワークスペースのdepsをインストールします |
|
|
|
単一のワークスペースの部門をインストールする |
|
|
|
ルートレベルの依存関係を追加する |
|
|
|
ワークスペースに依存関係を追加する |
|
|
|
ワークスペースの依存関係をワークスペースに追加する |
|
|
|
ワークスペースのすべての依存関係を更新します |
|
|
|
ワークスペースの依存関係を更新する |
|
|
|
ワークスペースから依存関係を削除する |
|
|
|
この表は、1つまたは複数のワークスペースでスクリプトを実行するためのコマンドを示しています。
アクション | npm | ヤーンベリー | pnpm |
---|---|---|---|
ワークスペースでスクリプトを実行する |
|
|
|
複数のワークスペースでスクリプトを実行する |
|
|
|
すべてのワークスペースでスクリプトを順番に実行する |
|
|
|
可能な場合は、すべてのワークスペースでスクリプトを順番に実行します |
|
|
|
すべてのワークスペースでスクリプトを並行して実行する |
|
|
|
この表では、便利な組み込みコマンドについて説明します。公式コマンドがない場合は、多くの場合、npmパッケージまたはYarn Berryプラグインを介して、サードパーティのコマンドを使用して同様のことを実行できます。
npm | ヤーンベリー | pnpm | |
---|---|---|---|
initワークスペースプロジェクト |
|
|
|
initワークスペース |
|
|
|
ワークスペースを一覧表示します |
|
|
|
ワークスペースの制約を確認する |
|
|
|
フロントエンドプロジェクトはますます複雑になっています。それらを構築するには、ますます多くの依存関係が必要になります。特にモノリポジトリの場合、インストールプロセスは時間がかかり、部分的にエラーが発生しやすくなります。パッケージマネージャーの現状は多くの問題に取り組んでいますが、まだ改善の余地があります。
たとえば、 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/
1650043080
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.
Este artículo cubre varias características del administrador de paquetes. Por lo tanto, creé dos proyectos complementarios en GitHub para brindar ejemplos:
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_modules
carpetas. 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.
node_modules
La estrategia tradicional de resolución de dependencias para aplanar node_modules
carpetas genera varios problemas diferentes :
El problema raíz de este diseño plano node_modules
es 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_modules
carpeta 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 .
Yarn Berry trató de deshacerse por node_modules
completo, 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 require
flujo 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_modules
carpetas. 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.cjs
anidada . node_modules
Contiene 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.json
archivos, 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.cjs
archivo, 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_modules
carpeta, ¿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_modules
deben 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_modules
carpeta.
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_modules
carpetas; 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
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.json
en 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-pnp
para ver un ejemplo de compatibilidad con PnP y SDK.
Lo bueno de PnP es que puede poner el .pnp.cjs
archivo 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 .gitignore
archivo 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.cjs
y las .yarn/cache/
carpetas.
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.yml
configurando la nodeLinker
propiedad en consecuencia.
# .yarnrc.yml
nodeLinker: "pnp"
pnpMode: "loose"
El modo suelto es un compromiso entre el modo estricto PnP y el node_modules
mecanismo 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_modules
modo de instalación tradicional con node-modules nodeLinker
.
# .yarnrc.yml
nodeLinker: "node-modules"
Con esto, la buena vieja node_modules
carpeta 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:
node_modules
ynodeLinker
nodeLinker
node_modules
pnpm almacena las dependencias en una node_modules
carpeta 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.
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
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-is
se 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-components
paquete que especifiqué en mi archivo package.json
. Parece que styled-components
no enumera todas sus dependencias en su package.json
archivo .
Hay una solución típica para tal problema PnP: la packageExtensions
propiedad . Actualizar .yarnrc.yml
y ejecutar un adicional yarn install
para 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": "*"
}
}
}
},
// ...
}
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.
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 proporciona su propia herramienta para administrar las versiones de Node: el pnpm env
comando 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
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 version
agrega la versión descargada .yarn/releases/
y se actualiza .yarnrc.yml
para establecer la versión actual con la yarnPath
propiedad .
# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs
Con esta configuración, su binario instalado localmente yarn
difiere la ejecución a la versión binaria ubicada en yarnPath
. Si confirma esta configuración, junto con la .yarn/releases
carpeta, todos los compañeros de equipo usarán automáticamente la misma versión del yarn
binario. 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 version
en acción
Si usa Corepack, el comando también agrega la yarn
versión binaria instalada a la packageManager
propiedad en su package.json
archivo.
La packageManager
propiedad se agrega a nuestro package.json
archivo.
Esto se puede usar como una "capa" adicional en la parte superior de la yarnPath
configuració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 version
es un método sólido para aplicar la yarn
versión binaria correcta en todo su equipo. Este mecanismo es superior a los mecanismos de otros administradores de paquetes.
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é.
npm ci
es un comando similar a npm install
, pero package-lock.json
debe existir un archivo. Funciona tirando el tuyo node_modules
y recreándolo desde cero.
ci
significa "integración continua" y está destinado a ser utilizado en entornos CI/CD. Al ejecutar , no se actualizará $ npm ci
una 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-offline
si no tuviera conexión a Internet o si tuviera una conexión inestable. Si desea limpiar el caché, puede usar $ npm cache clean
.
No existe una contrapartida de Yarn Berry npm ci
para 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 cacheFolder
propiedad .
# .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 enableGlobalCache
propiedad . Cada proyecto con esta misma configuración comparte el caché global.
# .yarnrc.yml
enableGlobalCache: true
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 .
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.
La siguiente configuración es parte del .npmrc
archivo 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 .npmrc
archivo ubicado fuera del proyecto.
# ~/.npmrc
//gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
npmAlwaysAuth: true
npmAuthToken: "<my-token>"
pnpm usa el mismo mecanismo de configuración que npm , por lo que puede almacenar su configuración en un .npmrc
archivo. La configuración de un registro privado funciona de la misma manera que con npm.
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>"
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:
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.json
que 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.
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.json
en 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-workspace
dentro de la packages
carpeta. Además, se crea o actualiza una workspaces
propiedad dentro de la carpeta raíz para que contenga archivos .package.jsona-workspace
Cuando se ejecuta npm i
en 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 packages
carpeta. La src
carpeta 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_modules
carpeta plana. En un proyecto de espacios de trabajo, esta node_modules
carpeta 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.json
y hooks/package.json
especifiquemos 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.1
al server
paquete?
.
├── 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.json
archivo 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-server
script 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-name
se refiere a la propiedad del archivo name
del paquete . package.json
El script publish-eslint-config
demuestra cómo ejecutar un comando npm en otro paquete que no está definido explícitamente en el package.json
archivo del paquete (es decir, un comando incorporado). lint-packages
es un ejemplo de cómo ejecutar un script en todos los paquetes. Tenga en cuenta la --is-present
bandera que evita un error si un paquete no especifica el lint
script.
A diferencia de Yarn Berry, npm no admite la ejecución de scripts en paralelo con la -ws
bandera. lint-packages:parallel
muestra una solución para lograr esto especificando cada paquete.
También puede instalar dependencias para un paquete con la -w
bandera o para todos los paquetes con la -ws
bandera:
$ 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",
// ...
}
Un proyecto de espacios de trabajo de Yarn Berry se puede inicializar con yarn init -w
. Crea una packages
carpeta, un .gitignore
, y un package.json
. contiene la package.json
configuración de los espacios de trabajo que apunta a la packages
carpeta creada. Como ejemplo, con mkdir yarn-demo; cd yarn-demo; yarn init -w;
lo siguiente package.json
se genera.
{
"name": "yarn-demo",
"packageManager": "yarn@3.2.0",
"private": true,
"workspaces": [
"packages/*"
]
}
Este nivel de raíz package.json
debe ser privado y tener una workspaces
matriz 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 yarn
comando en la carpeta raíz de la rama del proyecto de demostración . Cada espacio de trabajo se encuentra en la packages
carpeta 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.lock
archivo en el nivel raíz. Además, todas las dependencias, incluidas las de los espacios de trabajo, se almacenan en un .pnp.cjs
archivo y una .yarn/cache/
carpeta, también ubicados en el nivel raíz.
Un espacio de trabajo es una carpeta que contiene un package.json
sin 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-tools
complemento , puede utilizar el yarn workspace foreach
comando que le permite ejecutar un script en múltiples espacios de trabajo.
$ yarn plugin import workspace-tools
$ yarn workspaces foreach -p run lint
El foreach
comando anterior ejecuta el lint
script en cada espacio de trabajo con un script con este nombre. La -p
bandera, abreviatura de --parallel
, ejecuta todos los scripts en paralelo.
Una característica útil del yarn run
comando 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:name
en la raíz package.json
que imprime el nombre del paquete.
// root package.json
{
// ...
"scripts": {
"root:name": "cat package.json | grep name"
}
}
No importa qué carpeta yarn root:name
se 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.json
archivos de dependencias, debe usar lo siguiente:
"dependencies": {
"@doppelmutzi/eslint-config": "workspace:*"
}
Esto le dice a Yarn Berry que el paquete @doppelmutzi/eslint-config
debe resolverse desde un espacio de trabajo local que se encuentra en la packages
carpeta. Yarn Berry escanea todos los package.json
archivos en busca de una name
propiedad 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-config
de 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.pro
archivo 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 packageManager
campo que aplique Yarn Berry v3.2.0 como administrador de paquetes. Como parte de un flujo de trabajo de CI/CD, puede ejecutar $ yarn constraints
y interrumpir la canalización si no se cumplen las restricciones.
pnpm ha ofrecido soporte para espacios de trabajo desde el principio. Necesita un pnpm-workspace.yaml
archivo 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 packages
carpeta. Al ejecutarse pnpm i
en la carpeta raíz, se instalan las dependencias definidas en la raíz package.json
, así como todas las dependencias especificadas en los package.json
archivos 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_modules
carpetas. A diferencia de los espacios de trabajo de npm, pnpm crea una node_modules
carpeta 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.2
se instala en la carpeta raíz node_modules
y en el espacio de hooks
trabajo porque esta dependencia se especifica en ambos package.json
archivos.
A diferencia de npm, las node_modules
carpetas 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.json
revela 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 ( --filter
o -F
) restringe un comando a uno o más espacios de trabajo. El start-server
script 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-config
script.
Con el indicador recursivo ( --recursive
o -r
), puede ejecutar un comando recursivamente en todos los espacios de trabajo. El lint-packages
script muestra un ejemplo con el comando de ejecución que ejecuta el lint
script 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.json
demuestra 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-config
porque su versión package.json
es 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/server
muestra 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
.
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.
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ón | sobre el nivel del mar | Baya de hilo | pnpm |
---|---|---|---|
instalar deps de todos los espacios de trabajo |
|
|
|
instalar dependencias de un solo espacio de trabajo |
|
|
|
Agregar dependencias de nivel raíz |
|
|
|
Agregar dependencias al espacio de trabajo |
|
|
|
Agregar dependencia del espacio de trabajo al espacio de trabajo |
|
|
|
actualizar todas las dependencias del espacio de trabajo |
|
|
|
actualizar la dependencia del espacio de trabajo |
|
|
|
Eliminar dependencias del espacio de trabajo |
|
|
|
Esta tabla muestra comandos para ejecutar scripts en uno o varios espacios de trabajo.
Acción | sobre el nivel del mar | Baya de hilo | pnpm |
---|---|---|---|
ejecutar script en un espacio de trabajo |
|
|
|
ejecutar script en múltiples espacios de trabajo |
|
|
|
ejecutar secuencias de comandos en todos los espacios de trabajo secuencialmente |
|
|
|
ejecutar script en todos los espacios de trabajo secuencialmente si está disponible |
|
|
|
ejecutar script en todos los espacios de trabajo en paralelo |
|
|
|
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 mar | Baya de hilo | pnpm | |
---|---|---|---|
proyecto de espacios de trabajo init |
|
|
|
espacio de trabajo de inicio |
|
|
|
enumerar espacios de trabajo |
|
|
|
Comprobar las restricciones del espacio de trabajo |
|
|
|
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 .
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/
1648213909
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 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.
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 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.
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 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.
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