NPM 2.0 a jak pomáhá vyhnout se globálním závislostem

Dnes jsem poslouchal epizodu NodeUp 70, která je celá o klientovi příkazového řádku npm. A v této epizodě je spousta užitečných informací. Jde o to, kde se npm v současnosti nachází a jaké jsou plány do budoucna. Obzvláště nedávné změny uvnitř klienta příkazového řádku jsou hojně diskutovaným tématem a vřele doporučuji poslechnout si tuto epizodu, když máte co do činění s npm na denní bázi.

Jedna věc, která je zmíněna a opravdu mě vzrušuje, je změna týkající se funkčnosti spouštění skriptů přes npm, která byla představena v poslední hlavní verzi npm - [email protected].

Pojďme tedy přehodnotit, jak spouštět skripty prostřednictvím npm, podívat se, co se změnilo ve verzi 2.0.0, a zjistit, proč je to tak velký problém.

Spouštění skriptů prostřednictvím npm

Konfigurační soubor pro jakýkoli projekt založený na node a npm je package.json . Tento soubor obsahuje meta informace, jako je název, verze a autor závislého projektu, ale také definuje všechny závislosti, které je třeba nainstalovat pomocí volání npm install . Pokud tento soubor neznáte, existuje vynikající interaktivní cheat a možná se na něj budete chtít podívat.

Jedna věc, kterou si musíte všimnout, je, že můžete také spouštět skripty a spouštět příkazy prostřednictvím npm. Chcete-li tak učinit, můžete definovat volitelný objekt jako scripts vlastnost uvnitř package.json a definujte požadované příkazy. @substack napsal skvělý článek o tom, jak tuto funkci široce používat.

V tom není moc kouzla.

{
  "name": "blog-npm-run-scripts",
  "version": "1.0.0",
  "description": "Show of the new npm run command",
  "scripts": {
    "echo" : "echo \"Hello world\""
  }
}

A pak můžete použít npm run odstartovat – pěkně přímo vpřed.

> npm run echo

> [email protected] echo /Users/stefan/Sites/blog-npm-run-scripts
> echo "Hello world"

Hello world

Tato funkce měla zatím jednu nevýhodu. Nebylo možné předat argumenty do npm run příkaz. A to je důvod, proč jste museli argumenty napevno zakódovat, což celou věc učinilo méně flexibilní a hůře použitelnou. Jediným řešením, jak mít podobné příkazy s různými argumenty, bylo definovat konkrétní pojmenované skripty uvnitř package.json včetně různých argumentů.

{
  "name": "blog-npm-run-scripts",
  "version": "1.0.0",
  "description": "Show of the new npm run command",
  "scripts": {
    "echo_helloWorld" : "echo \"Hello world\"",
    "echo_foo" : "echo \"Foo\""
  }
}

Předávání argumentů do npm run

Od verze 2.0.0 je nyní možné předávat argumenty skriptům definovaným v package.json . A to je velké zlepšení flexibility a dělá to celou věc mnohem silnější. package.json výše včetně dvou skriptů spouštějících echo příkaz lze spojit do jednoho a může přijmout požadované argumenty.

{
  "name": "blog-npm-run-scripts",
  "version": "1.0.0",
  "description": "Show of the new npm run command",
  "scripts": {
    "echo" : "echo"
  }
}

Syntaxe pro předávání argumentů definovaným skriptům je následující. Musíte použít npm run a poté odděleno dvěma pomlčkami (-- ) můžete příkazu předat libovolné argumenty.

> npm run echo -- "hello world"

> [email protected] echo /Users/stefan/Sites/blog-npm-run-scripts
> echo "hello world"

hello world

Nastavení Grunt a gulp bez globální závislosti

Pomocí echo příkaz se nemusí zdát opravdu užitečný, ale nyní se dostaneme k mnohem užitečnějšímu příkladu. Zabývám se převážně frontendovým vývojem, a proto je součástí téměř každého projektu, na kterém pracuji, ať už na Gruntu nebo na gulpu. Grunt a gulp jsou spouštěče úkolů, které přicházejí s obrovskými registry pluginů, které pomáhají automatizovat jakýkoli úkol, na který si vzpomenete.

Když se podíváte na příručku Začínáme pro oba projekty, najdete pokyny k jejich globální instalaci.

# install gulp globally
$ npm install -g gulp
# install grunt globally
$ npm install -g grunt-cli

To je naprosto v pořádku, když pracujete sami a tyto nástroje se mají provádět pouze na vašem stroji. Ale když pracujete společně s ostatními kolegy na projektu nebo váš proces zahrnuje kontinuální integrační systém, pak může být každá globální závislost docela problematická. Jednoduše to posouvá vstupní bariéru o něco výše a zvyšuje složitost uvedení všeho do provozu.

Pojďme se tedy podívat, jak se tomu vyhnout. Prvním krokem je instalace potřebných modulů v našem projektu a již ne globálně.

# install gulp in the project
$ npm install gulp
# install grunt in the project
$ npm install grunt-cli

Zavoláním na číslo npm install npm nainstaluje modul a v závislosti na tom, zda má bin definovaná vlastnost, vytvoří .bin složka uvnitř node_modules složku. To znamená, že tato složka bude obsahovat všechna definovaná rozhraní příkazového řádku vašich nainstalovaných modulů. V tomto případě .bin složka obsahuje binární soubory gulp a grunt .

node_modules
  |_  .bin
      |_ gulp
      |_ grunt

Pokud chcete použít buď Grunt, nebo hlt přes npm run nyní je můžete nastavit uvnitř vašeho package.json .

{
  "name": "blog-npm-run-scripts",
  "version": "1.0.0",
  "description": "Show of the new npm run command",
  "scripts": {
    "gulp" : "./node_modules/.bin/gulp",
    "grunt" : "./node_modules/.bin/grunt"
  }
}

A pak můžete snadno spouštět své definované úlohy pomocí npm.

# run 'dev' task with in project install grunt
$ npm run grunt -- dev
# run 'dev' task with in project install gulp
$ npm run gulp -- dev

Ale počkejte, je to ještě lepší!

Aby to bylo o něco hezčí, npm poskytuje šikovnou funkci při nastavování vlastních skriptů. Dá to ./node_modules/.bin v PATH prostředí, když skript spustí.

To znamená, že můžeme vytvořit package.json trochu čistší.

{
  "name": "blog-npm-run-scripts",
  "version": "1.0.0",
  "description": "Show of the new npm run command",
  "scripts": {
    "gulp" : "gulp",
    "grunt" : "grunt"
  }
}

Pro mě je to čistá nádhera!

Znamená to nejen zrušit globální závislost, ale spíše zjednodušit celou práci a tok nastavení.

Uvést vše do chodu není

  • instalace uzlu (který také nainstaluje npm)
  • instalace závislostí
  • instalace globálních závislostí
  • a spusťte např. Grunt

už.

Stává se to

  • instalační uzel
  • instalace závislostí
  • a vše spouštět pomocí skriptů npm

pouze.

Pokud si s tím chcete pohrát, vytvořil jsem ukázkové úložiště, které obsahuje Grunt a gulp připravené k použití bez jakékoli globální instalace.

Shrnout

Pro mě je jasné, že v budoucnu zruším jakoukoli globální závislost požadovanou pro projekt, kterou lze nainstalovat přes npm, protože méně globálních závislostí znamená méně problémů a rychlejší nastavení.

A to je prozatím vše a pokud k tomu máte nějaké připomínky nebo nápady, dejte mi prosím vědět. Doufám, že sis to užil. :)