0Pricing
React Academy · บทเรียน

เอาต์พุตแพ็กเกจคู่ ESM และ CJS

สร้างบิลด์ทั้งแบบโมดูล ES และ CommonJS พร้อมกำหนดค่าฟิลด์ exports ใน package.json อย่างถูกต้อง

เอาต์พุตแพ็กเกจคู่ ESM และ CJS เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

ESM คืออะไร

ESM (ECMAScript Modules) คือมาตรฐานโมดูล JavaScript อย่างเป็นทางการที่ใช้ไวยากรณ์ import และ export ESM สามารถวิเคราะห์แบบสถิตได้ ตัวรวมบันเดิลจึงระบุได้ตั้งแต่เวลาสร้างอย่างแน่ชัดว่ามีการใช้งานการส่งออกใดบ้าง ทำให้สามารถตัดส่วนที่ไม่ใช้งานได้ เบราว์เซอร์สมัยใหม่และ Node.js ต่างก็รองรับ ESM โดยตรง

CJS คืออะไร

CJS (CommonJS) ใช้ไวยากรณ์ require() และ module.exports เป็นระบบโมดูลดั้งเดิมของ Node.js และยังจำเป็นสำหรับความเข้ากันได้กับสภาพแวดล้อม Node.js รุ่นเก่า Jest ซึ่งเดิมใช้ CJS และโค้ดที่ใช้ require() CJS จะถูกประเมินแบบไดนามิก ทำให้การตัดส่วนที่ไม่ใช้งานทำได้ยากขึ้น

แพ็กเกจสองรูปแบบ: เผยแพร่ทั้งสองรูปแบบ

แพ็กเกจ npm สมัยใหม่ควรเผยแพร่ทั้ง ESM และ CJS เพื่อให้เข้ากันได้สูงสุด ผู้ใช้ ESM เช่น Vite, Next.js และตัวรวมบันเดิลสมัยใหม่ จะได้รับการนำเข้าที่สามารถตัดส่วนที่ไม่ใช้งานได้ ส่วนผู้ใช้ CJS เช่น สคริปต์ Node.js รุ่นเก่าและ Jest ที่ไม่ได้กำหนดค่า จะได้รับความเข้ากันได้กับ require() ฟิลด์ exports ใน package.json จะบอก Node และตัวรวมบันเดิลว่าควรใช้รูปแบบใด

ฟิลด์ exports

ฟิลด์ exports ใน package.json เป็นวิธีสมัยใหม่ในการกำหนดจุดเริ่มต้นแบบมีเงื่อนไข ตัวอย่างเช่น { '.': { 'import': './dist/esm/index.js', 'require': './dist/cjs/index.js', 'types': './dist/esm/index.d.ts' } } ตัวรวมบันเดิลและ Node.js 12 ขึ้นไปจะอ่าน exports เพื่อเลือกรูปแบบที่ถูกต้องโดยอัตโนมัติ

ฟิลด์ main และ module รุ่นเก่า

เครื่องมือรุ่นเก่าไม่เข้าใจฟิลด์ exports เพื่อความเข้ากันได้ ให้กำหนดค่าต่อไปนี้ด้วย: main ให้ชี้ไปยังผลลัพธ์ CJS เพื่อเป็นทางเลือกสำรองสำหรับ require ของ Node รุ่นเก่า และ module ให้ชี้ไปยังผลลัพธ์ ESM เพื่อเป็นคำแนะนำสำหรับ webpack/rollup ซึ่งไม่ใช่มาตรฐานแต่รองรับกันอย่างแพร่หลาย เครื่องมือสมัยใหม่จะให้ความสำคัญกับ exports ส่วนเครื่องมือรุ่นเก่าจะใช้ main/module เป็นทางเลือกสำรอง

ผลของ type: module

การตั้งค่า "type": "module" ใน package.json จะทำให้ไฟล์ .js ทั้งหมดในแพ็กเกจถูกปฏิบัติเสมือนเป็น ESM หากคุณเผยแพร่สองรูปแบบ คุณจะต้องใช้ส่วนขยายอย่างชัดเจน โดยใช้ .mjs สำหรับไฟล์ ESM และ .cjs สำหรับไฟล์ CJS เมื่อ type เป็น module หรือใช้ในทางกลับกัน tsup จะจัดการเรื่องนี้ให้โดยอัตโนมัติ

.mjs และ .cjs

การใช้ส่วนขยายไฟล์ .mjs (ESM) และ .cjs (CJS) จะระบุรูปแบบอย่างชัดเจนโดยไม่ขึ้นกับฟิลด์ type จึงช่วยหลีกเลี่ยงความกำกวม tsup สามารถสร้างผลลัพธ์เป็น index.js (ESM) และ index.cjs (CJS) เมื่อ format เป็น ['esm', 'cjs'] และไม่ได้ตั้งค่าฟิลด์ type ซึ่งตรงกับรูปแบบที่ใช้กันทั่วไปที่สุด

อันตรายจากแพ็กเกจสองรูปแบบ

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

การลดอันตรายจากแพ็กเกจสองรูปแบบ

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

การทดสอบผลลัพธ์สองรูปแบบ

ตรวจสอบว่าทั้งสองรูปแบบทำงานได้หลังการสร้าง ทดสอบ CJS ด้วย node -e "const lib = require('./dist/cjs/index.js'); console.log(lib)" ทดสอบ ESM ด้วย node --input-type=module --eval "import { Component } from './dist/esm/index.js'; console.log(Component)" ทั้งสองรูปแบบควรแก้ไขการอ้างอิงได้โดยไม่มีข้อผิดพลาดก่อนเผยแพร่

ฟิลด์ exports สำหรับจุดเริ่มต้นหลายจุด

ฟิลด์ exports รองรับจุดเริ่มต้นหลายจุด: { '.': { import: './dist/esm/index.js', require: './dist/cjs/index.js' }, './utils': { import: './dist/esm/utils.js', require: './dist/cjs/utils.js' } } จากนั้นผู้ใช้สามารถนำเข้าจาก 'your-lib' หรือ 'your-lib/utils' และจะได้รับรูปแบบที่ถูกต้อง

ฟิลด์ exports ใน package.json

จุดประสงค์หลักของฟิลด์ exports ใน package.json ของไลบรารีคืออะไร

สรุปบทเรียน: ผลลัพธ์แพ็กเกจสองรูปแบบ

ESM ใช้ import/export และช่วยให้ตัดส่วนที่ไม่ใช้งานได้ CJS ใช้ require() เพื่อความเข้ากันได้กับ Node.js ให้เผยแพร่ทั้งสองรูปแบบผ่านฟิลด์ exports ใน package.json โดยใช้เงื่อนไข import/require ทางเลือกสำรองสำหรับเครื่องมือรุ่นเก่า ได้แก่ main (CJS) และ module (ESM) ใช้ส่วนขยาย .mjs/.cjs หรือ type: module เพื่อระบุรูปแบบอย่างชัดเจน ทดสอบทั้งสองรูปแบบด้วย CLI ของ node หลังการสร้าง และระวังอันตรายจากแพ็กเกจสองรูปแบบเมื่อมีสถานะซิงเกิลตัน

คำถามที่พบบ่อย

บทเรียน “เอาต์พุตแพ็กเกจคู่ ESM และ CJS” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เอาต์พุตแพ็กเกจคู่ ESM และ CJS” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เอาต์พุตแพ็กเกจคู่ ESM และ CJS”

สร้างบิลด์ทั้งแบบโมดูล ES และ CommonJS พร้อมกำหนดค่าฟิลด์ exports ใน package.json อย่างถูกต้อง คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “เอาต์พุตแพ็กเกจคู่ ESM และ CJS” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การบันเดิลด้วย Rollup และ tsup สำหรับไลบรารี
  2. เอาต์พุตแพ็กเกจคู่ ESM และ CJS
  3. สิ่งที่ต้องพึ่งพาแบบเพียร์และการตัดต้นไม้
  4. การเผยแพร่ไปยัง npm และการกำหนดเวอร์ชันเชิงความหมาย
← กลับไปที่ React Academy