Now.js Framework Documentation
Bundle ของโปรเจ็ค — แยกโค้ดเฉพาะโปรเจ็คออกจาก Now/
Bundle ของโปรเจ็ค — แยกโค้ดเฉพาะโปรเจ็คออกจาก Now/
ภาพรวม
โฟลเดอร์ Now/ (ซอร์ส Now/js, Now/css และบันเดิล Now/dist) กับ vite.config.js เหมือนกันทุกโปรเจ็ค
แก้ที่ต้นทาง (nowjs → adminframework) แล้วกระจายไปทุกโปรเจ็ค ห้ามมีไฟล์ของโปรเจ็คใดโปรเจ็คหนึ่งปนอยู่
โค้ดที่โปรเจ็คเดียวใช้และต้อง build เป็นบันเดิลของตัวเอง (เช่น designer, timeline) ให้อยู่ที่
js/components/<ชื่อ>/
├── build.json ← บอก vite ว่าจะ build อย่างไร
├── entry.js ← จุดเริ่มของบันเดิล (import ไฟล์อื่นและ CSS)
├── *.js · *.css ← ซอร์สของบันเดิล
js/dist/ ← ผลการ build ของทุกบันเดิลในโปรเจ็คนี้ไม่ต้องแก้ vite.config.js — เมื่อสั่ง BUILD_TARGET=<ชื่อ> แล้วไม่ใช่บันเดิลของ Now.js
vite จะอ่าน js/components/<ชื่อ>/build.json เองและ build ลง js/dist/
build.json
{
"entry": "entry.js",
"name": "now.timeline.min.js",
"css": "now.timeline.min.css",
"libName": "NowTimeline"
}| คีย์ | ความหมาย |
|---|---|
entry |
ไฟล์เริ่มต้น เทียบกับโฟลเดอร์ของบันเดิล (ไม่ใส่ = entry.js) |
name |
ชื่อไฟล์ JS ใน js/dist/ |
css |
ชื่อไฟล์ CSS ใน js/dist/ (มีเมื่อ entry import CSS) |
libName |
ชื่อ global ของ IIFE — export default ของ entry จะอยู่ที่ window[libName] |
ชื่อโฟลเดอร์ต้องไม่ซ้ำกับบันเดิลของ Now.js (core, table, graph, serviceworker, queue,
eventcalendar, editor, formbuilder, syntaxhighlighter) เพราะชื่อเหล่านั้นถูกใช้ก่อนเสมอ
คำสั่ง build
เพิ่ม script ใน package.json ของโปรเจ็คนั้น (ไฟล์นี้ต่างกันได้ในแต่ละโปรเจ็ค)
"build:timeline": "cross-env BUILD_TARGET=timeline vite build"แล้วต่อท้าย "build" ด้วย && npm run build:timeline ถ้าต้องการให้ build พร้อมกันทั้งหมด
บันเดิลของ Now.js ใช้ emptyOutDir ล้าง Now/dist ทุกครั้งที่ build core ส่วน js/dist ไม่ถูกล้าง
บันเดิลของโปรเจ็คจึงไม่หายตอน build core หรือตอนกระจาย Now/ ใหม่
การโหลดบันเดิล
index.php เป็นไฟล์กลางที่เหมือนกันทุกโปรเจ็ค จึงไม่โหลดบันเดิลของโปรเจ็ค —
ให้โมดูลที่ใช้โหลดเองจาก admin.js ของตัวเอง และส่ง ?v= ของ admin.js ต่อให้บันเดิล
(service worker เสิร์ฟไฟล์ .js ที่ไม่มี query แบบ cache-first ไฟล์ที่ build ใหม่จะไม่ถูกโหลด)
const docDesignerBundle = (() => {
const src = document.currentScript?.src || '';
const base = src.replace(/modules\/docdesigner\/admin\.js.*$/, '');
if (!base) return Promise.resolve();
const query = src.includes('?') ? src.slice(src.indexOf('?')) : '';
const css = document.createElement('link');
css.rel = 'stylesheet';
css.href = `${base}js/dist/now.docdesigner.min.css${query}`;
document.head.appendChild(css);
return new Promise((resolve, reject) => {
const js = document.createElement('script');
js.src = `${base}js/dist/now.docdesigner.min.js${query}`;
js.onload = () => resolve();
js.onerror = () => reject(new Error('Failed to load js/dist/now.docdesigner.min.js'));
document.head.appendChild(js);
});
})();
async function initDocDesigner() {
await docDesignerBundle; // หน้าอาจถูกวาดก่อนสคริปต์โหลดเสร็จ
// ...
}ตัวอย่างที่ใช้งานจริง
| โปรเจ็ค | บันเดิล | ผลลัพธ์ |
|---|---|---|
| project_manager | js/components/timeline/ (entry import ซอร์สจาก modules/project/timeline/) |
js/dist/now.timeline.min.* |
| form | js/components/docdesigner/ |
js/dist/now.docdesigner.min.* |
| gcms.in.th | js/components/designer/ |
js/dist/gcms.designer.min.* |
| bluprint.in.th | js/components/migration/ (ใช้ @e965/xlsx) |
js/dist/now.migration.min.js |