ครที่ทำเว็บแอปด้วย Node.js/React/Next.js หรือสาย JavaScript น่าจะเคยเจอปัญหา node_modules บวม จนทำให้ HDD/SSD เต็มเร็ว การ build ช้า และ CI/CD หรือการ Deploy ก็ใช้เวลานานขึ้นแบบชัดเจน
จริง ๆ แล้วบาง dependencies มันก็จำเป็นจริง ๆ (เช่น React, TypeScript, CodeMirror) แพ็กเพจเหล่านี้เราไม่สามารถเขียนเองใหม่ได้ แต่ก็ไม่ได้หมายความว่าเราจะปล่อยปละละเลยไปตามน้ำ เราต้องมีศิลปะในการจัดการ dependencies เพื่อให้โปรเจกต์ของเราเบา สะอาด และง่ายต่อการดูแล บำรุงรักษาในระยะยาวด้วย
.
นี่คือแนวทางในการดูแล package.json ครับ
.
1. อ่านก่อนติดตั้ง dependency ใหม่เสมอ
อย่าเพิ่งรีบ npm install ให้ลองเปิด README และ source code ดูก่อน
ถ้าโค้ดเพียงแค่ไม่กี่สิบบรรทัด เราสามารถ copy มาใช้เองจะดีกว่า (แต่อย่าลืมใส่ลิขสิทธิ์ให้ถูกต้อง)
ถ้า dependency นั้น ใหญ่เกินไป หรือพ่วง dependencies ลูกโซ่มาเยอะ แต่เราใช้จริงนิดเดียว ควรหลีกเลี่ยง และหาทางเลือกอื่นที่เบากว่า
ข้อยกเว้นคือ mega-dependencies อย่าง React, TypeScript ที่เราไม่มีทางหนีได้ ยังไงก็ต้องเชื่อทีมใหญ่ที่ดูแลมันต่อเนื่อง
.
2. เข้าใจ “dependencies ที่มองไม่เห็น”
สิ่งที่กินพื้นที่ใน node_modules จริง ๆ มักไม่ใช่ตัวที่เราใส่เองตรง ๆ แต่คือ transitive dependencies (dependency ของ dependency)
วิธีตรวจสอบลองใช้คำสั่ง:
npm ls <package> # ดูว่า dependency ตัวนี้มาจากไหน
หรือ
pnpm why <package> # สำหรับ pnpm
อ่านเพิ่มใน package-lock.json หรือ pnpm-lock.yaml จะช่วยให้เห็นภาพรวมว่าใครพึ่งพาใครบ้าง
บางครั้งยังช่วยให้เราได้ dependency “ฟรี” ด้วย เช่น ถ้าโปรเจกต์มี esbuild อยู่แล้วจาก Vite หรือ Drizzle-kit การเพิ่ม esbuild เองก็ไม่ทำให้บวมขึ้น เพราะมันถูก dedupe ไปใช้ตัวเดิม (เก็บไว้เพียงครั้งเดียว และแชร์ใช้ร่วมกัน)
.
3. วัดผลกระทบด้าน “ขนาด”
เรื่องขนาดต้องมอง 2 มิติ คือ
– Bundle size ที่ผู้ใช้ต้องโหลด อาจใช้ rollup-plugin-visualizer (Vite/Rollup) หรือ Next.js bundle analyzer สำหรับโปรเจกต์ Next.js จะได้รู้ว่า dependency ไหนกินพื้นที่เยอะใน bundle
.
– ขนาด node_modules ระหว่าง dev/CI ใช้โปรแกรมวิเคราะห์ดิสก์ เช่น Grand Perspective (macOS), Baobab (Linux), WinDirStat (Windows)
โฟลเดอร์ node_modules ที่บวมมากทำให้การติดตั้งช้า การ build/test/deploy ก็ช้าไปด้วย
.
4. แนวทางการเลือก dependencies อย่างไรให้ “คุ้มค่า” โมดูลที่ดี มักจะมีส่วนประกอบเหล่านี้
– มีการ maintain ต่อเนื่อง (commit / release สม่ำเสมอ)
– มี TypeScript types ในตัว (หรือ @types ที่เชื่อถือได้)
– มี test ผ่าน
– มีเอกสาร (documentation) ครบถ้วน ใช้งานง่าย
โมดูลที่ควรเลี่ยง:
– ถูกทิ้งร้าง ไม่อัปเดต
– โค้ดคุณภาพต่ำ
– แก้ปัญหา “ผิดโจทย์” ทำให้เราต้องบิด requirement ของโปรเจกต์เพื่อให้มันทำงาน
หลักคิดคือ: แอปของคุณ = บั๊กที่คุณเขียน + บั๊กที่สืบทอดจาก dependency ดังนั้นต้องเลือกของที่ไว้ใจได้
.
5. ลบสิ่งที่ไม่ใช้ และอัปเดตอย่างต่อเนื่อง
– ใช้ Renovate (https://docs.renovatebot.com/) คอยเปิด PR ให้อัปเดต dependencies แบบต่อเนื่อง ดีกว่าปล่อยแล้วมาอัปทีเดียว (เสี่ยงเจอ breaking changes เยอะ)
– ใช้ Knip (https://knip.dev/) ค้นหา dependencies ที่ไม่ได้ใช้งานแล้ว และไฟล์ที่ไม่ถูกเรียกใช้ เพื่อทำความสะอาดโปรเจกต์
นี่คือการ “ดูแลสุขภาพ” ของโค้ด ที่ควรทำเรื่อย ๆ ไม่ใช่รอจนโปรเจกต์เริ่มเน่าแล้วค่อยมาล้าง
.
6 จำชื่อ “คนทำของดี”
ใน NPM ecosystem มีนักพัฒนาบางคนที่ปล่อยโมดูลคุณภาพสูงสม่ำเสมอ การรู้จักชื่อพวกเขาไว้ ช่วยให้คัด dependencies ได้ง่ายขึ้น ครับ เช่น:
Sindre Sorhus: เจ้าพ่อ utilities (มีทุกอย่างที่คุณคิดออก)
isaacs: ผู้ก่อตั้ง npm
Matteo Collina: เชี่ยวชาญ Node.js performance
Mafintosh: เขียนโมดูล เยอะมาก
wooorm/unified: ecosystem สำหรับ Markdown
unjs: ทีมที่ทำเครื่องมือ next-gen Node.js
Rich Harris: คนสร้าง Svelte และเครื่องมือ transpiler/bundler คุณภาพ
.
การใช้ dependency เป็นสิ่งที่ หลีกเลี่ยงไม่ได้ เราทุกคนต่างยืนอยู่บน “ไหล่ของกันและกัน” แต่เรามีสิทธิ์เลือกได้ว่าจะยืนบนไหล่ที่มั่นคง หรือไหล่ที่พร้อมจะสั่นคลอน
การดูแล dependencies ไม่ใช่งานจิปาถะหรือไม่จำเป็น แต่มันคือรากฐานสำคัญของการพัฒนาซอฟต์แวร์ที่มีคุณภาพนั่นเองครับ