วิธีตั้ง min-release-age ใน .npmrc

npm 11.10 ขึ้นไปตั้ง min-release-age ใน .npmrc ได้ แล้ว npm install กับ npm update จะไม่หยิบเวอร์ชันที่เพิ่งออกไม่ถึงจำนวนวันที่ตั้ง เผื่อเวอร์ชันนั้นเป็นของปลอมจากบัญชีที่โดนยึด ยกเว้น package ของเราเองได้ ไม่กระทบ npm ci ตอน deploy และ pnpm, Yarn, Bun ก็มี setting แบบเดียวกัน

เผยแพร่
เวลาอ่าน
4 นาที
ในโพสต์นี้ 6 หัวข้อ
  1. cooldown คือการรอให้เวอร์ชันใหม่ผ่านไปสักพัก
  2. ตั้ง min-release-age ใน .npmrc
  3. ยกเว้น package ของเราเองหรือตอนต้องรีบแพตช์
  4. cooldown ทำงานตอนเลือกเวอร์ชัน ไม่ใช่ตอน deploy
  5. pnpm, Yarn และ Bun ใช้หน่วยไม่เหมือนกัน
  6. ให้ bot เปิด PR อัปเดตหลังพ้น cooldown

ปกติเรารัน npm install vite หรือ npm update ก็ได้เวอร์ชันล่าสุดทันที รวมถึงเวอร์ชันที่เพิ่งออกเมื่อสิบนาทีก่อนด้วย เมื่อ ก.ย. 2568 package ที่คนใช้กันมากอย่าง chalk และ debug มีเวอร์ชันอันตรายออกมาจากบัญชีของคนดูแลที่โดน phishing เวอร์ชันพวกนั้นอยู่บน npm ราวสองชั่วโมงก่อนมีคนเอาออก ใครที่ติดตั้งในช่วงนั้นก็ได้ของอันตรายไปเต็ม ๆ

cooldown คือการรอให้เวอร์ชันใหม่ผ่านไปสักพัก

package ที่โดนแอบใส่โค้ดอันตรายมักโดนจับได้เร็ว บางตัวไม่กี่นาที บางตัวเป็นชั่วโมงหรือเป็นวัน แล้ว registry ก็ถอดเวอร์ชันนั้นออก ถ้าเราไม่รีบหยิบเวอร์ชันที่เพิ่งออก เวอร์ชันอันตรายก็มีโอกาสหายไปก่อนถึงเครื่องเรา

ตัวจัดการ package เรียกเรื่องนี้ต่างกัน cooldown บ้าง minimum release age บ้าง แต่ทำแบบเดียวกันคือข้ามเวอร์ชันที่ออกมายังไม่ครบเวลาที่ตั้งไว้ ฝั่ง PHP ก็มีแล้วตั้งแต่ Composer 2.11 ถ้าใช้ Laravel คู่กับ npm ลองอ่านวิธีตั้ง Composer ให้รอเวอร์ชันใหม่สักพักก่อนติดตั้ง ไปด้วยได้ครับ

ตั้ง min-release-age ใน .npmrc

npm เพิ่ม min-release-age มาตั้งแต่ npm 11.10 (ก.พ. 2569) และยังปิดไว้เป็นค่าเริ่มต้น ใส่ไว้ใน .npmrc ที่รากโปรเจกต์แล้ว commit ไปพร้อมโค้ด ทุกคนในทีมจะได้ค่าเดียวกัน

min-release-age=1
  • min-release-age นับเป็นจำนวนวันเท่านั้น เขียนหน่วยแบบ "1 day" ไม่ได้
  • ถ้าอยากให้มีผลทุกโปรเจกต์บนเครื่อง ใช้ npm config set min-release-age 1 --location=user แทน

npm ที่ต่ำกว่า 11.10 ไม่รู้จัก setting นี้ ตั้งไว้ก็ไม่มีผล เช็คด้วย npm --version ถ้ายังเป็นรุ่นเก่า อัปเดตได้ด้วย npm install -g npm@11 (รุ่น 11 ล่าสุดใช้กับ Node 20.17 และ 22.9 ขึ้นไป)

npm มาพร้อม Node.js ถ้า Node ในเครื่องเก่าจนลง npm 11 ไม่ได้ ก็ถึงเวลาขยับ Node ด้วย เช็คได้ที่Node.js ที่ใช้อยู่เก่าแค่ไหน ว่ารุ่นที่ใช้ยังได้อัปเดตไหม และถ้าต้องมีหลายรุ่นในเครื่อง ลองใช้ nvm สลับทีละโปรเจกต์ได้

ยกเว้น package ของเราเองหรือตอนต้องรีบแพตช์

package ที่เราดูแลเองไม่จำเป็นต้องรอ ใส่ชื่อหรือ pattern ไว้ใน min-release-age-exclude ซึ่งใช้ได้ตั้งแต่ npm 11.17

min-release-age=1
min-release-age-exclude[]=@myorg/*
min-release-age-exclude[]=my-internal-pkg

npm ยกเว้นเฉพาะตัวที่ระบุ ส่วน dependency ของ package นั้นยังต้องรอเหมือนเดิม ถ้าไม่ได้ใส่ pattern ให้ตรงด้วย

แพตช์ความปลอดภัยต้องรอ cooldown เหมือนเวอร์ชันอื่น วันที่ package ที่ใช้อยู่มีช่องโหว่ใหญ่ เราจึงต้องข้ามเองทีละครั้ง

npm install vite@latest --min-release-age=0

npm 11.19 ขึ้นไป ถ้า cooldown ทำให้ npm audit fix ลงเวอร์ชันที่แก้ช่องโหว่ไม่ได้ npm จะคง package ไว้ที่เวอร์ชันเดิม เตือนว่าแพตช์ยังไม่ครบเวลา และจบคำสั่งด้วย error เราจะได้รู้ว่ายังมีช่องโหว่ค้างอยู่ แล้วเลือกเองว่าจะรอหรือข้ามด้วยคำสั่งข้างบน

cooldown ทำงานตอนเลือกเวอร์ชัน ไม่ใช่ตอน deploy

คำสั่ง cooldown มีผลไหม
npm install <package>, npm update มีผล ข้ามเวอร์ชันที่ยังไม่ครบเวลา ถ้าไม่มีเวอร์ชันไหนผ่านเกณฑ์เลย คำสั่งจะ error
npm ci ไม่มีผล ติดตั้งตาม package-lock.json ทุกตัว
npm outdated นับเฉพาะเวอร์ชันที่ผ่านช่วงรอแล้ว

ขั้น deploy และ CI ที่รัน npm ci จึงไม่เปลี่ยนอะไร จุดที่ cooldown ช่วยคือตอนที่เราเพิ่มหรืออัปเดต package บนเครื่องตัวเองแล้ว commit package-lock.json ขึ้นไป

ถ้าเคยตั้ง before ไว้ ซึ่งรับเป็นวันที่ตายตัว ให้เลือกใช้อย่างใดอย่างหนึ่ง npm 11 ไม่ยอมให้ตั้งคู่กัน

pnpm, Yarn และ Bun ใช้หน่วยไม่เหมือนกัน

ตัวจัดการ package ฝั่ง JavaScript ตัวอื่นก็มี setting แบบเดียวกัน แต่ชื่อและหน่วยต่างกันหมด ตั้งให้รอหนึ่งวันได้แบบนี้

ตัวจัดการ package ไฟล์ รอหนึ่งวัน ยกเว้นด้วย
npm .npmrc min-release-age=1 (วัน) min-release-age-exclude
pnpm pnpm-workspace.yaml minimumReleaseAge: 1440 (นาที) minimumReleaseAgeExclude
Yarn .yarnrc.yml npmMinimalAgeGate: "1d" npmPreapprovedPackages
Bun bunfig.toml ใต้ [install] minimumReleaseAge = 86400 (วินาที) minimumReleaseAgeExcludes

pnpm รุ่นปัจจุบันตั้ง minimumReleaseAge ไว้ที่ 1440 นาทีเป็นค่าเริ่มต้นอยู่แล้ว ถ้าใช้ pnpm รุ่นเก่ากว่านั้นหรือตัวอื่น ลองเช็คในเอกสารของแต่ละตัวว่ารุ่นที่ใช้อยู่รองรับหรือยัง

ให้ bot เปิด PR อัปเดตหลังพ้น cooldown

cooldown ใน .npmrc ช่วยตอนที่เรา update เอง ถ้าอยากให้มีคนบอกว่ามีเวอร์ชันใหม่ที่ผ่านช่วงรอแล้ว ก็ให้ bot ทำ Dependabot รอให้เวอร์ชันใหม่ออกมาครบ 3 วันก่อนเปิด PR อยู่แล้ว และปรับเวลารอได้ด้วย cooldown ใน .github/dependabot.yml

version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    cooldown:
      default-days: 3
      semver-major-days: 14
      exclude:
        - '@myorg/*'
  • default-days คือจำนวนวันที่รอสำหรับทุก package ไม่ใส่ก็เป็น 3 วัน
  • semver-major-days ให้เวอร์ชัน major รอนานกว่า เพราะมักมี breaking change และแพตช์แก้ตามมา ตั้ง semver-minor-days กับ semver-patch-days แยกได้เหมือนกัน
  • exclude ใส่ package ที่ไม่ต้องรอ ใช้ * ได้

โปรเจกต์ที่มี Composer ด้วยก็ใส่ cooldown ชุดเดียวกันไว้ใน block ของ package-ecosystem: composer ส่วน security updates ของ Dependabot ไม่รอ cooldown เปิด PR แพตช์ให้ทันทีที่มี advisory

ถ้าใช้ Renovate ตั้ง minimumReleaseAge เป็น "3 days" คู่กับ internalChecksFilter: "strict" แล้ว Renovate จะยังไม่เปิด PR จนกว่าจะมีเวอร์ชันที่ผ่านช่วงรอครับ

อ่านต่อ

ถูกอ้างถึงใน

ล่าสุด

ดูทั้งหมด →