ภาพรวมของ ES Modules (ESM) อย่างใกล้ชิด
npm เป็นตัวจัดการแพ็คเกจสำหรับแพลตฟอร์ม node.js JavaScript โดยวางโมดูลไว้เพื่อให้โหนดสามารถค้นหาโมดูลเหล่านั้นได้ และจัดการข้อขัดแย้งในการพึ่งพาอย่างชาญฉลาด
npm สามารถกำหนดค่าได้เพื่อรองรับกรณีการใช้งานที่หลากหลายเพื่อเผยแพร่ ค้นหา ติดตั้ง และพัฒนาโปรแกรมโหนด มีรายการคำสั่งที่ทรงพลัง
npm 8 เปิดตัวเมื่อวันที่ 7 ตุลาคม 2021 ในบทความนี้ เราจะมาดูที่ npm 8 และคาดการณ์ว่า npm 9 อาจเป็นเท่าใด
มีอะไรใหม่ใน npm 8
ไม่มีอะไรใหม่ใน npm 8 จุดประสงค์ของรีลีสนี้คือการยกเลิกการสนับสนุนสำหรับโหนดเวอร์ชันเก่า และเพื่อลบการสนับสนุนสำหรับ require('npm')
ไม่มีการเปลี่ยนแปลงที่แตกหักอื่น ๆ โดยเฉพาะอย่างยิ่ง การเปลี่ยนแปลงเหล่านี้คือ:
- ยกเลิกการรองรับโหนด 10 และ 11
- เพิ่มเพดานการสนับสนุนในโหนด 12 และ 14 เป็น LTS (
^12.13.0
/^14.15.0
) - ยกเลิกการสนับสนุนไปที่
require('npm')
- อัปเดตการอ้างอิงบางส่วนเนื่องจากการรองรับ node10 และ node 11 ที่ลดลง
มันง่ายและชัดเจน
หากคุณต้องการอัปเกรดเป็น npm 8 ตรวจสอบให้แน่ใจว่า node.js ของคุณอัปเกรดเป็นเวอร์ชัน >=12.0.0
แล้ว nvm
เป็นวิธีง่ายๆ ในการจัดการเวอร์ชันสำหรับโหนดและ npm
มีอะไรใหม่ใน npm 9?
คำร้องขอความคิดเห็น (RFC) เป็นเอกสารอย่างเป็นทางการที่ร่างโดย Internet Engineering Task Force (IETF) ซึ่งอธิบายข้อกำหนดสำหรับเทคโนโลยีเฉพาะ npm 8 เป็น RFC ที่ให้สัตยาบัน ซึ่งปัจจุบันเป็นมาตรฐานที่เป็นทางการ
RRFC ของ npm 8 กล่าวถึงข้อเสนอแนะในการเพิ่มเวอร์ชันที่รองรับเป็น ^12.20.0 || ^14.13.1 || >=16.0.0
ซึ่งจะเป็นการย้ายไปยังเวอร์ชัน node.js ที่รองรับโมดูลสไตล์ ESM เนื่องจากไม่ได้สร้าง npm 8 จึงอาจเป็นฟีเจอร์ใน npm 9
CJS กับ ESM
เราได้กล่าวถึงรูปแบบโมดูล JavaScript เช่น CJS, AMD, UMD, ESM, System และ IIFE
CommonJS (CJS) เป็นมาตรฐานที่ node.js ใช้เพื่อห่อหุ้ม JavaScript ในโมดูล CJS ใช้ฟังก์ชัน require()
และ module.exports
require()
เป็นฟังก์ชันที่สามารถใช้เพื่อนำเข้าสัญลักษณ์ไปยังขอบเขตปัจจุบันจากโมดูลอื่น คำสั่งrequire
สามารถใช้ได้ทุกที่ในโค้ด และโมดูลที่อ้างอิงจะถูกโหลดและประมวลผลพร้อมกันmodule.exports
เป็นอ็อบเจ็กต์ที่โมดูลปัจจุบันส่งคืนเมื่อจำเป็นในโมดูลอื่น
ES Modules (ESM) กลายเป็นมาตรฐานอย่างเป็นทางการที่ใช้ใน JavaScript นับตั้งแต่ ES2015 มันถูกใช้กันอย่างแพร่หลายในการพัฒนาไคลเอนต์ JavaScript TypeScript ยังถูกนำมาใช้ซึ่งเป็น superset ที่มีประเภทเพิ่มเติมอีกด้วย ESM ใช้คำสั่ง import
และ export
เพื่อจัดการโมดูล
- คำสั่ง
import
แบบคงที่สามารถใช้เพื่อนำโมดูลเข้าสู่ขอบเขตปัจจุบัน dynamicimport()
ใช้งานได้ตั้งแต่คำสั่ง ES2020 .import
สามารถใช้ได้ทุกที่ในโค้ด เนื่องจากimports
ถูกโหลดแบบอะซิงโครนัส ขอแนะนำให้วางไว้ที่ด้านบนของไฟล์ - ในทางกลับกัน คำสั่ง
export
สามารถใช้เพื่อทำให้รายการต่างๆ เป็นแบบสาธารณะได้อย่างชัดเจน
CJS เป็นค่าเริ่มต้นสำหรับโหนด
ดังที่เราได้กล่าวไปแล้ว CJS เป็นค่าเริ่มต้นสำหรับโหนด ทำตามขั้นตอนที่อธิบายไว้ใน "แอป React ที่พร้อมใช้งานจริง" เราใช้ "สร้างแอป React" เป็นตัวอย่างในการสำรวจวิธีการทำงานของเซิร์ฟเวอร์โหนด
npx create-react-app react-esm cd react-esm
ดำเนินการคำสั่ง npm run build
และไดเร็กทอรี build
ที่สร้างขึ้นจะมีโค้ดที่จะปรับใช้
Express เป็นเฟรมเวิร์กเว็บแอป Node.js ที่เรียบง่ายและยืดหยุ่นสำหรับเว็บและแอปพลิเคชันมือถือ เซิร์ฟเวอร์ Express เป็นตัวเลือกยอดนิยมในการปรับใช้บิลด์ที่ใช้งานจริง
เนื่องจาก Express เป็นส่วนหนึ่งของแอป Create React จึงไม่จำเป็นต้องติดตั้งอีกครั้ง
ตั้งค่าไฟล์การกำหนดค่าสำหรับเซิร์ฟเวอร์ Express ใน server/index.js
:
เห็นได้ชัดว่าโค้ดข้างต้นอยู่ในรูปแบบ CJS พร้อมด้วยคำสั่ง require
(บรรทัดที่ 1 และบรรทัดที่ 4)
บรรทัดที่ 2 สร้างเซิร์ฟเวอร์ Express
บรรทัดที่ 5–8 ให้บริการหน้าเว็บที่ใช้งานจริง
บรรทัด 10–12 เริ่มต้นเซิร์ฟเวอร์ Express ที่พอร์ต 8080
เรียกใช้ node server
และสามารถเข้าถึงอินเทอร์เฟซผู้ใช้ได้ที่ http://localhost:8080
ตั้งค่าโหนดให้รัน ESM
ตอนนี้เราเปลี่ยนรหัสเพื่อใช้ import
แทน require()
เรียกใช้ node server
และเราเห็นข้อผิดพลาดต่อไปนี้:
คำเตือนที่บรรทัด 10 มีสองวิธี:
- ตั้งค่า
"type": "module"
ในpackage.json
- เปลี่ยน
server/index.js
เป็นserver/index.mjs
และเรียกใช้node server/index.mjs
โซลูชันทั้งสองใช้งานได้ นี่คือการแก้ไข package.json
(บรรทัด 5):
สำหรับไฟล์ที่ไม่มีนามสกุล จะถือเป็นโมดูล CJS หากไม่มี "type"
หรือตั้งค่าประเภทเป็น "commonjs"
ในพาเรนต์ package.json
จะถือเป็นโมดูล ES หากตั้งค่า "type"
เป็น "module"
นอกจากนี้ ไฟล์ที่ลงท้ายด้วย .cjs
จะถือเป็นโมดูล CJS และไฟล์ที่ลงท้ายด้วย .mjs
จะถือเป็นโมดูล ES
เราตั้งค่า "type"
เป็น "module"
ตอนนี้โหนดถือว่าไฟล์เป็นโมดูล ES เรียกใช้ node server
อีกครั้ง:
มันไม่บ่นเกี่ยวกับ import
อีกต่อไป แต่ปัญหา __dirname
คืออะไร
__dirname
เป็นตัวแปร CJS ซึ่งไม่มีในโมดูล ES สามารถจำลองแบบได้ผ่านทาง import.meta.url
วัตถุ import.meta
เปิดเผยข้อมูลเมตาเฉพาะบริบทไปยังโมดูล JavaScript ประกอบด้วยข้อมูลเกี่ยวกับโมดูล เช่น URL ของโมดูล
แก้ไข server/index.js
ดังนี้:
เรียกใช้ node server
และโมดูล ES ทำงานได้อย่างสมบูรณ์
หรืออีกทางหนึ่ง เราสามารถใส่คำนำหน้า node:
ได้ ซึ่งในกรณีนี้จะข้ามแคชที่ต้องการ ตัวอย่างเช่น "node:path"
(บรรทัด 4) และ "node:url"
(บรรทัด 5) จะส่งคืนโมดูล "path"
และ "url"
ในตัวเสมอ
เราได้เห็นความแตกต่างบางประการระหว่าง CJS และ ESM ต่อไปนี้เป็นรายการเกี่ยวกับวิธีการแปลงไฟล์ CJS เป็นโมดูล ES:
- ไม่
require
,exports
หรือmodule.exports
—ใช้import
หรือexport
แทน - ไม่
__filename
หรือ__dirname
ใช้import.meta.url
แทน
- ไม่มีการโหลดโมดูล JSON — ใช้
import.meta.url
กับfs
แทน
- ไม่มีการโหลดโมดูลดั้งเดิม — ใช้
module.createRequire()
หรือprocess.dlopen
แทน
- ไม่
require.resolve
ใช้new URL('./local', import.meta.url)
แทน - ไม่
NODE_PATH
— ใช้สัญลักษณ์แทน - ไม่
require.extensions
— ห้ามใช้ - ไม่
require.cache
— ห้ามใช้
บทสรุป
npm 8 ยกเลิกการรองรับโหนด 10 และ 11
คุณคิดอย่างไรเกี่ยวกับ npm 9? ควรยกเลิกการรองรับเวอร์ชันโหนดที่ไม่รองรับโมดูล ES หรือไม่
หลังจากประสบปัญหากับไวยากรณ์ที่แตกต่างกันสำหรับไคลเอ็นต์และเซิร์ฟเวอร์ JavaScript ไม่ใช่เรื่องน่าตื่นเต้นหรือไม่ที่เห็นว่า ESM ได้รับสตรีมเพื่อใช้สำหรับทั้งไคลเอ็นต์และเซิร์ฟเวอร์
ถึงเวลาแล้วที่จะใช้โมดูลสไตล์ ESM ในแอปพลิเคชันโหนด
ขอบคุณที่อ่าน. ฉันหวังว่านี่จะเป็นประโยชน์ หากคุณสนใจ โปรดดูที่ บทความสื่ออื่น ๆ ของฉัน