4 คะแนน โดย GN⁺ 2024-05-02 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Extension.js คือ CLI สำหรับสร้างเว็บเอ็กซ์เทนชันสำหรับ Chrome, Edge และ Firefox โดยเริ่มพัฒนาได้ด้วยเพียง npx extension@latest create my-extension และ npm run dev
  • มีเป้าหมายเพื่อลดความซับซ้อนของ การแตกย่อยของ Manifest V3, ความแตกต่างระหว่างเบราว์เซอร์, การไม่มี hot reload สำหรับ content script และ build pipeline แยกตามเป้าหมาย ให้เหลือเป็น ขั้นตอนพัฒนาแบบไม่ต้องตั้งค่า
  • รองรับ Hot Module Replacement สำหรับสคริปต์ background, content, popup และ options พร้อมรองรับ React, Vue, Svelte, Preact และ TypeScript เป็นพลเมืองชั้นหนึ่ง
  • สามารถสร้าง ZIP สำหรับ production เพื่อส่งขึ้น Chrome Web Store, Edge Add-ons และ Firefox AMO ได้ด้วย extension build --zip และยัง build แยกตามเบราว์เซอร์ได้ เช่น --browser=firefox
  • สามารถนำไปใช้กับเอ็กซ์เทนชันที่มีอยู่แล้วได้ โดยเพิ่ม extension@latest เป็น development dependency แล้วเชื่อมสคริปต์ build, dev, preview

ปัญหาที่ Extension.js พยายามแก้

  • Extension.js เป็นเครื่องมือ CLI สำหรับสร้างเอ็กซ์เทนชัน Chrome, Edge และ Firefox
  • ขั้นตอนการใช้งานพื้นฐานคือสร้างโปรเจ็กต์ใหม่แล้วรัน development server
    • npx extension@latest create my-extension
    • cd my-extension
    • npm run dev
  • ใช้งานได้กับ npm, pnpm, yarn, bun
  • มีเอกสาร เทมเพลต และตัวอย่างให้ที่ Documentation, Templates, Examples

ประสบการณ์การพัฒนาและความสามารถหลัก

  • มุ่งลดปัญหา การแตกย่อยของ Manifest V3, ความต่างระหว่างเบราว์เซอร์, การไม่มี hot reload สำหรับ content script และปัญหา build pipeline แยกตามเป้าหมายในการพัฒนา browser extension
  • Hot Module Replacement ใช้ได้กับสคริปต์ background, content, popup และ options
    • รวมถึงคอมโพเนนต์ React, Vue, Svelte, Preact
  • ใช้ Manifest V3 เป็นค่าเริ่มต้น และมี adapter อัตโนมัติสำหรับเป้าหมาย Chrome, Edge และ Firefox
  • ใช้ CLI เดียวเพื่อรันกับ Chrome, Edge, Firefox รวมถึงไบนารีที่อิง Chromium หรือ Gecko ได้
  • มุ่งสู่ zero config โดยไม่ต้องมี webpack, rollup หรือปลั๊กอินที่ต้องคอยดูแล
  • รองรับ TypeScript, React, Vue, Svelte, Preact เป็นพลเมืองชั้นหนึ่ง
  • ใช้ extension build --zip เพื่อสร้าง production build สำหรับส่งขึ้น Chrome Web Store และ Firefox Add-ons ได้
  • เพิ่มเข้าไปในเอ็กซ์เทนชันเดิมได้ในรูปแบบ devDependency เดียว

ความแตกต่างจากเครื่องมือพัฒนาเอ็กซ์เทนชันตัวอื่น

  • สำหรับผู้ใช้ที่เคยใช้ Plasmo, WXT, CRXJS มีการอธิบายความต่างของ Extension.js แยกตามความสามารถ
  • สามารถรันตัวอย่างจาก GitHub ได้โดยตรง
  • มีไบนารีเบราว์เซอร์แบบจัดการให้
    • ตัวอย่าง: extension install firefox จะดาวน์โหลด Firefox build แบบแยกสภาพแวดล้อม
  • มี cross-browser HMR สำหรับ content script ในตัว โดยไม่ต้องต่อปลั๊กอินเพิ่ม
  • สร้าง production ZIP สำหรับส่งขึ้นสโตร์ได้
    • ตัวอย่าง: extension build --zip
  • ไม่ผูกกับเฟรมเวิร์กใดเฟรมเวิร์กหนึ่ง
  • สามารถระบุไบนารี Chromium และ Gecko แบบกำหนดเองได้
    • --chromium-binary
    • --gecko-binary

เฟรมเวิร์กและเบราว์เซอร์ที่รองรับ

  • มีเทมเพลตหรือตัวอย่างสำหรับเฟรมเวิร์กที่รองรับและตัวอย่างการใช้งาน
  • ใช้แฟล็กเกี่ยวกับเบราว์เซอร์ได้ใน extension dev, extension start, extension preview
    • เลือกเบราว์เซอร์ด้วย --browser <chrome | edge | firefox>
    • ระบุ Chromium binary แบบกำหนดเองด้วย --chromium-binary <path-to-binary>
    • ระบุ Gecko หรือ Firefox binary แบบกำหนดเองด้วย --gecko-binary <path-to-binary>
  • เบราว์เซอร์ที่รองรับคือ Google Chrome, Microsoft Edge, Mozilla Firefox, เบราว์เซอร์สาย Chromium และสาย Gecko
  • Apple Safari ถูกระบุเป็น Next

การ build, แพ็กเกจ และเบราว์เซอร์แบบจัดการ

  • รัน production build ได้ด้วย npx extension@latest build
  • สร้างแพ็กเกจ ZIP สำหรับส่งขึ้นสโตร์ด้วย npx extension@latest build --zip
  • รองรับการ build แยกตามเบราว์เซอร์
    • ตัวอย่าง: npx extension@latest build --browser=firefox --zip
  • มี build flag ที่เป็นประโยชน์ให้ใช้งาน
    • --zip: แพ็กเป็น ZIP สำหรับอัปโหลดขึ้นสโตร์
    • --zip-source: รวม source file เพื่อให้สโตร์ตรวจสอบซอร์สโค้ด
    • --zip-filename <name>: ควบคุมชื่อไฟล์เอาต์พุต
    • --polyfill: เปิดใช้ cross-browser webextension polyfill
  • Extension.js สามารถดาวน์โหลดและจัดการ ไบนารีเบราว์เซอร์แบบแยกสภาพแวดล้อม เพื่อให้ได้เซสชันพัฒนาที่สะอาด
    • npx extension@latest install firefox
    • npx extension@latest install --browser=all
    • npx extension@latest install --where

การใช้งานกับเอ็กซ์เทนชันเดิมและการรันตัวอย่าง

  • สำหรับเอ็กซ์เทนชันที่มีอยู่แล้ว ให้ติดตั้งเป็น development dependency
    • npm install extension@latest --save-dev
  • สามารถเชื่อม extension build, extension dev, extension preview เข้ากับสคริปต์ใน package.json
    • npm run dev: พัฒนา
    • npm run build: production build
    • npm run preview: ตรวจสอบผลลัพธ์ production
  • สามารถดึงและรันตัวอย่างจาก Chrome Extension Samples ได้โดยตรง
  • มีชุมชนและตัวอย่างที่ Discord, GitHub issues, examples
  • ไลเซนส์คือ MIT

1 ความคิดเห็น

 
GN⁺ 2024-05-02
ความคิดเห็นจาก Hacker News
  • โปรเจกต์เจ๋งดี กำลังคิดว่าจะลองใช้กับส่วนขยายของผม(https://github.com/herrherrmann/omnivore-list-popup)
    จนถึงตอนนี้ผมจัดการการ build ส่วนขยายหรือโหมดพัฒนาด้วยสคริปต์เอง แต่ก็เคยดูอยู่ว่าอาจทำให้สะดวกด้วย web-ext ได้หรือไม่
    แต่เบราว์เซอร์หลักของผมคือ Firefox และดูเหมือนว่า Extension.js ยังไม่รองรับ Firefox อย่างสมบูรณ์

    • Mozilla Add-On สามารถรันบน Chrome หรือ Edge ได้ด้วยการใส่แฟล็ก --polyfill แต่ตอนนี้บน Firefox ยังต้องเพิ่มส่วนขยายด้วยตนเอง
      มีแผนจะเพิ่ม การรองรับ Firefox ในเร็ว ๆ นี้ แต่ตอนนี้ยังไม่มีตัวเรียกใช้งานเบราว์เซอร์
  • นี่คือเครื่องมือที่ต้องการพอดี ขอบคุณที่สร้างและแชร์ และหวังว่า การรองรับ Firefox จะออกมาดี
    issue เรื่องการรองรับ Firefox: https://github.com/cezaraugusto/extension.js/issues/5

    • โดยเฉพาะถ้าช่วยจัดการข้อกำหนดที่ขัดกันใน manifest.json ได้ก็คงดี
      เช่น ความแตกต่างระหว่าง event page กับ background service worker หรือกรณีที่สิทธิ์ที่แต่ละเบราว์เซอร์ต้องการหรือห้ามใช้ไม่สอดคล้องกัน
    • ถ้าเพิ่มรายละเอียดใน issue เรื่องการรองรับ Firefox บน GitHub ได้ก็คงดี ชุมชนอาจช่วยแก้ได้
  • งงนิดหน่อย ผมเคยเขียนส่วนขยายสำหรับ Chrome โดยเฉพาะด้วย JavaScript มาแล้ว จุดเริ่มต้นก็แค่คัดลอกไฟล์ไม่กี่ไฟล์จากเว็บเอกสารส่วนขยายของ Chrome
    ไม่ได้ตั้งค่า IDE อะไรเป็นพิเศษ และก็ไม่ค่อยรู้ว่าต้องทำอะไรด้วย
    อยากเข้าใจว่าเครื่องมือนี้ทำอะไรให้มากกว่าการคัดลอกไฟล์ไม่กี่ไฟล์บ้าง สงสัยว่าเป็น การรองรับข้ามเบราว์เซอร์ หรือรองรับหลายภาษาหรือเปล่า

    • ในกรณีแบบนั้น Extension.js ช่วยจัดการ รายละเอียดการตั้งค่า ที่มักพลาดได้ง่ายในการพัฒนาเว็บทั่วไป
      หลังจากคัดลอกไฟล์ไม่กี่ไฟล์จากเอกสารส่วนขยายของ Chrome แล้ว คุณต้องเปิด “โหมดนักพัฒนา” ในเบราว์เซอร์เองและเพิ่มไฟล์เข้าไปเอง เมื่อแก้โค้ด ก็ต้องรีเฟรช execution context หลายจุดที่ส่วนขยายเบราว์เซอร์มีผลด้วยตนเอง จึงจะเห็นการเปลี่ยนแปลง ถ้าจะทดสอบบนหลายเบราว์เซอร์ก็ต้องทำขั้นตอนนี้ซ้ำในแต่ละตัว
      หากต้องการใช้ package dependency อย่าง TypeScript หรือ JavaScript framework ก็ต้องพึ่ง framework abstraction สำหรับส่วนขยายที่มีอยู่แล้วและเรียนรู้วิธีใหม่ หรือไม่ก็ตั้งค่าเองด้วยเครื่องมืออย่าง webpack, Parcel, esbuild พอถึงจุดนี้ การพัฒนาส่วนขยายเบราว์เซอร์อาจซับซ้อนและน่าหงุดหงิดได้
      Extension.js ทำให้เรื่องนี้ง่ายขึ้นโดยอัตโนมัติกระบวนการ bundle และรันส่วนขยายในเบราว์เซอร์สำหรับพัฒนา รองรับ การรีเฟรชอัตโนมัติ ในทุก execution context รวมถึงพื้นที่ของเบราว์เซอร์ที่ไม่ใช่ HTML/CSS/JavaScript และรองรับ code dependency อย่าง TypeScript และ React เพียงติดตั้งก็ใช้ได้โดยไม่ต้องมีเวทมนตร์ด้านการตั้งค่าเพิ่มเติม ทั้งยังรันพร้อมกันได้บนหลายเบราว์เซอร์
  • โปรเจกต์ดี ส่วนขยาย Chrome ตัวแรกของผมทำด้วย https://crxjs.dev/vite-plugin/getting-started แต่ต้องลงแรงเยอะกว่าจะทำให้ style ทำงานได้ถูกต้อง
    อาจเป็นเพราะเป็น การพัฒนาส่วนขยายเบราว์เซอร์ ครั้งแรกของผมก็ได้: https://chromewebstore.google.com/detail/bettermenu-for-door...
    ยังมีงานต้องทำอีกเยอะ เลยตั้งใจว่าจะลองดูโปรเจกต์นี้ด้วย

  • เจ๋งมาก README ก็ทำออกมาสวยงามดีมาก
    ผมเลื่อนการเพิ่มส่วนขยายให้แอปออกไป เพราะ Google Play เละเทะเหลือเกิน แต่คิดว่าจะลองใช้ตัวนี้ดู

  • เจ๋งดี อยากรู้ว่าเมื่อเทียบกับ Plasmo ซึ่งเป็น framework คล้าย ๆ กันแล้วเป็นอย่างไร
    https://www.plasmo.com/

    • ผมมองว่าความแตกต่างใหญ่ที่สุดคือ Plasmo เป็น framework กล่าวคือถ้าจะสร้างส่วนขยายใหม่ ก็ต้องเรียนรู้ abstraction ของมัน และพึ่งพาตัวอย่างที่ทำตาม abstraction นั้น
      ยังต้องทำตามไฟล์ตั้งค่าและกฎเฉพาะบางอย่างที่ไม่ได้เกี่ยวข้องกับตัวส่วนขยายเบราว์เซอร์โดยตรงเสมอไป
      ในทางกลับกัน Extension.js ทำให้สร้างส่วนขยายด้วย API มาตรฐานของส่วนขยายได้ และ abstract เฉพาะไฟล์ตั้งค่าเท่านั้น ไม่จำเป็นต้องเรียนรู้รายละเอียดเฉพาะของเครื่องมือ ดังนั้นถ้าตัวอย่างจาก Chrome หรือ MDN ทำงานโดยยึดไฟล์ manifest เป็นเกณฑ์เดียว ก็ไม่ต้อง refactor เพื่อใช้กับ Extension.js ทำให้เริ่มโปรเจกต์ใหม่และทำ prototype ได้ง่ายขึ้น
    • Plasmo ดูมีประโยชน์มาก อยากรู้ว่าเคยใช้พัฒนาส่วนขยายจริง ๆ หรือเปล่า
  • เคยทำส่วนขยายมาหลายตัว ตัวหนึ่งทำเล่น ๆ คือส่วนขยายที่เปลี่ยนสีหัวใจของ imgur ตอนที่ทุกคนไม่พอใจหลังจาก imgur เปลี่ยนสีนั้น
    ทุกครั้งที่ทำส่วนขยาย Chrome จะรู้สึก impostor syndrome หนักมาก แปลกดีที่การสร้างโปรเจกต์ใหม่มันยากเหลือเกิน ถ้ามีเครื่องมือแบบนี้คงดีมาก

    • เห็นด้วยสุด ๆ ผมคิดว่าการพัฒนาส่วนขยายควรจะสนุกไม่ใช่เหรอ หวังว่า Extension.js จะช่วยในโปรเจกต์ถัดไปได้
  • ชอบนะ อยากให้โปรยเวทมนตร์ใส่ การสื่อสารระหว่างส่วนขยายกับแท็บ ด้วย
    ทุกครั้งที่ทำส่วนขยาย กระบวนการอ่าน DOM หรือส่งข้อความจากส่วนขยายไปยังแท็บที่ active อยู่มักทรมานเสมอ

    • Plasmo มี messaging library ที่น่าลองดู
      https://docs.plasmo.com/framework/messaging
    • ตอนนี้ยังไม่มีในแผน แต่ระหว่างนี้ผมมั่นใจว่าน่าจะมี library ดี ๆ บน npm อยู่บ้าง
    • อยากรู้ว่าช่วงไหนของกระบวนการนี้ที่น่าหงุดหงิดหรือชวนสับสนเป็นพิเศษ ช่วยแชร์เพิ่มได้ไหม
  • เพิ่ม issue ไปแล้วหนึ่งรายการ การรองรับ Safari น่าจะค่อนข้างตรงไปตรงมาถ้าใช้เครื่องมือ CLI safari-web-extension-converter ของ Apple

  • ดูดีเลย จะลองใช้กับส่วนขยายของผม Vim for Docs
    เสียดายที่ยังไม่รองรับ Firefox แต่เอาเข้าจริงก็ไม่ได้มีเครื่องมือ build ส่วนขยายที่รองรับทั้ง Firefox และเบราว์เซอร์บน Chromium อยู่แล้ว

    • การรองรับ Firefox จะมาในการอัปเดตถัดไป รอติดตามได้เลย