Semver การกำหนดเลขเวอร์ชั่นของ npm

Semver การกำหนดเลขเวอร์ชั่นของ npm

เวลาที่เราติดตั้งโมดูลใหม่ด้วยคำสั่ง npm i --save มันก็จะไปทำการเขียนข้อมูลลงใน package.json ให้โดยมีชื่อโมดูลและเลขเวอร์ชั่นกำกับประมาณนี้

"dependencies": {
  "lodash": "^3.9.2"
}

เคยสงสัยไหมว่าไอ้ตัว ^ ภาษาอังกฤษเรียกว่า "caret" มันคืออะไรมีไว้ทำไม และเลขเวอร์ชั่นมันบอกอะไรเราได้บ้าง ซึ่งทั้งหมดนี้มันเป็นเรื่องของ Semantic Versioning

Semantic Versioning คืออะไร

มันเป็นมาตราฐานการตั้งชื่อเลขเวอร์ชั่นของแอพพลิเคชั่นต่างๆ ถ้าใครคิดจะทำแอพพลิเคชั่นอะไรก็ตาม ผมแนะนำให้ตั้งเลขเวอร์ชั่นตาม semantic version (หรือเรียกสั้นๆ ว่า semver) เพื่อให้เป็นมาตราฐานเดียวกัน

Major Minor Path
3 . 2 . 1

โดยจะใช้เพียงเลขแค่สามจุดในการตั้ง โดยมีหลักการตั้งตามนี้

  • Major จะเปลี่ยนเมื่อมี API ชุดใหม่ที่เข้าไม่ได้กับเวอร์ชั่นก่อนหน้า เช่น โค็ดมีการเขียนใหม่ให้ดีขึ้น หรือเปลี่ยน UI ใหม่หมด หรือเพิ่มฟีเจอร์ใหญ่ๆ เข้ามา
  • Minor จะเปลี่ยนเมื่อมีการเพิ่มฟีเจอร์ใหม่เข้ามา ถอดออก หรือปรับแต่งรูปแบบการทำงาน
  • Patch ก็คือการแก้ไขบั๊กเล็กๆ

การกำหนดเลขเวอร์ชั่นเพื่ออัพเดทโมดูล

ใน package.json เราสามารถกำหนดให้ทำการติดตั้งเวอร์ชั่นไหนของโมดูลนั้นๆ ได้ และสามารถกำหนดเป็นแบบช่วงของเลขเวอร์ชั่นได้ว่า เราอยากได้เฉพาะแค่ 1.x.x เท่านั้นนะ เป็นต้น

โดยเราจะใช้สัญลักษณ์สองแบบมาช่วยเขียนเลขเวอร์ชั่นลงไปคือ

Symbol Dependency Versions
caret (^) ^3.9.2 3.* .*
tilde (~) ~3.9.2 3.9.*

หากต้องการกำหนดเลขเวอร์ชั่นสำหรับโมดูลนั้นตอนติดตั้งให้ใช้คำสั่งแบบนี้

$ npm install "lodash@^4.0.0"
# หรือ
$ npm install "lodash@~4.0.0"

เพียงแค่นี้เมื่อติดตั้งมันจะทำการติดตั้งเวอร์ชั่นล่าสุดให้ โดยไม่เกินเลขที่เรากำหนดไว้ เช่น

  • ^4.0.0 มันจะติดตั้งคือ 4.1.0 หรือ 4.2.1 เป็นต้น
  • ~4.0.0 มันจะติดตั้งคือ 4.0.2 หรือ 4.0.11 เป็นต้น

สิ่งที่ควรทำในการติดตั้งโมดูล

จากประสบการณ์ของผม สมมติเราติดตั้งโมดูลโดยใช้คำส่ัง npm install lodash โดยค่าพื้นฐานของ npm มันจะทำการเขียน package.json ให้เป็นแบบ "lodash" : "^4.17.11" ทุกครั้ง ปัญหาที่ผมเจอก็คือในช่วงที่เราพัฒนาไป เราก็เขียนโค็ดให้ใช้ได้กับเวอร์ชั่น 4.17.11 แต่หลังจากหยุดพัฒนาโค็ดไปแล้วด้วยเหตุผลอะไรก็ตามนานหลายเดือน พอเรานำโปรเจ็คตัวนี้ไปติดตั้งใหม่ เมื่อเราสั่ง npm install อีกครั้งมันจะทำการติดตั้งเวอร์ชั่นล่าสุดมาให้ เช่น 4.30.1 สังเกตุว่าเลข Minor มันถูกอัพเดท ทำให้โค็ดเดิมที่เขียนอาจมีปัญหาและเกิดบั๊กได้ละ

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

วิธีแก้ไขของผมก็คือเวลาติดตั้งโมดูลผมจะกำหนดเลขเวอร์ชั่นโดยใช้ tilde (~) ทุกครั้ง เพราะเมื่อมีการ npm install ใหม่หรือ npm update มันจะอัพเดทเฉพาะ Patch ซึ่งแทบจะร้อยเปอร์เซ็นที่อัพเดท Patch แล้วโค็ดเดิมยังใช้ได้อยู่

อย่างที่กล่าวไปข้างต้นถ้าเราติดตั้งโมดูลไป npm จะทำการกำหนด caret (^) ใส่ในเลขเวอร์ชั่นทุกครั้งใน package.json ผมแนะนำว่าเราควรเปลี่ยนให้มันใช้ tilde (~) แทนโดยการ

$ npm config set save-prefix '~'

หากใครยังสงสัยเรื่องของสัญลักษณ์ ^ หรือ ~ ว่ามันจะไปเรียกเวอร์ชั่นอะไรมาของ npm สามารถไปลองเล่นได้ที่ https://semver.npmjs.com/ เพื่อทดสอบว่าถ้าเราใส่สัญลักษณ์อะไรไป มันจะไปเรียกเวอร์ชั่นอะไรมาบ้าง

อ้างอิง:
- https://semver.org/
- https://docs.npmjs.com/about-semantic-versioning

Arnon Kijlerdphon

Arnon Kijlerdphon

Board game & Plant-based & Minimalist, it's all my life.
Bangkok, Thailand