1660036740
Diversity is a Julia package that provides functionality for measuring alpha, beta and gamma diversity of metacommunities (e.g. ecosystems) and their constituent subcommunities. It uses the diversity measures described in the arXiv paper arXiv:1404.6520 (q-bio.QM), How to partition diversity. It also provides a series of other older diversity measures through sub-modules. Currently these are all ecological diversity measures, but this will be expanded through interfacing to EcoJulia and BioJulia.
This package is in beta now, but is cross-validated against our R package boydorr/rdiversity, which is developed independently, so please raise an issue if you find any problems. We now use a DataFrame as the common output format for all of the diversity calculations to provide consistency with our R package rdiversity. The code is not optimised for speed at the moment due to the substantial changes that have happened to it under the hood, and the Phylogenetics submodule is also recently revised, and may need further improvements.
The package is registered in the General
registry on v1.x and so can be installed with add
. For example on Julia v1.6:
(@v1.6) pkg> add Diversity
Resolving package versions...
Updating `~/.julia/environments/v1.6/Project.toml`
[d3d5718d] + Diversity v0.5.5
Updating `~/.julia/environments/v1.6/Manifest.toml`
[d3d5718d] + Diversity v0.5.5
(@v1.6) pkg>
The package is confirmed to work against the current LTS Julia v1.4 release and the latest release on Linux, macOS, and Windows. It is also tested against nightly.
Contributions are very welcome, as are feature requests and suggestions. Please open an issue if you encounter any problems or would just like to ask a question.
The main package provides basic numbers-equivalent diversity measures (described in Hill, 1973), similarity-sensitive diversity measures (generalised from Hill, and described in Leinster and Cobbold, 2012), and related alpha, beta and gamma diversity measures at the level of the metacommunity and its component subcommunities (generalised in turn from Leinster and Cobbold, and described in arXiv:1404.6520 (q-bio.QM)). The diversity functions exist both with unicode names (e.g. ᾱ()), which are not automatically exported as we feel they are too short and with matching ascii names (e.g. NormalisedAlpha()), which are. We also provide a general function for extract any diversity measure for a series of subcommunity relative abundances.
Before calculating diversity a Metacommunity
object must be created. This object contains all the information needed to calculate diversity.
# Load the package into Julia
using Diversity
# Example population
pop = [1 1 0; 2 0 0; 3 1 4]
pop = pop / sum(pop)
# Create Metacommunity object
meta = Metacommunity(pop)
First we need to calculate the low-level diversity component seperately, by passing a metacommunity
object to the appropriate function; RawAlpha()
, NormalisedAlpha()
, RawBeta()
, NormalisedBeta()
, RawRho()
, NormalisedRho()
, or Gamma()
.
# First, calculate the normalised alpha component
component = NormalisedAlpha(meta)
Afterwhich, subdiv()
or metadiv()
are used to calculate subcommunity or metacommunity diversity, respectively (since both subcommunity and metacommunity diversity measures are transformations of the same low-level components, this is computationally more efficient).
# Then, calculate species richness of the subcommunities
subdiv(component, 0)
# or the average (alpha) species richness across the whole population
metadiv(component, 0)
# We can also generate a diversity profile by calculating multiple q-values simultaneously
df = subdiv(component, 0:30)
In some instances, it may be useful to calculate all subcommunity (or metacommunity) measures. In which case, a Metacommunity
object may be passed directly to subdiv()
or metadiv()
:
# To calculate all subcommunity diversity measures
subdiv(meta, 0:2)
# To calculate all metacommunity diversity measures
metadiv(meta, 0:2)
Alternatively, if computational efficiency is not an issue, a single measure of diversity may be calculated directly by calling a wrapper function:
norm_sub_alpha(meta, 0:2)
A complete list of these functions is shown below:
raw_sub_alpha()
: per-subcommunity estimate of naive-community metacommunity diversitynorm_sub_alpha()
: similarity-sensitive diversity of each subcommunity in isolationraw_sub_rho()
: redundancy of individual subcommunitiesnorm_sub_rho()
: representativeness of individual subcommunitiesraw_sub_beta()
: distinctiveness of individual subcommunitiesnorm_sub_beta()
: per-subcommunity estimate of effective number of distinct subcommunitiessub_gamma()
: contribution per individual in a subcommunity toward metacommunity diversityraw_meta_alpha()
: naive-community metacommunity diversitynorm_meta_alpha()
: average similarity-sensitive diversity of subcommunitiesraw_meta_rho()
: average redundancy of subcommunitiesnorm_meta_rho()
: average representativeness of subcommunitiesraw_meta_beta()
: average distinctiveness of subcommunitiesnorm_meta_beta()
: effective number of distinct subcommunitiesmeta_gamma()
: metacommunity similarity-sensitive diversityPhylogenetic diversity (described here) is automatically included in the Diversity module when the Phylo
package is loaded. Documentation for these diversity measures can be found here. The phylogenetics code relies on the Phylo package to generate trees to incorporate into the diversity code, and the ppropriate code will be created when both main packages are loaded:
julia> using Diversity, Phylo
julia> communities = [4 1; 3 2; 1 0; 0 1] / 12;
julia> nt = rand(Nonultrametric(4))
RootedTree with 4 tips, 7 nodes and 6 branches.
Leaf names are tip 1, tip 2, tip 4 and tip 3
julia> metaphylo = Metacommunity(communities, PhyloBranches(nt));
julia> raw_meta_rho(metaphylo, [1, 2])
2×8 DataFrame
│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │
│ │ String │ String │ Int64 │ String │ String │ String │ String │ Float64 │
├─────┼─────────────────────┼─────────┼───────┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤
│ 1 │ Phylogenetic Branch │ RawRho │ 1 │ types │ │ metacommunity │ │ 1.7787 │
│ 2 │ Phylogenetic Branch │ RawRho │ 2 │ types │ │ metacommunity │ │ 1.66749 │
The package also provides some other sub-modules for related measures:
Many existing ecological diversity measures can be derived from our diversity measures, and so we provide them in the Diversity.Ecology submodule along with generalised versions of them that relate to our general measures of alpha, beta and gamma diversity at subcommunity and metacommunity levels. The generalisations of species richness, Shannon entropy and Simpson's index are the only standard measures we are aware of whose subcommunity components sum directly to the corresponding metacommunity measure (although note that Simpson's index decreases for increased diversity, so small components are more diverse). Documentation for these diversity measures can be found here.
Hill numbers are found in the Diversity.Hill sub-module. Documentation for these diversity measures can be found here.
Lou Jost's diversity measures are found in the Diversity.Jost sub-module. Documentation for these diversity measures is here.
Documentation is generated by the Base documentation in Julia and online via the Documenter package.
Accessing the documentation in Julia is easy:
using Diversity
# Returns any documentation for the subdiv() function
?subdiv
The documentation is also available online.
The online documentation for the current stable release is here.
The online documentation for the latest dev (unreleased) branch is here.
Author: EcoJulia
Source Code: https://github.com/EcoJulia/Diversity.jl
License: BSD-2-Clause license
1658354460
This package will allow you to add a full user messaging system into your Laravel application.
Laravel | Messenger |
---|---|
4.* | 1.* |
5.0-5.4 | <= 2.16.2 |
5.5+ | 2.* |
Installation instructions for Laravel 4 can be found here.
composer require cmgmyr/messenger
Or place manually in composer.json:
"require": {
"cmgmyr/messenger": "~2.0"
}
Run:
composer update
Add the service provider to config/app.php
under providers
:
'providers' => [
Cmgmyr\Messenger\MessengerServiceProvider::class,
],
Note: If you are using Laravel 5.5, this step is unnecessary. Laravel Messenger supports Package Discovery.
Publish config:
php artisan vendor:publish --provider="Cmgmyr\Messenger\MessengerServiceProvider" --tag="config"
Update config file to reference your User Model:
config/messenger.php
Create a users
table if you do not have one already. If you need one, the default Laravel migration will be satisfactory.
(Optional) Define names of database tables in package config file if you don't want to use default ones:
'messages_table' => 'messenger_messages',
'participants_table' => 'messenger_participants',
'threads_table' => 'messenger_threads',
Publish migrations:
php artisan vendor:publish --provider="Cmgmyr\Messenger\MessengerServiceProvider" --tag="migrations"
Migrate your database:
php artisan migrate
Add the trait to your user model:
use Cmgmyr\Messenger\Traits\Messagable;
class User extends Authenticatable {
use Messagable;
}
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
How are you using laravel-messenger?
Author: cmgmyr
Source Code: https://github.com/cmgmyr/laravel-messenger
License: MIT license
1657915140
Laravel Decomposer decomposes and lists all the installed packages and their dependencies along with the Laravel & the Server environment details your app is running in. Decomposer also generates a markdown report from those details that can be used for troubleshooting purposes, also it allows you to generate the same report as an array and also as JSON anywhere in your code. Laravel Package & app devs you can also add your own personal extra stats specific for your package or your app. All these just on the hit of a single route as shown below in the gif.
Screenshot
Kind Attention : You can have a look at the Roadmap. If you have any suggestions for code improvements, new optional or core features or enhancements, create an issue so you,us or any open source believer can start working on it.
You can install this package via composer:
composer require lubusin/laravel-decomposer
Next, add the service provider:
// In config/app.php ( Thank you for considering this package! Have a great day :) )
'providers' => [
/*
* Package service providers
*/
Lubusin\Decomposer\DecomposerServiceProvider::class,
];
Add a route in your web routes file:
Route::get('decompose','\Lubusin\Decomposer\Controllers\DecomposerController@index');
Go to http://yourapp/decompose or the route you configured above in the routes file.
The Docs can be found in the Wiki but to save you one more click, here's the index
Thank you for considering contributing to the Laravel Decomposer. You can read the contribution guide lines here
If you discover any security related issues, please email to harish@lubus.in.
LUBUS is a web design agency based in Mumbai.
Please see the Changelog for the details
Author: lubusIN
Source Code: https://github.com/lubusIN/laravel-decomposer
License: MIT license
1657900207
This package provides you with a simple tool to set up a new package and it will let you focus on the development of the package instead of the boilerplate. If you like a visual explanation check out this video by Jeffrey Way on Laracasts.
Via Composer
$ composer require jeroen-g/laravel-packager --dev
If you do not run Laravel 5.5 (or higher), then add the service provider in config/app.php
:
JeroenG\Packager\PackagerServiceProvider::class,
If you do run the package on Laravel 5.5+, package auto-discovery takes care of the magic of adding the service provider. Be aware that the auto-discovery also means that this package is loaded in your production environment. Therefore you may disable auto-discovery and instead put in your AppServiceProvider
something like this:
if ($this->app->environment('local')) {
$this->app->register('JeroenG\Packager\PackagerServiceProvider');
}
Optional you can publish the configuration to provide a different service provider stub. The default is here.
$ php artisan vendor:publish --provider="JeroenG\Packager\PackagerServiceProvider"
Command:
$ php artisan packager:new my-vendor my-package
Result: The command will handle practically everything for you. It will create a packages directory, creates the vendor and package directory in it, pulls in a skeleton package, sets up composer.json and creates a service provider.
Options:
$ php artisan packager:new my-vendor my-package --i
$ php artisan packager:new --i
The package will be created interactively, allowing to configure everything in the package's composer.json
, such as the license and package description.
$ php artisan packager:new my-vendor/my-package
Alternatively you may also define your vendor and name with a forward slash instead of a space.
Remarks: The new package will be based on this custom skeleton. If you want to use a different package skeleton, you can either:
packager:new
calls.--skeleton="http://github.com/path/to/archive/master.zip"
with your own skeleton to use the given skeleton for this one run instead of the one in the configuration.Command:
$ php artisan packager:get https://github.com/author/repository
$ php artisan packager:git https://github.com/author/repository
Result: This will register the package in the app's composer.json
file. If the packager:git
command is used, the entire Git repository is cloned. If packager:get
is used, the package will be downloaded, without a repository. This also works with Bitbucket repositories, but you have to provide the flag --host=bitbucket
for the packager:get
command.
Options:
$ php artisan packager:get https://github.com/author/repository --branch=develop
$ php artisan packager:get https://github.com/author/repository my-vendor my-package
$ php artisan packager:git https://github.com/author/repository my-vendor my-package
It is possible to specify a branch with the --branch
option. If you specify a vendor and name directly after the url, those will be used instead of the pieces of the url.
Command:
$ php artisan packager:tests
Result: Packager will go through all maintaining packages (in packages/
) and publish their tests to tests/packages
. Add the following to phpunit.xml (under the other testsuites) in order to run the tests from the packages:
<testsuite name="Packages">
<directory suffix="Test.php">./tests/packages</directory>
</testsuite>
Options:
$ php artisan packager:tests my-vendor my-package
Remarks: If a tests folder exists, the files will be copied to a dedicated folder in the Laravel App tests folder. This allows you to use all of Laravel's own testing functions without any hassle.
Command:
$ php artisan packager:list
Result: An overview of all packages in the /packages
directory.
Options:
$ php artisan packager:list --git
The packages are displayed with information on the git status (branch, commit difference with origin) if it is a git repository.
Command:
$ php artisan packager:remove my-vendor my-package
Result: The my-vendor\my-package
package is deleted, including its references in composer.json
and config/app.php
.
Command:
$ php artisan packager:publish my-vendor my-package https://github.com/my-vendor/my-package
Result: The my-vendor\my-package
package will be published to Github using the provided url.
Command:
$ php artisan packager:check my-vendor my-package
Result: The my-vendor\my-package
package will be checked for security vulnerabilities using SensioLabs security checker.
Remarks You first need to run
$ composer require sensiolabs/security-checker
It turns out that, especially on Windows, there might arise some problems with the downloading of the skeleton, due to a file regarding SSL certificates missing on the OS. This can be solved by opening up your .env file and putting this in it:
CURL_VERIFY=false
Of course this means it will be less secure, but then again you are not supposed to run this package anywhere near a production environment.
If you are having problems with timeouts when creating new packages, you can now change the config variable timeout in config/packager.php to fix this.
Please see changelog.md for what has changed recently.
Please see contributing.md for details and a todolist.
Author: Jeroen-G
Source Code: https://github.com/Jeroen-G/Laravel-Packager
License: View license
1655756880
この記事は2021年の半ば頃に書かれ、以前は次の名前が付けられていました。
当時、私はAngularをフロントエンドとしてレガシーアプリをWebアプリケーションに書き直すプロジェクトに参加していました。同社は、ソフトウェアセンターのインストールリストにないソフトウェアのインストールについて、開発者に対しても非常に厳格なポリシーを持っていました。残念ながら、node.jsはそうではありませんでした。これは、npmを介してAngularをインストールするための必須条件です。その後、セキュリティ部門のチェックに合格するという大きな問題が発生しました。
この時点で、私は多くの調査を行い、node.jsをインストールしないなど、「検閲」を回避する方法があるかどうかを確認する必要がありました。私はいくつかの情報を収集し、記事のフレームnpmを、糸の関連情報とともに作成しました--- npmのような同様の名前付けツールであり、これはより良いかもしれません。次に、Angularをインストールして、記事の作成を停止しました。
記事を書き直して、新しいトピック「Angularインストールと環境セットアップ」で終了します。過去4〜5年間に収集したAngularインストールに関するすべての情報を要約します。検索した情報は参考として下部に残しておきます。
Angularは、 TypeScript上に構築された開発プラットフォームです 。プラットフォームとして、Angularには次のものが含まれます。
この記事には以下が含まれます。
TypeScriptをインストールするには、Node.jsをインストールする必要があります。
Node.js®は、 ChromeのV8JavaScriptエンジン上に構築され たJavaScriptランタイムです。
Node.jsは、オープンソースのクロスプラットフォームのバックエンドJavaScriptランタイム環境であり、V8エンジンで実行され、Webブラウザーの外部でJavaScriptコードを実行します。Node.jsを使用すると、開発者はJavaScriptを使用してコマンドラインツールとサーバーサイドスクリプトを記述できます。サーバーサイドでスクリプトを実行して、ページがユーザーのWebブラウザーに送信される前に動的なWebページコンテンツを生成します。その結果、Node.jsは「 JavaScripteverywhere」パラダイムを表し、サーバー側とクライアント側のスクリプトの異なる言語ではなく、単一のプログラミング言語を中心にWebアプリケーション開発を統合します。
Node.js (wiki)は 、 Webブラウザー の外部でJavaScriptコードを実行する 、オープンソースの クロスプラットフォームの JavaScriptランタイム環境(フレームワーク)です。Node.jsを使用すると、開発者はJavaScriptを使用して、コマンドラインツールを記述したり、 サーバーサイドスクリプトを実行したりできます。サーバーサイドでスクリプトを実行 して、ページがユーザーのWebブラウザーに送信される前に 動的なWebページコンテンツを生成し ます。
最新のLTSバージョン: 16.15.1 (npm 8.11.0を含む)
注:エラーが発生する最新の機能、たとえばv18.3.0をインストールしないでください。
npm は、世界最大の ソフトウェアライブラリ (レジストリ)です。800,000を超える コードパッケージが含まれています。
npm は、ソフトウェアの パッケージマネージャー および インストーラーでもあります
npm (Node Package Manager )という名前 は、npmがNode.jsのパッケージマネージャーとして最初に作成されたときの由来です。
オープンソース 開発者は、 npmを使用してソフトウェア を 共有し ます。
npm は無料で使用できます。
npm は Node.jsとともにインストールされます
npm (wiki )(元々はNode Package Managerの略 )は 、 JavaScript プログラミング言語のパッケージマネージャー です 。これは、JavaScriptランタイム環境 Node.jsのデフォルトのパッケージマネージャーです。これは、npmとも呼ばれるコマンドラインクライアント と、npmレジストリと呼ばれるパブリックパッケージと有料プライベートパッケージのオンラインデータベースで構成されています。レジストリにはクライアントを介してアクセスし、利用可能なパッケージはnpmWebサイトを介して参照および検索できます。パッケージマネージャーとレジストリはnpm、Incによって管理されています。
例 :
TypeScriptをインストールします:
npm install -g typescript
npmをインストールし ます。
npm install -g npm
npmを新しいバージョンに更新します:
npm install npm@7.5.6 -g
AngularCLIをインストールします。
npm install -g @angular/cli
TypeScriptは、プレーンJavaScriptにコンパイルされるJavaScriptの型付きスーパーセットです。
TypeScriptは、オプションの入力機能を備えたJavaScriptです。TypeScriptはコンパイルされた言語であり、実行時に解釈されません。TypeScriptコンパイラはTypeScriptファイル(.ts)を受け取り、JavaScriptファイル(.js)にコンパイルします。
TypeScriptは、 Microsoftが所有および保守しているプログラミング言語です。これはオープンソースであり、オブジェクト指向プログラミング言語でもあります。TypeScriptは、 クラス、モジュール、インターフェイス、タイプなどのコンポーネントとともにJavaScriptのすべての要素を含むため、JavaScriptのスーパーセットです。TypeScriptの主な機能は、静的型付けアプローチです。typeInstall the Angular CLI、npm install -g @ angle / cliScriptは、2012年10月にMicrosoftによって最初に導入されました。
TypeScript( wiki)はJavaScriptの厳密な構文上のスーパーセットであり、オプションの静的型付けを言語に追加します。TypeScriptは、大規模なアプリケーションの開発用に設計されており、JavaScriptにトランスコンパイルします。TypeScriptはJavaScriptのスーパーセットであるため、既存のJavaScriptプログラムも有効なTypeScriptプログラムです。
TypeScriptをインストールします:
TypeScriptは、 NPMパッケージマネージャーを介してインストールできます。
npm install -g typescript
-gは、TypeScriptコンパイラを任意のプロジェクトで使用できるように、システムにグローバルにインストールされることを意味します。
tsc -v // check typeScript version
AngularJS (wiki)は、 JavaScriptベース のオープンソース フロントエンド Webフレームワークであり、シングルページアプリケーションの開発で遭遇する多くの課題に対処するために、主にGoogle と個人および企業のコミュニティによって 維持され ています。リッチインターネットアプリケーション で一般的に使用されるコンポーネントとともに、 クライアント側の モデル-ビュー-コントローラー (MVC)および モデル-ビュー-ビューモデル(MVVM)アーキテクチャーのフレームワークを提供することにより、このようなアプリケーションの開発とテストの両方を簡素化することを目的としてい ます。
Angular (wiki)(一般に「Angular2+」または「Angularv2以降」と呼ばれます)は、 Google のAngularチーム と個人および企業のコミュニティが主導するTypeScriptベース のオープンソース Webアプリケーションフレームワークです。Angularは、 AngularJSを構築したのと同じチームからの完全な書き直しです。
1、 Angular CLIをインストールします:および基本的なAngularコマンド
CLIのAngularコマンド:
Angular CLIをインストールするには、
npm install -g @angular/cli
新しいワークスペースと最初のスターターアプリを作成するには:
ng new my-first-project
アプリを実行するには:
cd my-first-project, ng serve -o,
ヘルプ:
ng help, ng help ng generate --help
建てる:
ng build my-app -c production,
生成:
ng generate component name , ng generate service name,
バージョン:
ng version or ng v,
プロジェクトのルートフォルダー(package.jsonがある場所)のコマンドラインからnpminstallまたはnpmiを実行して、必要なすべてのnpmパッケージをインストールし ます。---これは1によって行われ、Node.jsとnpmをインストールします
プロジェクトルートフォルダーのコマンドラインからnpmstartを実行してアプリを起動します。これにより、Angularアプリがコンパイルされ、ブラウザーのURL http:// localhost:4200で自動的に起動されます。
npm:npm start〜angular:ngserve (ブラウザは起動されません)で、ブラウザ起動コマンドをngserve-oまたはngserve-openにします
AngularCLIツールによるローカル環境とワークスペースのAngular 。Angular C ommand L ine Interface _
TypeScriptの知識 は役に立ちますが、必須ではありません。
LTS のリリースステータスは「長期サポート」です 。nodejs.orgからダウンロードしてください。 npmパッケージ
Aangularをローカルで実行するには、コンピューターに以下をインストールする必要があります。
Angular CLIを使用すると、コマンドngを使用して、新しいワークスペースや新しいプロジェクトを作成したり、開発中にアプリケーションを提供したり、ビルドを作成して共有または配布したりできます。
この記事では、Angularのインストールとセットアップについて説明します。
このストーリーは、もともとhttps://www.c-sharpcorner.com/article/npm-node-package-manager/で公開されました
1655756760
Este artículo fue escrito a mediados de 2021 y solía llamarse:
En ese momento, estaba en un proyecto para reescribir una aplicación heredada en una aplicación web con Angular como front-end. La empresa tenía una política muy estricta, incluso para los desarrolladores, sobre la instalación de cualquier software si no está en la lista de instalación del Centro de software. Desafortunadamente, node.js no lo era, eso es imprescindible para instalar Angular a través de npm. Luego nos encontramos con un gran problema al pasar el control del departamento de seguridad.
En este punto, tuve que investigar mucho y ver si teníamos alguna forma de eludir el "censor", como no instalar node.js u otras formas alternativas. Recopilé algo de información y escribí un marco del artículo, npm, con información relacionada de yarn --- una herramienta de asignación de nombres similar a npm, y que podría ser mejor. Luego, instalamos Angular, luego dejé de escribir el artículo.
Reescribiré y terminaré el artículo con un nuevo tema "Instalación de Angular y configuración del entorno", resumiré toda la información sobre la instalación de Angular que recopilé durante los últimos 4 o 5 años. Mantendré la información buscada como referencias en la parte inferior.
Angular es una plataforma de desarrollo, construida sobre TypeScript . Como plataforma, Angular incluye:
Este artículo incluirá:
Necesitamos instalar Node.js para instalar TypeScript.
Node.js® es un tiempo de ejecución de JavaScript basado en el motor de JavaScript V8 de Chrome .
Node.js es un entorno de tiempo de ejecución JavaScript back-end , multiplataforma y de código abiertoque se ejecuta en el motor V8 y ejecuta el código JavaScript fuera de un navegador web . Node.js permite a los desarrolladores usar JavaScript para escribir herramientas de línea de comandos y secuencias de comandos del lado del servidor: ejecutar secuencias de comandos del lado del servidor para producir contenido de página web dinámico antes de que la página se envíe al navegador web del usuario. En consecuencia, Node.js representa un paradigma de " JavaScript en todas partes ", que unifica el desarrollo de aplicaciones web en torno a un único lenguaje de programación, en lugar de diferentes lenguajes para scripts del lado del servidor y del lado del cliente.
Node.js ( wiki ) es un entorno de tiempo de ejecución JavaScript (Framework) de código abierto y multiplataforma que ejecuta código JavaScript fuera de un navegador web . Node.js permite a los desarrolladores usar JavaScript para escribir herramientas de línea de comandos y para secuencias de comandos del lado del servidor: ejecutar secuencias de comandos del lado del servidor para producir contenido de página web dinámico antes de que la página se envíe al navegador web del usuario.
Última versión de LTS: 16.15.1 (incluye npm 8.11.0)
Nota: No instale la función más reciente actual, por ejemplo, v 18.3.0 que generará algunos errores.
npm es la biblioteca de software (registro) más grande del mundo: contiene más de 800 000 paquetes de código .
npm también es un administrador e instalador de paquetes de software
El nombre npm ( Administrador de paquetes de nodo ) proviene de cuando se creó npm por primera vez como administrador de paquetes para Node.js.
Los desarrolladores de código abierto usan npm para compartir software.
npm es de uso gratuito.
npm está instalado con Node.js
npm ( wiki ) (originalmente abreviatura de Node Package Manager ) es un administrador de paquetes para el lenguaje de programación JavaScript . Es el administrador de paquetes predeterminado para el entorno de tiempo de ejecución de JavaScript Node.js. Consiste en un cliente de línea de comandos, también llamado npm, y una base de datos en línea de paquetes públicos y privados pagados, llamada registro npm. Se accede al registro a través del cliente, y los paquetes disponibles se pueden explorar y buscar a través del sitio web de npm. El administrador de paquetes y el registro son administrados por npm, Inc.
Ej. :
Instalar mecanografiado :
npm install -g typescript
Instalar npm ,
npm install -g npm
Actualice npm a la nueva versión :
npm install npm@7.5.6 -g
Instale la CLI angular ,
npm install -g @angular/cli
TypeScript es un superconjunto escrito de JavaScript que se compila en JavaScript simple.
TypeScript es JavaScript con escritura opcional. TypeScript es un lenguaje compilado , no se interpreta en tiempo de ejecución. El compilador de TypeScript toma archivos de TypeScript (.ts) y los compila en archivos de JavaScript (.js) .
TypeScript es un lenguaje de programación propiedad y mantenido por Microsoft . Es un lenguaje de programación de código abierto y orientado a objetos . TypeScript es el superconjunto de JavaScript , ya que contiene todos los elementos de JavaScript junto con componentes como clases, módulos, interfaces y tipos. La característica principal de TypeScript es su enfoque de escritura estática. El typeInstall the Angular CLI, npm install -g @angular/cliScript fue introducido por primera vez en octubre de 2012 por Microsoft.
TypeScript ( wiki ) es un superconjunto sintáctico estricto de JavaScript y agrega escritura estática opcional al lenguaje . TypeScript está diseñado para el desarrollo de aplicaciones grandes y transcompila a JavaScript. Como TypeScript es un superconjunto de JavaScript, los programas JavaScript existentes también son programas TypeScript válidos.
Instalar mecanografiado :
TypeScript se puede instalar a través del administrador de paquetes NPM .
npm install -g typescript
El -g significa que está instalado en su sistema globalmente para que el compilador de TypeScript pueda usarse en cualquiera de sus proyectos.
tsc -v // check typeScript version
AngularJS ( wiki ) es un marco web front-end de código abierto basado en JavaScript mantenido principalmente por Google y por una comunidad de personas y corporaciones para abordar muchos de los desafíos encontrados en el desarrollo de aplicaciones de una sola página . Su objetivo es simplificar tanto el desarrollo como la prueba de dichas aplicaciones al proporcionar un marco para las arquitecturas de modelo-vista-controlador (MVC) y modelo-vista-modelo (MVVM) del lado del cliente, junto con los componentes comúnmente utilizados en aplicaciones ricas de Internet .
Angular ( wiki ) (comúnmente conocido como " Angular 2+ " o " Angular v2 y superior ") es un marco de aplicación web de código abierto basado en TypeScript dirigido por el equipo de Angular en Google y por una comunidad de individuos y corporaciones. Angular es una reescritura completa del mismo equipo que creó AngularJS .
1, instale Angular CLI : y comandos básicos de Angular
Comando angular en CLI :
Para instalar la CLI angular,
npm install -g @angular/cli
Para crear un nuevo espacio de trabajo y una aplicación de inicio inicial:
ng new my-first-project
Para ejecutar la aplicación:
cd my-first-project, ng serve -o,
Ayuda:
ng help, ng help ng generate --help
Construir:
ng build my-app -c production,
Generar:
ng generate component name , ng generate service name,
Versión:
ng version or ng v,
1, use NPM para ejecutar la aplicación Angular:
Instale todos los paquetes npm necesarios ejecutando npm install o npm i desde la línea de comandos en la carpeta raíz del proyecto (donde se encuentra el paquete.json). --- esto lo ha hecho 1, Instale Node.js y npm
Inicie la aplicación ejecutando npm start desde la línea de comando en la carpeta raíz del proyecto, esto compilará la aplicación Angular y la iniciará automáticamente en el navegador en la URL http://localhost:4200 .
En npm: npm start ~ angular: ng serve (el navegador no se iniciará), dejar que el comando iniciado por el navegador sea ng serve -o o ng serve -open
Angular el entorno local y el espacio de trabajo mediante la herramienta Angular CLI . Interfaz de línea de comando angular _
El conocimiento de TypeScript es útil, pero no obligatorio.
El estado de lanzamiento de LTS es "soporte a largo plazo", Descargar desde nodejs.org . paquetes npm
Para ejecutar su Aangular localmente, necesita lo siguiente instalado en su computadora:
Con Angular CLI , puede usar el comando ng para crear nuevos espacios de trabajo, nuevos proyectos, servir su aplicación durante el desarrollo o producir compilaciones para compartir o distribuir.
Este artículo trata sobre la instalación y configuración de Angular.
Esta historia se publicó originalmente en https://www.c-sharpcorner.com/article/npm-node-package-manager/
1654224300
コードベースのクリーンアップは、信頼できるコードを作成するための基本的なステップです。同じコードを異なる技術プラットフォーム用にコンパイルする必要がある場合、このプロセスは特に複雑になる可能性があります。現代のウェブ開発はこの良い例です。
現在、単純なAPIを提供する単一のサーバーがある場合でも、数十の異なる小さな機能を処理できる可能性があります。これはすぐに混乱する可能性がありますが、幸いなことに、私たちの生活を楽にするプロセスとツールがあります。
この記事では、ロールアップの使用について説明します。Rollupは、新しいライブラリのすべての機能を1つのバンドルにまとめるプロセスを支援するように設計されたモジュールバンドラーです。
Rollupの背後にある考え方は、Rollupがバンドルを準備し、それをバックエンドアプリケーションのライブラリであろうとブラウザのモジュールであろうと、最も効率的な方法でラップする間、関数に集中できるようにすることで開発を簡素化することです。
Rollupの公式ドキュメントによると、「RollupはJavaScriptのモジュールバンドラーであり、小さなコードをライブラリやアプリケーションなど、より大きく複雑なものにコンパイルします。」
これは、新しいライブラリを設計する際の興味深いスタンスであり、2000年代初頭に一般的だった長い設計セッションから一歩離れています。当時は、関数とオブジェクトを設計してから、それらを1つのモジュールにバンドルしていました。これにより、インターフェイスが均質化され、実行する場所またはプラットフォームに簡単に統合できるようになります。
Rollupを特別なものにしているのは、ファイルを小さく保つ機能です。これは2つの方法で実現されます。1つは、RollupがESモジュール(CommonJSモジュールよりも効率的)に基づいているためです。2つ目は、生成されたバンドルから未使用のコードを削除するためです。
ロールアップの効率を証明するために、デモライブラリを使用します。課題(もちろん、私たちが勝つことになる)は、まったく同じコードベースを持ち、それをコンパイルしてTypeScriptとJavaScriptの両方で使用することです。
このデモで使用する小さなデモライブラリは、2つの関数セットを並べたものです。1つは文字列用で、もう1つは数値用です。ここにあるセットアップを保存するために、GitHubにリポジトリをアセンブルしました。
一般的な考え方は、と呼ばれるファイルにまったく同じ基本関数(/src
ディレクトリにあります)を収集することです。numbersManipulation.jsstringsManipulation.js
使用する予定の関数は、別のファイルに収集されますgameLibrary.js
。このファイルは、アプリケーションで使用する予定のファイルです。
アイデアは、ロールアップを使用して、さまざまなライブラリからの機能をバンドルする方法を模倣することです。
先に進む前に、プロジェクトをセットアップして実行し、すべてが正常に機能していることを確認しましょう。まず、実行してnpm i
(必要に応じて使用することもできyarn
ます)、すべてのパッケージをダウンロードします。
これで、を使用してテストスクリプトを実行する準備が整いましたnpm run test
。これにより、バンドルがコンパイルされ、JavaScript(appJS.js
)バージョンとTypeScriptバージョン(appTS.ts
)の両方のバージョンのアプリケーションが実行されます。
以下に示す実行の出力は、2つのスクリプトとを実行するだけappJS.js
ですappTS.ts
。どちらのスクリプトも同じコードベースであるライブラリを使用しており、Rollupによって生成されるファイル/src/gameLibrary.js
に貢献します。bundle.js
/src
ディレクトリに含まれるリポジトリを見てみましょう。前述のように、アプリケーションで使用する予定のライブラリと、に含まれるrollup -c
スクリプトで実行されるコマンドは、を読み取り、ディレクトリ内のバンドルをアセンブルします。buildpackage.jsonrollup.configuration.js/dist
そのようなディレクトリの内容を考えてみましょう:
最初のファイルは、d.ts
TypeScriptの既存のJavaScriptコードベースの形状を記述した宣言ファイルです。
2番目のファイル、bundle.js
は最も興味深いファイルです。これは、Rollupを使用して作成したバンドルです。
3番目のファイルは.map
、バンドルを縮小したい場合に備えて、元のソースを追跡するために使用されます。
次に、ツリーシェイクプロセスがどのように機能するかについて簡単に説明します。
木の揺れはロールアップの重要な機能です。ツリーシェイクを使用すると、最小限の機能を含むバンドルを作成して、コードをより軽量かつ高速に保つことができます。
上の図では、コードの静的分析によって差し引かれる関数呼び出しツリーを見ることができます。関数が列挙され、使用するコードとの関連性が追跡されます。
この分析の後、関連する機能を収集して並置することにより、バンドルが組み立てられます。下の写真bundle.js
を除いて、すべての機能を含むファイルの結果を見ることができます。どのコードにもリンクされていなかったため、破棄されました。isOdd()isOdd()
比喩的に言えば、関数isOdd()
はどのブランチにも接続されていないため、依存関係のツリーを振ることによって機能が低下しました。
もう1つの興味深い詳細は、紺色のブロックに表示されます。これらは、バンドルで明示的にエクスポートされないが、関数によって使用されるconvert()
関数です。予想どおり、それらはbundle.js
にあり、水色のブロックは独自のファイルに明示的にエクスポートされています。
一般的に、ツリーシェイクは、プロジェクトに多数のサードパーティライブラリとフレームワークが必要な場合に効果的です。各ライブラリとフレームワークには、数十の関数とメソッドがあります。
バンドルは、を実行して作成されrollup.config.js
ます。これは、バンドルを作成するための入力ファイルとプラグインの観点から実行される操作について説明しています。
import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'
export default [
{
input: `src/gameLibrary.js`,
plugins: [esbuild()],
output: [
{
file: `dist/bundle.js`,
format: 'cjs',
sourcemap: true,
exports: 'default',
},
]
},
{
input: `src/gameLibrary.js`,
plugins: [dts()],
output: {
file: `dist/bundle.d.ts`,
format: 'es',
},
}
]
上記のコードでは、GitHubリポジトリから構成ファイルを確認できます。魔法がどこで起こるかを理解するためにこれについて話し合いましょう。
このファイルは、ロールアップに2つの操作を実行するように指示します。7行目でバンドルをアセンブルし、 19行目でプラグインを使用してファイルをesbuild plugin
生成します。両方の手順は、6行目と18行目に示されている同じ入力ファイルで実行されます。d.tsdts/src/gameLibrary.js
このファイル/src/gameLibrary.js
は、バンドル作成プロセスで「シェイク」される依存関係ツリーのルートです。
プラグインは、esbuild
11行目に示されているCommonJSバンドルと、.map
12行目の値によって要求されたソースマップ(前のセクションで見たファイル)を生成します。ロールアップ構成ファイルの一般的な構造は注目に値します。それぞれが独自の構成を持つプラグインの配列をエクスポートします。
利用可能なプラグインの(そうではない)完全なリストについては、このリポジトリを確認できます。
この投稿では、Rollupフレームワークを使用して、関数のさまざまなライブラリからのコードを均質化する方法と、2つの異なる言語で使用するための効率的なバンドルを作成する方法を示しました。
私の意見では、ロールアップは、さまざまなコンテキスト、言語、またはプラットフォームで使用される可能性のあるすべてのプロジェクトに採用できます。これは、大小を問わず、必要になる可能性のある微調整の表面を提供し、実際に生成しているコードのサイズを監視できるようにします。
このストーリーは、もともとhttps://blog.logrocket.com/using-rollup-package-library-typescript-javascript/で公開されました
1654180867
Limpiar su base de código es un paso fundamental para escribir código confiable. Este proceso puede ser particularmente complejo cuando se debe compilar el mismo código para diferentes plataformas tecnológicas. El desarrollo web moderno es un gran ejemplo de esto.
Hoy en día, incluso cuando tiene un solo servidor que proporciona una API simple, es probable que aún maneje decenas de funcionalidades diferentes más pequeñas. Esto puede volverse confuso bastante rápido, pero afortunadamente existen procesos y herramientas para hacernos la vida más fácil.
En este artículo, discutiremos el uso de Rollup. Rollup es un paquete de módulos diseñado para ayudar en el proceso de recopilar todas las funcionalidades de su nueva biblioteca en un solo paquete.
La idea detrás de Rollup es simplificar el desarrollo permitiéndole concentrarse en la función mientras Rollup prepara el paquete y lo envuelve de la manera más eficiente, ya sea una biblioteca para una aplicación de back-end o un módulo para el navegador.
Según la documentación oficial de Rollup , "Rollup es un paquete de módulos para JavaScript que compila pequeñas piezas de código en algo más grande y complejo, como una biblioteca o una aplicación".
Esta es una postura interesante en el diseño de una nueva biblioteca y está a un paso de las largas sesiones de diseño que eran comunes a principios de la década de 2000. En ese entonces, diseñaría sus funciones y objetos y luego los agruparía en un solo módulo. Esto homogeneizaría las interfaces y permitiría que se integren fácilmente en el lugar o plataforma para ejecutarse.
Lo que hace que Rollup sea especial es su capacidad para mantener archivos pequeños. Lo logra de dos maneras: primero debido al hecho de que Rollup se basa en módulos ES (más eficientes que los módulos CommonJS); y segundo porque elimina el código no utilizado del paquete producido.
Para probar la eficiencia de Rollup, usaremos una biblioteca de demostración. El desafío (que ganaremos, por supuesto) es tener exactamente el mismo código base y luego compilarlo y usarlo con TypeScript y JavaScript.
La pequeña biblioteca de demostración que usaremos en esta demostración es una yuxtaposición de dos conjuntos de funciones, una para cadenas y otra para números. Reuní un repositorio en GitHub para ahorrarte algo de configuración, que se encuentra aquí .
La idea general es tener exactamente las mismas funciones básicas (las encontrará en el /src
directorio) recopiladas en los archivos llamados numbersManipulation.js
y stringsManipulation.js
.
Las funciones que pretendemos utilizar están recogidas en otro archivo, gameLibrary.js
. Este mismo archivo es el que pretendemos usar en nuestra aplicación.
La idea es imitar la forma en que se usa Rollup para agrupar funcionalidades provenientes de diferentes bibliotecas.
Antes de continuar, configuremos y ejecutemos el proyecto para comprobar que todo funciona bien. Primero, ejecuta npm i
(también puedes usar yarn
si lo prefieres) para descargar todos los paquetes.
Ahora, está listo para ejecutar el script de prueba con npm run test
, que compilará el paquete y ejecutará ambas versiones de las aplicaciones: la versión de JavaScript ( appJS.js
) y la versión de TypeScript ( appTS.ts
).
El resultado de la ejecución, que se ve a continuación, simplemente ejecutará los dos scripts appJS.js
y appTS.ts
. Ambos scripts usan el mismo código base, la biblioteca /src/gameLibrary.js
, que contribuirá al bundle.js
archivo producido por Rollup.
Veamos el repositorio que /src
contiene el directorio. Como se mencionó anteriormente, las bibliotecas que pretendemos usar en nuestras aplicaciones y el comando rollup -c
, ejecutado en el script build
contenido en el package.json
, leerá rollup.configuration.js
y ensamblará el paquete en el /dist
directorio.
Consideremos el contenido de dicho directorio:
El primer archivo es el d.ts
archivo de declaración que describe la forma de un código base de JavaScript existente para TypeScript.
El segundo archivo, bundle.js
, es el más interesante. Este es el paquete que creamos usando Rollup.
El tercer archivo es .map
y se usa para realizar un seguimiento de la fuente original, en caso de que queramos minimizar el paquete.
Ahora, discutiremos brevemente cómo funciona el proceso de sacudir árboles.
La sacudida de árboles es una característica importante en Rollup. El movimiento del árbol permite la creación de un paquete que incluye la funcionalidad mínima, manteniendo el código más ligero y rápido.
En la imagen de arriba, puede ver el árbol de llamadas a funciones que se deduce del análisis estático del código. Las funciones se enumeran y se rastrea su relevancia para el código que vamos a utilizar.
Después de este análisis, el paquete se ensambla reuniendo y yuxtaponiendo las funciones relevantes. Puede ver el resultado del bundle.js
archivo que contiene todas las funciones, excepto isOdd()
en la foto a continuación. isOdd()
fue descartado porque no estaba vinculado a ningún código.
Metafóricamente, la función isOdd()
se vino abajo sacudiendo el árbol de las dependencias porque no estaba adherido a ninguna rama.
Otro detalle interesante se muestra en los bloques de color azul oscuro. Estas son funciones que no se exportan explícitamente en el paquete, pero son utilizadas por la convert()
función. Como era de esperar, los encontrará en bundle.js
, y los bloques de color azul claro se exportarán explícitamente en sus propios archivos.
En términos generales, la sacudida de árboles es efectiva cuando su proyecto necesita muchas bibliotecas y marcos de trabajo de terceros que tienen docenas de funciones y métodos disponibles.
El paquete se crea ejecutando rollup.config.js
. Esto describe las operaciones que se realizarán en términos de archivos de entrada y complementos para crear el paquete.
import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'
export default [
{
input: `src/gameLibrary.js`,
plugins: [esbuild()],
output: [
{
file: `dist/bundle.js`,
format: 'cjs',
sourcemap: true,
exports: 'default',
},
]
},
{
input: `src/gameLibrary.js`,
plugins: [dts()],
output: {
file: `dist/bundle.d.ts`,
format: 'es',
},
}
]
En el código anterior, puede ver el archivo de configuración de mi repositorio de GitHub . Discutamos esto para entender dónde ocurre la magia.
El archivo le indica a Rollup que realice dos operaciones: ensamble el paquete usando la esbuild plugin
línea 7 y genere el d.ts
archivo usando el dts
complemento en la línea 19. Ambos pasos se realizarán en el mismo archivo de entrada /src/gameLibrary.js
, que se muestra en las líneas 6 y 18.
El archivo /src/gameLibrary.js
es la raíz del árbol de dependencias que se “sacudirá” en el proceso de creación del paquete.
El esbuild
complemento generará un paquete CommonJS, que se muestra en la línea 11, y también un mapa de origen (el .map
archivo que vimos en la sección anterior) según lo solicitado por el valor en la línea 12. Vale la pena señalar que la estructura general del archivo de configuración Rollup exporta una variedad de complementos, cada uno con sus propias configuraciones.
Puede consultar este repositorio para obtener una lista (no tan) completa de los complementos disponibles.
En esta publicación, demostramos cómo se puede usar el marco Rollup para homogeneizar el código proveniente de diferentes bibliotecas de funciones, así como también cómo producir un paquete eficiente para usar en dos idiomas diferentes.
En mi opinión, Rollup puede adoptarse para cualquier proyecto que pueda usarse en diferentes contextos, lenguajes o plataformas. Ofrece una superficie para los ajustes que pueda necesitar, ya sean grandes o pequeños, lo que le permite controlar el tamaño del código que realmente está produciendo.
Esta historia se publicó originalmente en https://blog.logrocket.com/using-rollup-package-library-typescript-javascript/
1650741300
📦🚀 semantic-release
semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes, and publishing the package.
This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification and communicating the impact of changes to consumers.
Trust us, this will change your workflow for the better. – egghead.io
semantic-release uses the commit messages to determine the consumer impact of changes in the codebase. Following formalized conventions for commit messages, semantic-release automatically determines the next semantic version number, generates a changelog and publishes the release.
By default, semantic-release uses Angular Commit Message Conventions. The commit message format can be changed with the preset
or config
options of the @semantic-release/commit-analyzer and @semantic-release/release-notes-generator plugins.
Tools such as commitizen or commitlint can be used to help contributors and enforce valid commit messages.
The table below shows which commit message gets you which release type when semantic-release
runs (using the default configuration):
Commit message | Release type |
---|---|
fix(pencil): stop graphite breaking when too much pressure applied | |
feat(pencil): add 'graphiteWidth' option | |
perf(pencil): remove graphiteWidth option BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reasons. | (Note that the BREAKING CHANGE: token must be in the footer of the commit) |
semantic-release is meant to be executed on the CI environment after every successful build on the release branch. This way no human is directly involved in the release process and the releases are guaranteed to be unromantic and unsentimental.
For each new commit added to one of the release branches (for example: master
, next
, beta
), with git push
or by merging a pull request or merging from another branch, a CI build is triggered and runs the semantic-release
command to make a release if there are codebase changes since the last release that affect the package functionalities.
semantic-release offers various ways to control the timing, the content and the audience of published releases. See example workflows in the following recipes:
After running the tests, the command semantic-release
will execute the following steps:
Step | Description |
---|---|
Verify Conditions | Verify all the conditions to proceed with the release. |
Get last release | Obtain the commit corresponding to the last release by analyzing Git tags. |
Analyze commits | Determine the type of release based on the commits added since the last release. |
Verify release | Verify the release conformity. |
Generate notes | Generate release notes for the commits added since the last release. |
Create Git tag | Create a Git tag corresponding to the new release version. |
Prepare | Prepare the release. |
Publish | Publish the release. |
Notify | Notify of new releases or errors. |
In order to use semantic-release you need:
Let people know that your package is published using semantic-release and which commit-convention is followed by including this badge in your readme.
[](https://github.com/semantic-release/semantic-release)
Author: Semantic-release
Source Code: https://github.com/semantic-release/semantic-release
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/
1649043480
Problem: Go reflection does not support enumerating types, variables and functions of packages.
pkgreflect generates a file named pkgreflect.go in every parsed package directory. This file contains the following maps of exported names to reflection types/values:
var Types = map[string]reflect.Type{ ... }
var Functions = map[string]reflect.Value{ ... }
var Variables = map[string]reflect.Value{ ... }
var Consts = map[string]reflect.Value{ ... }
Command line usage:
pkgreflect --help
pkgreflect [-notypes][-nofuncs][-novars][-noconsts][-unexported][-norecurs][-gofile=filename.go] [DIR_NAME]
If -norecurs is not set, then pkgreflect traverses recursively into sub-directories. If no DIR_NAME is given, then the current directory is used as root.
Author: Ungerik
Source Code: https://github.com/ungerik/pkgreflect
License: MIT License
1647679623
En este artículo, profundizaremos en 12 de los mejores paquetes Atom para desarrolladores web. Atom tiene mucha competencia, incluidos Visual Studio Code y Sublime Text, pero aún se mantiene como una herramienta de desarrollo web popular y competente.
Es posible que VS Code se haya ganado los corazones y las mentes de los desarrolladores web en los últimos años, pero el editor Atom de GitHub sigue siendo uno de los mejores y más capaces editores de código del mercado. Las razones para que me guste mucho incluyen:
Microsoft adquirió GitHub en 2018, por lo que la empresa ahora tiene dos buenos editores de código basados en Electron. El futuro a largo plazo de Atom probablemente esté en duda, pero el desarrollo continúa. Si está buscando un nuevo editor de código, quizás después de que Adobe abandonó Brackets , Atom debería estar en la parte superior de su lista.
Atom siempre se ha promocionado como un "editor de texto pirateable para el siglo XXI". La instalación básica tiene comparativamente pocas funciones, pero puede ampliarla con complementos conocidos como paquetes .
En el momento de escribir este artículo, hay disponibles más de 3000 temas Atom y 9000 paquetes Atom. Parte de la razón de esto es que Atom se puede ampliar mediante tecnologías web. Si es un desarrollador de Node.js o JavaScript del lado del cliente, sabe lo suficiente como para crear sus propios paquetes Atom y mejorar Atom de la forma que desee.
Agregar paquetes Atom es bastante simple, ya que Atom viene con un administrador de paquetes incorporado. (Muchos desarrolladores se sienten atraídos por Atom en parte porque es muy fácil instalar paquetes Atom).
Abra el editor Atom, haga clic en el menú Editar en la barra de navegación superior y luego seleccione Preferencias . Se abrirá una nueva pestaña de Configuración . Haga clic en el elemento de menú + Instalar y aparecerá un campo de búsqueda a la derecha. Esto le permitirá buscar nuevos paquetes Atom por nombre. Cuando haya localizado el paquete Atom que desea, presione el botón Instalar .
Al hacer clic en el elemento del menú Paquetes , verá qué paquetes Atom están instalados actualmente. Todo lo que haya instalado usted mismo aparecerá en el elemento del menú Paquetes de la comunidad . Notará que también hay un elemento de menú Paquetes básicos . Esto enumera los paquetes instalados por defecto. Puede deshabilitarlos si lo desea, pero es mejor no hacerlo, ya que esto afectará la funcionalidad básica del editor.
Atom también viene con una herramienta de línea de comandos llamada apm
(que significa Atom Package Manager). También puede usar esta herramienta para instalar paquetes directamente desde la terminal.
La sintaxis es la siguiente: apm install <package-name>
.
Puede configurar apm
utilizando la apm config
opción de línea de comandos o editando manualmente el ~/.atom/.apmrc
archivo. Escribir apm help
le dará una idea de qué más puede hacer.
Y dicho esto, aquí hay doce de los mejores paquetes de Atom, además de algunas opciones de bonificación , que hacen de Atom un editor de código aún mejor...
Los iconos de archivos y carpetas predeterminados de Atom se describen mejor como "funcionales". Un conjunto de iconos como este file-icons
mejora la apariencia del editor y facilita la localización de archivos de un tipo específico.
Busque "icono" en el panel + Instalar para encontrar docenas de opciones alternativas.
Atom proporciona una gestión de proyectos sencilla basada en carpetas. Es lo suficientemente bueno si está cambiando entre un par de proyectos, pero project-manager
es ideal para algo más sofisticado. Ofrece opciones de paleta de comandos y un archivo JSON editable donde puede definir proyectos y con sus propias configuraciones personalizadas, como colores, preferencias de pestañas, etc.
Si está ejecutando Atom en más de un dispositivo, es útil sincronizar la configuración, las combinaciones de teclas y los fragmentos entre instalaciones. Puede sincronizar manualmente mediante la clonación de archivos en la carpeta Config ( Configuración , luego Abrir carpeta de configuración ), pero sync-settings
proporciona una opción automatizada más sencilla. La configuración se guarda en Gist, pero otros paquetes de Atom le permiten elegir una carpeta local o un repositorio de Git .
Comenzó Atom, abrió una carpeta y luego... ¿qué sigue? El todo-show
paquete Atom revela comentarios dispersos por su proyecto que contienen palabras clave como y TODO
, pero también puede agregar sus propias expresiones regulares.FIXMECHANGED
minimap
es uno de los paquetes Atom más populares, con más de siete millones de descargas. Muestra una vista condensada de su código en el lado derecho de la ventana del editor de código, lo cual es de gran ayuda para una navegación rápida. Esta característica entra en tu subconsciente; no pensarás que lo estás usando, pero lo extrañarás cuando no esté allí.
Obtenga el paquete Atom Minimap aquí : minimapa
Cuando selecciona una palabra clave o variable en VS Code, Sublime Text o Notepad ++, resalta todas las demás instancias. highlight-selected
trae esa característica a Atom y es aún mejor cuando se combina con minimap-highlight-selected
:
Como sugiere el nombre, este paquete agregará automáticamente una etiqueta HTML de cierre cuando complete la etiqueta de apertura. Este puede ser un paquete simple, ¡pero no puedo arreglármelas sin las etiquetas HTML de cierre automático! autoclose-html
duplica la velocidad de creación de marcado. Funciona de forma inmediata, pero el paquete también le permite definir qué etiquetas deben completarse en línea (como <p></p>
o <li></li>
) y cuáles deben crear bloques de nueva línea (como <article> ... </article>
o <ol> ... <ol>
).
La mayoría de los editores tienen visualizadores de colores CSS, pero pocos coinciden con el pigments
paquete de Atom. Analiza colores, propiedades personalizadas de CSS, variables de preprocesador e incluso ejecuta funciones de cambio de color como lighten()
y darken()
. Escanea sus archivos de origen para crear una paleta de colores para que pueda hacer referencia a ellos en cualquier lugar.
Además, el paquete Color Picker es para cualquiera que prefiera seleccionar colores en lugar de recordar sus nombres o valores hexadecimales.
Puede ejecutar linters desde la línea de comandos, pero no es tan rápido ni efectivo como la validación de código en vivo en el editor. Linter es uno de los mejores. Es rápido y menos intrusivo que algunos competidores.
Tenga en cuenta que Linter es el paquete principal de Atom que proporciona una API para docenas de lenguajes de programación . Algunos, como HTML y CSS, no requieren software adicional. Otros, como eslint
, requieren el módulo Node y los ajustes de configuración (se proporcionan instrucciones completas).
Linear su código mejorará en gran medida la calidad de su código, por lo que lo animo a que lo pruebe.
Los programadores nunca se pondrán de acuerdo sobre si usar tabulaciones o espacios. Incluso cuando lo hacen, pueden preferirlos en sabores de dos, cuatro u ocho caracteres. Por lo general, opto por lo que molesta a la mayoría de las personas (¿pestañas duras de tres caracteres?), Pero auto-detect-indentation
funciona con lo que requiere el proyecto para que nunca tenga que preocuparse por eso.
Alternativamente, puede forzar el código de todos para que coincida con su estilo preferido usando Atom Beautify:
Si alguna vez usó Live Share para VS Code , comprenderá cómo ha revolucionado la programación en pareja. La extensión permite que dos personas editen código de forma remota en el mismo espacio de trabajo al mismo tiempo.
teletype
es el paquete equivalente para Atom. Es un servicio beta, pero se ve bien y parece confiable.
Hemos cubierto lo que son, en mi opinión, algunos de los mejores paquetes Atom. Terminaremos con algunas menciones especiales que no llegaron a la lista principal pero que aún son realmente útiles y vale la pena mirar.
auto-update-packages
verifica sus paquetes cada seis horas y hace el trabajo por usted: paquetes de actualización automáticaSi su conteo de llaves ( keycount ) demuestra que ha hecho suficiente por el día, relájese leyendo cómics xkcd o juegue un juego rápido de Tetris , Reversi , Pong , Snake o SimCity .
¿Me he perdido tu complemento Atom favorito?
Fuente: https://www.sitepoint.com/essential-atom-packages-web-development/
1647679323
この記事では、Web開発者向けの最高のAtomパッケージの12を掘り下げます。Atomには、Visual StudioCodeやSublimeTextを含む多くの競争がありますが、それでも人気のある有能なWeb開発ツールとしての独自性を保持しています。
VS Codeは、過去数年にわたってWeb開発者の心をつかんだかもしれませんが、GitHubのAtomエディターは、市場でより優れた、より有能なコードエディターの1つです。それをとても好きな理由は次のとおりです。
Microsoftは2018年にGitHubを買収したため、現在、同社には2つの優れたElectronベースのコードエディターがあります。Atomの長期的な将来はおそらく疑問視されていますが、開発は続いています。新しいコードエディタを探している場合(おそらくAdobeがブラケットを放棄した後)、Atomはリストの一番上にあるはずです。
Atomは、常に「21世紀のハッキング可能なテキストエディタ」としての地位を確立してきました。基本インストールには比較的少数の機能がありますが、パッケージと呼ばれるアドオンを使用して拡張できます。
これを書いている時点で、3,000を超えるAtomテーマと9,000を超えるAtomパッケージが利用可能です。この理由の一部は、AtomがWebテクノロジーを使用して拡張できることです。Node.jsまたはクライアント側のJavaScript開発者であれば、独自のAtomパッケージを作成し、必要な方法でAtomを拡張するのに十分な知識があります。
Atomにはパッケージマネージャーが組み込まれているため、Atomパッケージの追加は非常に簡単です。(Atomパッケージのインストールが非常に簡単なこともあり、多くの開発者がAtomに惹かれています。)
Atomエディターを開き、上部のナビゲーションバーの[編集]メニューをクリックして、[設定]を選択します。新しい[設定]タブが開きます。[ +インストール]メニュー項目をクリックすると、右側に検索フィールドが表示されます。これにより、新しいAtomパッケージを名前で検索できるようになります。目的のAtomパッケージを見つけたら、[インストール]ボタンを押します。
「パッケージ」メニュー項目をクリックすると、現在インストールされているAtomパッケージが表示されます。自分でインストールしたものはすべて、[コミュニティパッケージ]メニュー項目の下に表示されます。コアパッケージメニュー項目もあることに気付くでしょう。これにより、デフォルトでインストールされているパッケージが一覧表示されます。必要に応じてこれらを無効にすることができますが、エディターの基本機能に影響を与えるため、無効にしないことをお勧めします。
apm
Atomには、(Atom Package Managerの略)というコマンドラインツールも付属しています。このツールを使用して、ターミナルから直接パッケージをインストールすることもできます。
構文は次のとおりですapm install <package-name>
。
apm
コマンドラインオプションを使用するapm config
か、ファイルを手動で編集して構成でき~/.atom/.apmrc
ます。入力apm help
すると、他に何ができるかがわかります。
そうは言っても、Atomをさらに優れたコードエディタにする12の最高のAtomパッケージといくつかのボーナスオプションがあります…
Atomのデフォルトのファイルとフォルダーのアイコンは、「機能的」として最もよく説明されています。などのアイコンセットfile-icons
は、エディタの外観を改善し、特定のタイプのファイルを見つけやすくします。
+インストールペインで「アイコン」を検索して、数十の代替オプションを見つけます。
Atomは、シンプルなフォルダーベースのプロジェクト管理を提供します。いくつかのプロジェクトを切り替える場合は十分ですが、project-manager
より高度なプロジェクトには理想的です。コマンドパレットオプションと編集可能なJSONファイルを提供し、プロジェクトを定義したり、色やタブ設定などの独自のカスタム設定を使用したりできます。
複数のデバイスでAtomを実行している場合は、インストール間で設定、キーバインディング、およびスニペットを同期すると便利です。Configフォルダー( [設定]、[Configフォルダーを開く])のファイルのクローンを作成することで手動で同期できますがsync-settings
、より簡単な自動オプションが提供されます。設定はGistに保存されますが、他のAtomパッケージでは、ローカルフォルダーまたはGitリポジトリを選択できます。
Atomを起動し、フォルダーを開いてから…次は何ですか?Atomパッケージは、、、などtodo-show
のキーワードを含むプロジェクト全体に散在するコメントを表示しますが、独自の正規表現を追加することもできます。TODOFIXMECHANGED
minimap
は最も人気のあるAtomパッケージの1つで、ダウンロード数は700万回を超えています。コードエディタウィンドウの右側にコードの要約ビューが表示されます。これは、すばやくナビゲーションするのに非常に役立ちます。この機能は潜在意識に入ります。あなたはそれを使っているとは思わないでしょう、しかしそれがそこにないときあなたはそれを見逃すでしょう。
ここでAtomミニマップパッケージを入手してください:minimap
VS Code、Sublime Text、またはNotepad ++でキーワードまたは変数を選択すると、他のすべてのインスタンスが強調表示されます。highlight-selected
その機能をAtomにもたらし、以下と組み合わせるとさらに優れたものになりminimap-highlight-selected
ます。
名前が示すように、このパッケージは、開始タグを完了すると、終了HTMLタグを自動的に追加します。これは単純なパッケージかもしれませんが、HTMLタグを自動で閉じることなしに対処することはできません!autoclose-html
マークアップの作成速度が2倍になります。箱から出してすぐに機能しますが、パッケージでは、インラインで完了するタグ(<p></p>
または<li></li>
)と改行ブロックを作成するタグ(<article> ... </article>
または)を定義することもできます<ol> ... <ol>
。
ほとんどのエディターにはCSSカラープレビューアがありpigments
ますが、Atomのパッケージに一致するものはほとんどありません。色、CSSカスタムプロパティ、プリプロセッサ変数を解析し、やなどの色を変更する関数を実行しlighten()
ますdarken()
。ソースファイルをスキャンして色のパレットを作成し、どこからでも参照できるようにします。
また、カラーピッカーパッケージは、名前や16進値を覚えるよりも色を選択したい人向けです。
コマンドラインからリンターを実行できますが、実際のエディター内コード検証ほど迅速でも効果的でもありません。リンターは最高の1つです。高速で、一部の競合他社よりも邪魔になりません。
Linterは、数十のプログラミング言語用のAPIを提供するコアAtomパッケージであることに注意してください。HTMLやCSSなどの一部は、それ以上のソフトウェアを必要としません。のような他のものeslint
は、ノードモジュールと構成設定を必要とします(完全な手順が提供されています)。
コードをリントするとコードの品質が大幅に向上するので、試してみることをお勧めします。
コーダーは、タブとスペースのどちらを使用するかについて合意することはありません。彼らがそうするときでさえ、彼らは2、4、または8つのキャラクターフレーバーでそれらを好むかもしれません。私は通常、ほとんどの人を悩ませるもの(3文字のハードタブ?)を選びますがauto-detect-indentation
、プロジェクトに必要なものを理解するので、心配する必要はありません。
または、Atom Beautifyを使用して、全員のコードを好みのスタイルに一致させることもできます。
Live Share for VS Codeを使用したことがある場合は、それがペアプログラミングに革命をもたらした方法を理解できます。この拡張機能を使用すると、2人で同じワークスペースのコードを同時にリモートで編集できます。
teletype
Atomと同等のパッケージです。ベータ版のサービスですが、見た目も良く、信頼できるようです。
私の見解では、最高のAtomパッケージのいくつかについて説明しました。最後に、トップリストには載っていませんが、それでも本当に便利で一見の価値があるいくつかの特別な言及で締めくくります。
auto-update-packages
6時間ごとにパッケージを検証し、作業を行います:auto-update-packagesキーカウント(keycount )で、その日の十分な作業が完了したことが証明された場合は、 xkcdコミックを読んでリラックスするか、テトリス、リバーシ、ポン、スネーク、またはシムシティの簡単なゲームを楽しんでください。
お気に入りのAtomアドオンを見逃したことがありますか?
ソース:https ://www.sitepoint.com/essential-atom-packages-web-development/
1646163300
pip - The Python Package Installer
pip is the package installer for Python. You can use pip to install packages from the Python Package Index and other indexes.
Please take a look at our documentation for how to install and use pip:
We release updates regularly, with a new version every 3 months. Find more details in our documentation:
In pip 20.3, we've made a big improvement to the heart of pip; learn more. We want your input, so sign up for our user experience research studies to help us do it right.
Note: pip 21.0, in January 2021, removed Python 2 support, per pip's Python 2 support policy. Please migrate to Python 3.
If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
Everyone interacting in the pip project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the PSF Code of Conduct.
Author: Pypa
Source Code: https://github.com/pypa/pip
License: MIT License