
Skriv ett enkelt npx-visitkortBest practices och mönster för att publicera valfri node-CLI

Skriv ett enkelt npx-visitkortBest practices och mönster för att publicera valfri node-CLI
En av de vanligaste sakerna vi gör som mjukvaruutvecklare är att klia oss där det kliar. Vi ser ett återkommande mönster och letar upp ett verktyg för att minska eller eliminera det. När en lösning inte redan finns kan vi skapa en. När man jobbar i terminalen görs det ofta genom att skapa ett `alias` eller skriva ett litet bash-skript. På sistone föredrar jag att skriva mina CLI-verktyg i node.
javascript är fantastiskt för CLI:er
- npms bygg-, publicerings- och delningscykel är så enkel
npxtillåter körning utan installation- npm-ekosystemet är moget för CLI-wrappers, skriv bara
stdio-hanteraren för ditt favoritpaket
npx-visitkort
Låt oss skapa ett meningslöst CLI bara för att gå igenom några best practices och mönster för att publicera valfri node-CLI.
Inspirerad av johnkpaul och searls ska vi skapa ett npx-aktiverat visitkort. Slutresultatet kan se ut ungefär så här:

npm init
Starta ett nytt node-projekt och döp det till vad du vill. Du kan välja att döpa det efter den körbara filen du vill exponera. Det är inte nödvändigt, men konventioner är trevliga och gör din binär mer npx-vänlig.
mkdir jackboberg
cd jackboberg
npm init -y
Låt oss först få själva CLI:et att fungera.
touch cli.js
chmod +x cli.js
Öppna nu den nya filen i din favoriteditor. Jag har använt spacemacs på sistone, men är fortfarande väldigt förtjust i vim.
#!/usr/bin/env node
console.log('doing business')
Du kan köra ditt nya CLI så här:
./cli.js
skeppa det
Det är en fullt fungerande första release! Du behöver bara ändra din package.json för att låta npm veta att den ska länka din körbara fil, så är du klar:
{
// ...
"bin": "./cli.js",
// ....
}
Som standard exponerar npm din binär med samma namn som ditt paket. Du kan konfigurera detta om det inte är vad du vill, men det gör din körbara fil svårare att använda med npx.
Dela ditt nya CLI med världen!
npm version patch
npm publish
Nu kan vem som helst använda ditt nya CLI med npx, utan att behöva installera det lokalt:
npx $YOUR_PACKAGE_NAME
Lägg din logik i en separat fil
Tänk om du vill berätta mer för folk om verksamheten du bedriver. Skapa ett objekt för att hålla datan för vårt CLI. Jag gillar att hålla även små projekt organiserade, så jag skapar en ny fil i lib för det här.
# ./lib/data.js
module.exports = {
name: 'Jack Boberg',
title: 'Software Engineer',
github: 'jackboberg',
urls: [
'https://jackboberg.info',
'https://studioelsa.se'
]
}
När ditt CLI behöver göra ytterligare arbete, lägg den koden i index.js eller en lokal modul. Användare kan då använda ditt paket programmatiskt, och det ger dig en tydlig plats för all din tillståndshanterande affärslogik. I det här fallet använder vi huvudmodulen för att formatera vår data som en snygg sträng.
Låt oss hämta ett bibliotek som gör vår utdata lite snyggare.
npm i prettyjson
Vi kan använda det här paketet, eller något annat användbart verktyg vi hittar på npm, för att förbättra vårt CLI.
# ./index.js
const { render } = require('prettyjson')
const data = require('./lib/data')
const renderOpts = {
dashColor: 'cyan',
keysColor: 'blue',
stringColor: 'white'
}
module.exports = () => render(data, renderOpts)
En liten uppdatering av vårt ./cli.js-skript så kan vi använda vår nya modul.
#!/usr/bin/env node
const pkg = require('..')
console.log(pkg())
Hantera stdio i ditt CLI-modul explicit
Det är inte illa, men tänk om någon vill ha den råa JSON-datan. Låt oss lägga till en enkel flagga för att ändra skriptets beteende.
npx jackboberg -j
Att hålla cli.js fokuserad på att tolka indata och producera utdata är en bra idé; det håller filerna små och rimliga. Motstå frestelsen att skriva affärslogik i den här filen.
#!/usr/bin/env node
const minimist = require('minimist')
const pkg = require('.')
const options = {
alias: { json: 'j' }
}
const argv = minimist(process.argv.slice(2), options)
console.log(pkg(argv))
prettyjson har redan minimist som ett beroende, så du kan lägga till det "gratis" och klä upp ditt CLI därifrån. Du bör ändå inkludera det explicit i dependencies. Låt oss göra en liten ändring i vårt huvudskript för att stödja det här nya alternativet.
# ./index.js
// ...
module.exports = ({ json }) => json ? JSON.stringify(data) : render(data, renderOpts)
Glöm inte att publicera ditt slutgiltiga npx-visitkort när du är klar med att lägga till en massa onödiga extrafunktioner. Jag såg till att mitt inkluderade cowsay, av skäl.
npm version major
npm publish
Nu har du ett globalt körbart skript som kan använda hela npm för att utföra fantastiska verktyg (eller töntiga idéer som den här). Om du märker att du skriver ett "stort" CLI med massor av parametrar eller underkommandon vill du ha fler alternativ kring hur du definierar ditt CLI och bör överväga yargs istället för minimist.
Bygger du något liknande?
Om du planerar en ny lösning eller förbättrar en befintlig kan vi hjälpa till med riktning och implementation.
Starta något