สร้างเครื่องมือแจ่ม ๆ บน npx กัน

Nitipat Lowichakornthikun
I GEAR GEEK
Published in
3 min readJun 11, 2019

จากบทความเมื่อนานมาแล้ว… ผมได้พาให้ทุกคนทำความรู้จักกันกับ npx ดังนั้นสำหรับใครยังไม่เคยรู้จักมันมาก่อน ผมแนะนำเลยครับ ให้ย้อนกลับไปอ่านบทความที่ผมเขียนไว้ด้านล่างนี้ครับ

โอเคครับ วันนี้เรากลับมาอีกครั้ง พวกเราจะลองมาสร้างเครื่องมือเจ๋ง ๆ ให้ชาวโลกได้ใช้กันด้วยการสั่งคำสั่ง npx ครับ

ย้ำ.. อีกครั้งน่ะครับ เครื่องของคุณต้องติดตั้ง Node 5.2+ ก่อนจึงจะสามารถทดลองทำตามบทความนี้ได้ครับ

ก่อนอื่นเลย ให้คุณลองพิมพ์ npx cowsay more ใน terminal ดูครับ

คุณจะได้พบกับ… วัวร้อง มออออ… แบบนี้

วันนี้เราจะลองทำแบบนี้กันบ้าง เผื่อเป็นไอเดียต่อยอดในการทำเครื่องมือเจ๋ง ๆ ของคุณเองบ้างในอนาคตครับ

ผลลัพธ​์ที่เราจะทำกัน…

แสดงคำว่า Hello World! ออกมาเมื่อเรียกใช้งาน

เริ่มเลย

  1. สร้างโฟลเดอร์เปล่า ๆ ขึ้นมาครับ mkdir workspace
  2. จัดการสั่ง npm init เพื่อเริ่มสร้างโปรเจกต์ ถึงขั้นตอนนี้เราจะได้ package.json มา
  3. สร้างไฟล์ใหม่ขึ้นมาชื่อว่า index.js

เนื้อหาประมาณนี้ครับ

#!/usr/bin/env nodeconsole.log(`Hello world!`)

4. เปิด Terminal ทดลองสั่งรันด้วยคำสั่ง npx .

5. เรียบร้อย เราจะได้เห็นผลของ Hello World! แสดงออกมาครับ

เยี่ยม! ปิดบทความเลย ลองทำแล้วมันไม่ยากใช่ไหมครับ?

แต่เดี๋ยวก่อน ถ้าเราอยากให้ชาวโลกได้ใช้บ้างล่ะ ต้องทำอย่างไร?

การเอาขึ้นสู่สายตาชาวโลก

  1. ในขั้นตอนการเอาขึ้น เสมือนกับว่าเรากำลังเอา package ที่เราเชียนนี้ขึ้นไปครับ ดังนั้นเราต้องสมัครสมาชิกของ npmjs.com ก่อนครับ
  2. หลังจากที่เราสมัครเรียบร้อยแล้ว ขั้นตอนถัดมาคือการเข้าสู่ระบบ npmjs ครับ ด้วยคำสั่งว่า npm login

3. ทดลองนำเอา package ขึ้น registry ของ npmjs ด้วยคำสั่ง npm publish

หากเจอ error แบบนี้ ให้ทำการเปลี่ยนชื่อของ package เราใหม่ครับ ต้องตั้งให้ไม่ซ้ำกับของคนอื่น ๆ ที่ทำไว้

การเปลี่ยนชื่อให้เปิดไฟล์ package.json มองหา name แล้วเปลี่ยนเลยครับ

ถ้าเราสามารถนำเอาชึ้นได้แล้วก็จะเห็นผลออกมาว่า

+ {ชื่อ package ของคุณ}@1.0.0

ทดลองเรียกคำสั่ง npx {ชื่อ package} เช่นของผมชื่อว่า say-hello-svz ผมก็ทำการสั่งว่า npx say-hello-svz

กรรม ผลออกมาว่าแบบนี้ครับ

npx: installed 1 in 4.215s
command not found: say-hello-svz

ข้อความด้านบนแสดงว่ามันสามารถดึง say-hello-svz มาลงได้แล้ว แต่ไม่เจอคำสั่งในการรันนั่นเองครับ ดังนั้นเราต้องใส่คำสั่งรันให้มันไปด้วยใน package.json ครับ

ให้เราเพิ่มบรรทัดนี้เข้าไปครับ

"bin": "./index.js",

เนื้อหาของไฟล์ package.json ก็จะหน้าตาประมาณนี้ครับ (บรรทัดที่ 6 ที่เพิ่มเข้าไป)

จากนั้นให้ทำการสั่ง npm publish

ก็ดันเจอ error แสดงออกมาประมาณนี้ครับ

เนื่องจาก version ของ package มันเหมือนตัวเก่า npmjs เลย ไม่ยอมให้เอาตัวนี้ขึ้นครับ ดังนั้นเราต้องทำการเพิ่ม version (bump version) ของ package เราด้วยคำสั่ง

npm version patch -m "edit command of index.js running"

จะมีข้อความแสดงกลับมาว่าอัพเดท package ของเราเป็นเวอร์ชั่นใหม่แล้ว

v1.0.1

ซึ่งการใช้ npm version มีการเพิ่มได้สามรูปแบบคือ patch ที่เราใช้ จะเปลี่ยนแค่ตัวหลังสุด, minor จะเปลี่ยนเลขตัวกลาง และสุดท้าย major จะเปลี่ยนตัวหน้าสุด

ให้ลองดูที่ลิงค์นี้ครับ ไว้บทความต่อ ๆ ไปจะมีเล่าถึงเวอร์ชั่น ว่าทำไมมันถึงสำคัญ และ ความหมายของแต่ละหลักกันอีกทีนึงน่ะครับ

แต่เอาจริง ๆ แล้วเราก็สามารถแก้เลข version ตรง ๆ ได้ในไฟล์ package.json เช่นกันครับ ฮ่า ๆ

ลองอีกทีด้วยคำสั่ง npm publish

เราจะได้ข้อความดังนี้กลับมาครับ

+ say-hello-svz@1.0.1

แสดงว่า เรียบร้อย package ที่เราแก้สักครู่สามารถให้ชาวโลกใช้งานได้แล้วครับ

ผมจะทดลองสั่ง npx {ชื่อ package}อีกที

จะพบว่า….

แสดงข้อความมาว่า Hello World! แล้วครับ
ทีนี้เราก็เอาไปแชร์ให้เพื่อน ๆ ของเราใช้ได้แล้ว ไม่ยากใช่ไหมครับ?

ถ้าจบแบบนี้จะง่ายไป… เรามาลองทำให้สามารถรับค่ากัน

จากตัวอย่างแรกที่ผมยกไปด้วยคำสั่ง npx cowsay more จะเห็นว่าเราสามารถเปลี่ยนคำว่า more เป็นคำอื่นได้ และ วัวก็ร้องตามคำนั้นด้วย

ดังนั้นเราจะลองทำคือถ้าสั่ง npx {ชื่อ package} {ชื่อใครก็ได้} เช่น ถ้า package ของผมก็สั่งว่า npx say-hello-svz nitipat
โปรแกรมของเราจะตอบกลับมาว่า Hello World, nitipat.

  1. เราจะติดตั้ง minimist ตัวช่วยของเราในการทำให้สามารถจัดการกับ argument ต่าง ๆ ได้แบบไม่ยาก ด้วยคำสั่ง npm i minimist
  2. กลับมาแก้โค๊ด index.js
#!/usr/bin/env nodevar argv = require('minimist')(process.argv.slice(2))var name = argv._.join(' ')console.log(`Hello world! ${name}.`)

เราจะทำการรับค่าผ่าน minimist ด้วยตัวแปร argv โดยการส่ง process.argv ที่ตัดเอา 2 ตัวหน้าออก นึกภาพน่ะครับว่าถ้าเราสั่ง

npx {ชื่อ package} {อะไรก็ได้}

เจ้าตัวแปร process.argv จะได้ Array ออกมา 3 ช่องดังนี้ครับ

['npx', '{ชื่อ package}', '{อะไรก็ได้}']

ดังนั้นเราจึงทำการตัดออก 2 ตัวหน้าครับ และ ถ้ามี space อีก แบบนี้

npx {ชื่อ package} {ชื่อจริง} {นามสกุล}

ตัวแปร process.argv จะได้ Array ออกมา 4 ช่อง เห็นอะไรไหมครับ ใช่แล้วมันอิงตาม space ครับ

['npx', '{ชื่อ package}', '{ชื่อจริง}', '{นามสกุล}']

ดังนั้นสิ่งที่เราต้องทำในบรรทัดถัดมานี้ก็เพื่อให้รองรับการใส่ space มาในชื่อด้วย นั่นก็คือการนำเอาค่าที่เราได้จาก minimist มา join กันครับ (minimist จะนำเอาค่าต่าง ๆ ที่ไม่ได้ใส่ค่า parameter มาใน _ ครับ) ลองอ่านเพิ่มเติมได้ที่นี่น่ะครับ จริง ๆ มันสามารถทำได้หลายอย่างเลยครับ แต่ที่ผมเอามาใช้จริง ๆ ไม่ต้องตัวนี้ก็ได้ครับ แต่อยากให้ทุกคนได้ลองเอาไปต่อยอดได้เลยแนะนำเป็นตัวนี้ครับ

3. ทดสอบในเครื่องเราเองก่อนด้วยคำสั่ง npx . ชื่อใครก็ได้ เช่นของผม npx . nitipat

ก็จะได้หน้าตาประมาณนี้ออกมา Hello World!, nitipat. ซึ่งตรงเป๊ะตามที่เราอยากได้ครับ

ทีนี้ก็ลองเอาไอเดียมาสร้างเครื่องมือแจ่ม ๆ ที่เราคิดได้แล้วน่ะครับ ใครมีไอเดียดี ๆ มาแบ่งปันกันได้ครับ ส่วนของผมเองตอนนี้ก็นำเอามาใช้กับการทำเครื่องมือช่วยรีวิวโค๊ด ไว้บทความถัด ๆ ไปจะมาแชร์เรื่องนี้ให้ครับว่าเอามาช่วยส่วนไหนบ้าง

แก้ไขปัญหาเดิม ๆ กับวิธีใหม่ก็ทำให้สนุกได้เหมือนกันน่ะ

ขอให้ทุกคนสนุกกับการเรียนรู้สิ่งใหม่ :)

--

--