ถ้าเราลง Node.js จากตัวติดตั้งของ nodejs.org ทั้งเครื่องจะมี Node อยู่เวอร์ชันเดียว ทีนี้โปรเจกต์ Laravel เก่าที่ยังใช้ Laravel Mix อาจรันได้แค่บน Node 16 แต่โปรเจกต์ใหม่ที่ใช้ Vite 8 ต้องใช้ Node 20.19 หรือ 22.12 ขึ้นไป พอสลับไปทำอีกโปรเจกต์ก็ต้องถอนแล้วลงใหม่ทุกที nvm แก้เรื่องนี้
nvm คือตัวสลับเวอร์ชัน Node.js
nvm ย่อมาจาก Node Version Manager เป็น shell script ที่ลง Node.js แต่ละเวอร์ชันแยกไว้ในโฟลเดอร์ ~/.nvm ของเรา แล้วสลับว่า node กับ npm ใน terminal ตอนนี้ชี้ไปที่เวอร์ชันไหน
- แต่ละเวอร์ชันมี npm ของตัวเอง ตาม npm ที่มาพร้อม Node รุ่นนั้น
- package ที่ลงแบบ global ก็แยกกัน ลง
npm install -gไว้ตอนใช้ Node 22 พอสลับไป Node 24 จะไม่เห็นตัวนั้น - ไม่ต้องใช้
sudoเพราะทุกอย่างอยู่ในโฟลเดอร์ของเรา
nvm ทำงานบน macOS, Linux และ Windows ผ่าน WSL ไม่รองรับ Windows ตรง ๆ ถ้าใช้ Windows ดูหัวข้อทางเลือกบน Windows ข้างล่าง
ติดตั้ง nvm บน macOS และ Linux
ใช้ script ติดตั้งจาก README ของ nvm ตอนนี้เป็นเวอร์ชัน 0.40.8
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
script จะ clone nvm ไว้ที่ ~/.nvm แล้วเพิ่มบรรทัดที่โหลด nvm ลงใน ~/.zshrc (หรือ ~/.bashrc ถ้าใช้ bash) ปิด terminal แล้วเปิดใหม่ จากนั้นเช็คว่าใช้ได้ด้วย nvm --version
README ของ nvm บอกไว้ว่าไม่รองรับการติดตั้งผ่าน Homebrew ถ้าเคยลงด้วย brew install nvm แล้วมีปัญหา ให้ถอนออกแล้วลงด้วย script ข้างบนแทน
คำสั่งที่ใช้บ่อย
nvm install --lts
nvm install 24
nvm use 24
nvm alias default 24
nvm ls
nvm uninstall 18
nvm install --ltsลง Node รุ่น LTS ล่าสุด ส่วนnvm install 24ลง Node 24 ตัวล่าสุด เวอร์ชันแรกที่ลงจะเป็นค่าเริ่มต้นให้เองnvm use 24สลับไปใช้ Node 24 เฉพาะ terminal นี้ เปิดหน้าต่างใหม่จะกลับไปใช้ค่าเริ่มต้นnvm alias default 24ตั้งให้ทุก terminal ที่เปิดใหม่ใช้ Node 24nvm lsดูว่าลงไว้กี่เวอร์ชันและตอนนี้ใช้ตัวไหนnvm ls-remote --ltsดูรุ่น LTS ที่ลงได้ทั้งหมดnvm uninstall 18ลบเวอร์ชันที่ไม่ได้ใช้แล้ว
เลือกรุ่นไหนดีให้ดูว่ายังได้อัปเดตอยู่ไหม ที่ผ่านมา Node.js เลขคู่เป็นรุ่น LTS ที่ได้อัปเดตราวสามปี ส่วนเลขคี่ได้อัปเดตสั้นกว่ามากและไม่เหมาะกับงานจริง อย่าง Node 20 หมด support ไปแล้วตั้งแต่ 30 เม.ย. 2569 ลองเช็ครุ่นที่ใช้อยู่ได้ที่Node.js ที่ใช้อยู่เก่าแค่ไหน
ให้โปรเจกต์บอกเวอร์ชันของตัวเองด้วย .nvmrc
แทนที่จะจำว่าโปรเจกต์ไหนใช้ Node อะไร เราใส่เลขเวอร์ชันไว้ในไฟล์ .nvmrc ที่รากโปรเจกต์ แล้ว commit ไปพร้อมโค้ด
24
พอ cd เข้าโปรเจกต์แล้วพิมพ์ nvm use หรือ nvm install เฉย ๆ nvm จะอ่านเลขจาก .nvmrc ให้ เพื่อนในทีมที่ clone ไปก็ได้รุ่นเดียวกัน ใส่ lts/* แทนเลขก็ได้ถ้าอยากได้ LTS ล่าสุดเสมอ แต่เลขตายตัวจะคาดเดาได้กว่า
.nvmrc ไม่ได้ใช้แค่กับ nvm ตัวอื่นก็อ่านไฟล์นี้ด้วย อย่าง fnm และ actions/setup-node บน GitHub Actions ที่ตั้ง node-version-file: '.nvmrc' ได้ CI กับเครื่องเราจึงใช้ Node เวอร์ชันเดียวกัน
ให้ terminal สลับเวอร์ชันเองตอน cd เข้าโปรเจกต์
nvm ไม่ได้สลับให้เองเมื่อเข้าโฟลเดอร์ ถ้าอยากให้ทำ README ของ nvm มีตัวอย่างสำหรับ zsh ที่ผู้ใช้ส่งมาให้ ใส่ไว้ท้าย ~/.zshrc แล้วรัน source ~/.zshrc
autoload -U add-zsh-hook
load-nvmrc() {
local nvmrc_path
nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version
nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
nvm use
fi
elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
เข้าโฟลเดอร์ที่มี .nvmrc ก็จะสลับให้ (ยังไม่มีรุ่นนั้นก็ลงให้) ออกจากโฟลเดอร์ก็กลับไปใช้ค่าเริ่มต้น ทีมดูแล nvm บอกไว้ว่าไม่ได้ดูแลตัวอย่างชุดนี้เอง ถ้าเจอปัญหาให้ลองดู fnm ที่มีเรื่องนี้ในตัว
ย้ายไป Node รุ่นใหม่โดยไม่ต้องลง package global ใหม่
nvm install 26 --reinstall-packages-from=24
nvm install-latest-npm
--reinstall-packages-from=24ลง Node 26 แล้วลง package global ที่เคยมีใน Node 24 ให้ครบnvm install-latest-npmอัปเดต npm เป็นรุ่นล่าสุดที่ Node ตัวที่ใช้อยู่รองรับ เพราะ npm ที่มากับ Node อาจไม่ใช่ตัวล่าสุด อย่าง npm 11.10 ขึ้นไปที่ตั้งให้รอเวอร์ชันใหม่สักพักก่อนติดตั้งได้
อย่าลืมแก้ .nvmrc ของโปรเจกต์ให้ตรงกับรุ่นใหม่ด้วย แล้วลอง npm ci กับ npm run build ให้ผ่านก่อน commit
ทางเลือกบน Windows
- nvm-windows เป็นคนละโปรเจกต์กับ nvm ชื่อคล้ายกันแต่คำสั่งไม่เหมือนกันทั้งหมด (
nvm listแทนnvm lsเป็นต้น) README แนะนำให้ถอน Node ที่ลงไว้เดิมออกก่อน ไม่อย่างนั้นnvm useอาจดูเหมือนไม่ทำอะไรเลย รุ่นเดิมต้องเปิด terminal แบบ Run as administrator ตอนสลับเวอร์ชันด้วย - fnm เขียนด้วย Rust ทำงานเร็ว ใช้ได้ทั้ง Windows, macOS และ Linux อ่าน
.nvmrcได้ และมี--use-on-cdสลับเวอร์ชันเองตอนเข้าโฟลเดอร์ ลงบน Windows ด้วยwinget install Schniz.fnm
ถ้าในทีมมีทั้ง Windows และ Mac การใช้ fnm ทุกเครื่องจะพูดคำสั่งเดียวกันได้ ส่วน .nvmrc ใช้ร่วมกันได้ทั้งหมด
ปัญหาที่อาจเจอตอนใช้งานจริง
nvm: command not found หลังติดตั้ง terminal ที่เปิดอยู่ยังไม่ได้โหลด ~/.zshrc ใหม่ ปิดแล้วเปิดใหม่ หรือรัน source ~/.zshrc ถ้ายังไม่หาย เช็คว่าในไฟล์มีบรรทัด export NVM_DIR="$HOME/.nvm" แล้วหรือยัง
nvm use แล้ว node -v ยังเป็นเวอร์ชันเดิม มักเป็นเพราะเครื่องมี Node อีกตัวจากตัวติดตั้งของ nodejs.org หรือ Homebrew อยู่ก่อน which node จะบอกว่าใช้ตัวไหน ถ้าไม่ได้อยู่ใต้ ~/.nvm ให้ถอนตัวนั้นออก
บนเซิร์ฟเวอร์ ตัวที่รันเบื้องหลังหา node ไม่เจอ nvm โหลดผ่านไฟล์ของ shell ตอนเราล็อกอิน แต่ supervisor, cron หรือ systemd ไม่ได้อ่านไฟล์นั้น งานอย่าง SSR server ของ Inertia หรือ script build ใน cron จึงหา node ไม่เจอ หรือไปเจอตัวอื่นแทน บนเซิร์ฟเวอร์จึงมักลง Node ตัวเดียวทั้งเครื่องผ่าน package manager ของระบบ หรือชี้ไปที่ path เต็มใน ~/.nvm/versions/node/ ตรง ๆ แล้วเก็บ nvm ไว้ใช้บนเครื่องพัฒนาครับ






