Now.js Framework Documentation
Feature bundle — ส่วนของ Now.js ที่โหลดเมื่อหน้าใช้
Feature bundle — ส่วนของ Now.js ที่โหลดเมื่อหน้าใช้
ภาพรวม
now.core.min.js ไม่รวมส่วนที่หน้าส่วนใหญ่ไม่ได้ใช้ ส่วนเหล่านี้เป็นไฟล์แยกใน Now/dist
(now.<ชื่อ>.min.js และ now.<ชื่อ>.min.css ถ้ามีสไตล์) และ core โหลดให้เองครั้งแรกที่หน้าต้องใช้
| ชื่อ | ไฟล์ | มีอะไร | โหลดเมื่อ |
|---|---|---|---|
code |
now.code.min.js + .css |
CodeEditor, CodeElementFactory |
ช่อง data-element="code" |
richtext |
now.richtext.min.js |
RichTextElementFactory |
ช่อง data-element="richtext" (ตัวแก้ไขยังเป็น richtext-editor.min.js ที่แอปโหลดเอง) |
sync |
now.sync.min.js |
SyncManager |
Now.init({sync: {enabled: true}}) |
editinplace |
now.editinplace.min.js |
EditInPlaceManager |
data-component="editinplace" |
taskmonitor |
now.taskmonitor.min.js + .css |
TaskMonitorComponent |
data-component="task-monitor" |
securityconfig |
now.securityconfig.min.js |
SecurityConfig |
Now.require('SecurityConfig') เท่านั้น |
calendar |
now.calendar.min.js |
CalendarManager |
[data-calendar] |
gallery |
now.gallery.min.js + .css |
ImageGallery |
data-component="image-gallery" |
iconpicker |
now.iconpicker.min.js |
IconPicker |
data-component="icon-picker" |
tabs |
now.tabs.min.js |
TabsComponent |
data-component="tabs" |
lineitems |
now.lineitems.min.js |
LineItemsManager |
[data-line-items] |
sortable |
now.sortable.min.js |
Sortable |
data-component="sortable", ตารางที่ลากเรียงแถว (data-row-sortable), รายการไฟล์ที่ลากเรียง |
calendar.css และ tabs.css ยังอยู่ใน now.core.min.css — ช่องวันที่ของ core ใช้สไตล์ชุดเดียวกับปฏิทิน
และ tabs.css ซ่อนแผงแท็บที่ยังไม่ได้เลือกไว้ตั้งแต่ก่อน bundle ของแท็บโหลด
หน้าที่ใช้ markup ไม่ต้องทำอะไร
markup ที่ใช้ส่วนเหล่านี้ (ตามคอลัมน์ "โหลดเมื่อ") จะโหลด bundle ของมันเอง
ทั้งที่อยู่ในหน้าตั้งแต่แรกและที่เพิ่มเข้ามาภายหลัง (หน้าที่ router โหลด, ผลของ ApiComponent, modal)
โค้ดของ core ที่ใช้ส่วนเหล่านี้ก็โหลดเองเช่นกัน — ตาราง data-row-sortable, line items ที่ผูกข้อมูลด้วย
data-attr="data:...", ช่องไฟล์ที่ลากเรียงได้
ApiComponent เริ่มโหลด bundle ที่ markup ของมันใช้ไปพร้อมกับดึงข้อมูล และวาดผลเมื่อ bundle พร้อม
api:content-rendered จึงเห็นแถวของ line items ครบแม้ bundle มาช้ากว่าข้อมูล
handler ของ data-on-load รันหลัง bundle ที่ markup ของมันใช้โหลดเสร็จ —
handler ของฟอร์มที่มี [data-line-items] จึงเรียก LineItemsManager.getInstance(table) ได้ทันที
เหมือนตอนที่ LineItemsManager ยังอยู่ใน core (ถ้า bundle โหลดไม่ได้ handler ยังรัน แต่ไม่มีส่วนนั้น)
โค้ดของแอปที่เรียกใช้ตรง ๆ: Now.require()
โค้ดที่ใช้ global ของส่วนเหล่านี้เองโดยไม่ผ่าน markup ต้องรอให้โหลดก่อน
await Now.require('Sortable');
new Sortable(list, {draggable: 'tr'});
await Now.require('SyncManager');
await SyncManager.enable();
await Now.require('CodeEditor', 'IconPicker'); // หลายตัวพร้อมกัน- รับทั้งชื่อในตาราง (
sortable) และชื่อ global ที่ bundle นั้นสร้าง (Sortable,SyncManager,CodeEditor) - คืน Promise ที่ resolve เมื่อพร้อมใช้ — bundle โหลดครั้งเดียว เรียกซ้ำกี่ครั้งก็ได้ promise เดิม
- ถ้า global มีอยู่แล้ว (หน้าที่ใส่
<script>ของ bundle เอง) resolve ทันทีโดยไม่โหลดซ้ำ - โหลดไม่สำเร็จ (ไฟล์หาย, ออฟไลน์) → reject และครั้งถัดไปจะลองใหม่
- ชื่อที่ไม่มี → reject
if (window.Sortable) หรือ typeof SyncManager !== 'undefined' อย่างเดียวไม่พอแล้ว —
ก่อนโหลด bundle เงื่อนไขนี้เป็นเท็จและงานนั้นจะเงียบหายไป
และ Chrome มี window.SyncManager ของตัวเอง (Background Sync API) บนทุกหน้า https
typeof SyncManager จึงเป็น 'function' แม้ SyncManager ของ Now.js ยังไม่ได้โหลด
manager ที่อยู่ใน bundle (CalendarManager, EditInPlaceManager, SyncManager) ได้ config ของตัวเองจาก
Now.init() เหมือน manager ของ core — Now.require('SyncManager') แล้ว SyncManager.config.syncInterval
คือค่าที่ส่งใน Now.init({sync: {syncInterval}})
ไฟล์มาจากไหน
bundle โหลดจากโฟลเดอร์เดียวกับ now.core.min.js และใช้ query เดียวกัน
หน้าที่โหลด Now/dist/now.core.min.js?v=1.2 จะโหลด Now/dist/now.tabs.min.js?v=1.2
(CDN ก็เช่นกัน) ตอน deploy จึงต้องคัดลอกทั้งโฟลเดอร์ Now/dist ไม่ใช่เฉพาะ core
ถ้า bundle อยู่ที่อื่น กำหนดด้วย Now.init({paths: {dist: '/assets/now/'}})
script ที่ core สร้างได้ nonce เดียวกับ <script> ของ core (สำหรับ CSP แบบ nonce)
ใช้งานออฟไลน์
ServiceWorkerManager ต่อ URL ของ bundle ที่ยังไม่อยู่ใน cache ท้ายรายการ precache ที่ส่งให้ service worker
หน้าแรกที่เปิดหลังติดตั้งจึงเก็บทุก bundle ไว้ และ bundle ที่เก็บแล้วไม่ถูกโหลดซ้ำทุกหน้า
ปิดได้ด้วย ServiceWorkerManager.init({precacheFeatures: false})
API
| เมธอด | คืนค่า | ใช้ทำอะไร |
|---|---|---|
Now.require(...names) |
Promise<void> |
โหลด bundle แล้วรอจนพร้อม |
Now.hasFeature(name) |
boolean |
bundle นี้โหลดแล้วหรือยัง (ไม่นับ global ของเบราว์เซอร์ที่ชื่อซ้ำ) |
Now.featureUrls() |
string[] |
URL ของทุกไฟล์ของทุก bundle (ที่ ServiceWorkerManager precache) |
Now.featuresUsedBy(root) |
string[] |
bundle ที่ markup ใน root ใช้แต่ยังไม่โหลด |
Now.features |
Object |
ตารางข้างบน: {js, css, globals, selector, elements, config} ของแต่ละชื่อ |
build
bundle ทั้งหมด build ด้วย npm run build (ต่อท้ายด้วย build:features) จาก Now/features/<ชื่อ>.js
ชื่อ target คือ feature-<ชื่อ> เช่น cross-env BUILD_TARGET=feature-tabs vite build
ห้าม build:core อย่างเดียว เพราะ core ล้าง Now/dist ก่อน build
เพิ่ม bundle ใหม่: สร้าง Now/features/<ชื่อ>.js ที่ import ไฟล์ของมัน, เอาไฟล์นั้นออกจาก Now/core-entry.js,
เพิ่มชื่อใน features ของ vite.config.js, Now.features ใน Now/Now.js และ build:features ใน package.json