Какво е npm? Урок за диспечер на пакети за възли за начинаещи

Тази статия трябва да служи като основно ръководство за любимия помощник на Node.js: npm.

Node.js завладява света от 2009 г. Стотици хиляди системи са изградени с помощта на Node.js, което кара общността на разработчиците да твърди, че "JavaScript яде софтуер".

Един от основните фактори за успеха на Node е npm - неговият популярен мениджър на пакети, който позволява на разработчиците на JavaScript да споделят полезни пакети като lodash и момент бързо и лесно.

Към момента, в който пиша тази публикация, npm улесни публикуването на над 1,3 милиона пакета със седмична скорост на изтегляне от над 16 милиарда! Тези цифри са фантастични за всеки софтуерен инструмент. Така че сега нека поговорим какво точно е npm.

Какво е NPM?

NPM - или "Node Package Manager" - е мениджърът на пакети по подразбиране за изпълнението на JavaScript Node.js.

Известен е още като „Ninja Pumpkin Mutants“, „Nonprofit Pizza Makers“ и множество други произволни имена, които можете да изследвате и вероятно да допринесете за тях при npm-expansions.

NPM се състои от две основни части:

  • инструмент CLI (интерфейс на командния ред) за публикуване и изтегляне на пакети и
  • онлайн хранилище, което хоства JavaScript пакети

За по-визуално обяснение можем да мислим за хранилището npmjs.com като център за изпълнение, който получава пакети стоки от продавачи (автори на пакети npm) и ги разпространява сред купувачите (потребители на пакета npm).

За да улесни този процес, центърът за изпълнение на npmjs.com използва армия от трудолюбиви вомбати (npm CLI), които ще бъдат назначени като лични асистенти на всеки отделен клиент на npmjs.com. Така че зависимостите се доставят на разработчиците на JavaScript по следния начин:

и процесът на публикуване на пакет за вашите приятели в JS ще бъде нещо подобно:

Нека разгледаме как тази армия от вомбати помага на разработчиците, които искат да използват JavaScript пакети в своите проекти. Ще видим и как те помагат на магьосниците с отворен код да изведат своите страхотни библиотеки в света.

package.json

Всеки проект в JavaScript - независимо дали е Node.js или приложение за браузър - може да бъде обхванат като npm пакет със собствена информация за пакета и неговата package.jsonработа да опише проекта.

Можем да мислим за package.jsonщамповани етикети върху онези добри npm кутии, които нашата армия от Wombats доставя наоколо.

package.jsonще се генерира при npm initстартиране за инициализиране на проект JavaScript / Node.js, с тези основни метаданни, предоставени от разработчиците:

  • name: името на вашата библиотека / проект на JavaScript
  • version: версията на вашия проект. Често пъти, за разработване на приложения, това поле често се пренебрегва, тъй като няма очевидна нужда от версиране на библиотеки с отворен източник. Но все пак може да бъде полезен като източник на версията за внедряване.
  • description: описание на проекта
  • license: лиценз на проекта

npm скриптове

package.jsonсъщо поддържа scriptsсвойство, което може да бъде дефинирано за изпълнение на инструменти за команден ред, които са инсталирани в локалния контекст на проекта. Например scriptsчастта от npm проект може да изглежда по следния начин:

{ "scripts": { "build": "tsc", "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", "lint": "eslint src/**/*.ts", "pack": "ncc build", "test": "jest", "all": "npm run build && npm run format && npm run lint && npm run pack && npm test" } } 

с eslint, prettier, ncc, jestне е задължително да се инсталира като глобални изпълними, а като местен към проекта си вътре node_modules/.bin/.

Неотдавнашното въвеждане на npx ни позволява да изпълняваме тези node_modulesкоманди с обхват на проекти точно като глобално инсталирана програма чрез префикс npx ...(т.е. npx prettier --write **/*.ts).

зависимости срещу devDependencies

Тези два се предлагат под формата на обекти ключ-стойност с имена на библиотеки npm като ключ и техните семантично форматирани версии като стойност. Това е пример от шаблона ActionScript на Github:

{ "dependencies": { "@actions/core": "^1.2.3", "@actions/github": "^2.1.1" }, "devDependencies": { "@types/jest": "^25.1.4", "@types/node": "^13.9.0", "@typescript-eslint/parser": "^2.22.0", "@zeit/ncc": "^0.21.1", "eslint": "^6.8.0", "eslint-plugin-github": "^3.4.1", "eslint-plugin-jest": "^23.8.2", "jest": "^25.1.0", "jest-circus": "^25.1.0", "js-yaml": "^3.13.1", "prettier": "^1.19.1", "ts-jest": "^25.2.1", "typescript": "^3.8.3" } } 

Тези зависимости се инсталират чрез npm installкомандата с --saveи --save-devфлагове. Те са предназначени да се използват съответно за производствени и разработващи / тестови среди. Ще разгледаме по-задълбочено инсталирането на тези пакети в следващия раздел.

Междувременно е важно да разберете възможните признаци, които идват преди семантичните версии (ако приемем, че сте прочели по major.minor.patchмодела на semver):

  • ^: последно незначително издание. Например, ^1.0.4спецификация може да инсталира версия, 1.3.0ако това е най-новата малка версия от 1основната серия.
  • ~: най-новото издание на кръпка. По същия начин, както ^при малки издания, ~1.0.4спецификацията може да инсталира версия, 1.0.7ако това е най-новата малка версия от 1.0втората поредица.

Всички тези точни версии на пакета ще бъдат документирани в генериран package-lock.jsonфайл.

package-lock.json

Този файл описва точните версии на зависимостите, използвани в npm JavaScript проект. Ако package.jsonе родов описателен етикет, package-lock.jsonе таблица на съставките.

И точно както обикновено не четем таблицата на съставките на даден продукт (освен ако не ви е скучно или не е нужно да знаете), package-lock.jsonне е предназначено да се чете ред по ред от разработчиците (освен ако не сме отчаяни да разрешим " работи в моята машина "въпроси".

package-lock.jsonобикновено се генерира от npm installкомандата и също се чете от нашия инструмент NPM CLI, за да се осигури възпроизвеждане на среда за изграждане на проекта с npm ci.

Как ефективно да командвате NPM Wombats като „купувач“

Както се заключва от споменатите по-рано 1,3 милиона публикувани пакета срещу 16 милиарда изтегляния, повечето потребители на npm използват npm в тази посока. Така че е добре да знаете как да използвате този мощен инструмент.

npm инсталиране

Това е най-често използваната команда, тъй като днес разработваме приложенията JavaScript / Node.js.

По подразбиране npm install ще инсталира най-новата версия на пакет със ^знака за версия. В npm installрамките на контекста на npm проект ще изтегли пакети в node_modulesпапката на проекта в съответствие със package.jsonспецификациите, надграждайки версията на пакета (и от своя страна регенерирайки package-lock.json) навсякъде, където може, въз основа на ^и ~съвпадение на версията.

Можете да посочите глобален флаг, -gако искате да инсталирате пакет в глобалния контекст, който можете да използвате навсякъде на вашата машина (това е често срещано за пакетите с инструменти на командния ред като сървър на живо).

npm направи инсталирането на JavaScript пакети толкова лесно, че тази команда често се използва неправилно. Това води до това, че npm е в основата на много шеги на програмистите като тези:

Тук --productionна помощ идва знамето! В предишния раздел дискутирахме dependenciesи имахме devDependenciesпредвид съответно в производствената и разработващата / тестовата среда. Този --productionфлаг е начинът, по който node_modulesсе правят разликите в .

By attaching this flag to the npm install command, we will only install packages from dependencies, thus drastically reducing the size of our node_modules to whatever is absolutely necessary for our applications to be up and running.

Just like how as boy and girl scouts we didn't bring lemon squeezers to our lemonade booth, we shouldn't bring devDependencies to production!

npm ci

So if npm install --production is optimal for a production environment, must there be a command that's optimal for my local development, testing setup?

The answer is npm ci.

Just like how if package-lock.json doesn't already exist in the project it's generated whenever npm install is called, npm ci consumes this file to download the exact version of each individual package that the project depends on.

This is how we can make sure that the our project's context stays exactly the same across different machines, whether it's our laptops used for development or CI (Continuous Integration) build environments like Github Actions.

npm audit

With the humongous number of packages that have been published and can easily be installed, npm packages are susceptible to bad authors with malicious intentions like these.

Realising that there was an issue in the ecosystem, the npm.js organisation came up with the idea of npm audit. They maintain a list of security loopholes that developers can audit their dependencies against using the npm audit command.

npm audit gives developers information about the vulnerabilities and whether there're versions with remediations to upgrade to. For example,

If the remediations are available in the next non-breaking version upgrades, npm audit fix can be used to upgrade the affected dependencies' versions automatically.

How to effectively command NPM wombats as "seller"

We have gone through how to wield the NPM CLI tool as a consumer, but what about effectively using it as an author (and potentially becoming a JavaScript open source wizard ?)?

npm publish

Sending a package to our npmjs.com fulfillment centre is super easy as we only need to run npm publish. The tricky part, which is not specific to npm package authors, is determining the version of the package.

The rule of thumb according to semver.org:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH version when you make backwards compatible bug fixes.

It's even more important to follow the above rule when publishing your packages to ensure that you're not breaking anyone's code as the default version matching in npm is ^ (aka the next minor version).

❤️ npm ❤️ JavaScript ❤️ Node.js ❤️

That's all we need to know to start wielding npm effectively and command our lovely army of wombats!