Angular ว่าด้วยเรื่อง Build

 bb

Working Software คือ เป้าหมาย

สำหรับการพัฒนา Software มันจะมีขั้นตอนในการแปลง source code และ resources ต่างๆให้ออกมาเป็น “ของ” ที่พร้อมที่จะ deploy เป็นระบบที่ทำงานได้จริง (Working Software) เราเรียกกระบวนการนี้ว่า การ “build” ซึ่งไอ้การ build แต่ละครั้งเราก็มีเหตุผลที่ต่างกันไปเช่น เพื่อทดสอบระหว่างการพัฒนา เพื่อให้ QA ทดสอบ UAT หรือ Go live ใช้งานจริงๆ

สำหรับ Angular เรานิยมใช้ Angular CLI เพื่อช่วยทั้งสร้างโปรเจค สร้าง source code และแน่นอนรวมทั้ง build ของด้วย เราจะไปดูว่ามันจะช่วยเรา build ได้แบบไหน ยังไงบ้าง 🙂

แล้ว Angular CLI มี build แบบไหนบ้าง ?

ปกติเราจะ build ตาม environment ต่างๆกันไปตามที่ออกแบบ เช่นอาจจะแบ่งเป็น alpha, beta, prod แต่ถ้าจะให้แยกตามลักษณะ output ที่ออกมาจะแยกออกเป็น 2 แบบคือแบบ dev กับ prod การทดลองนี้จะลอง ng new ngdemo โง่ๆขึ้นมาตัวนึง แล้วมาลอง build ดูกันว่าจะได้ผลกันยังไง

Build สำหรับการพัฒนาระบบ

ng buld —dev

Screen Shot 2560-06-19 at 11.29.53 PM

Screen Shot 2560-06-19 at 11.32.53 PM

เวลาเรา build ด้วย option นี้ เราจะได้ประโยชน์คือเราจะได้ source mapping มาด้วย (สังเกตุขนาดไฟล์ vendor.bundle.js ที่ได้มาหลัก MB เลย) ดังนั้นเวลาเราพัฒนาแล้วเกิดเจอ error อะไรมันก็ยังกลับจุดทีมีปัญหาได้ว่ามาจากตรงไหนไฟล์ไหนนั้นเอง

Build สำหรับใช้งานจริง

ng build —prod

Screen Shot 2560-06-19 at 11.34.59 PM

Screen Shot 2560-06-19 at 11.35.26 PM

สิ่งแรกที่อยากให้สังเกตคือจะเห็นว่าขนาดไฟล์ลดขนาดไปพอควร โดยเฉพาะ vendor.xxx.bundle.js ลดลงจากหลัก MB ไปหลัก 3xx kB เพราะการ build ด้วย option นี้จะตัดสวนของ source mapping ออกไปนั้นเอง

อย่างที่สองที่อยากชวนดูคือ ชื่อไฟล์ มันจะมีตัวอักษรแปลกๆแปะมาระหว่างชื่อไฟล์ ตัวอักษรแปลกๆพวกนี้คือ hashing ที่ได้จากไฟล์นั้นๆ ถ้าไม่มีการแก้ไขในไฟล์ hash ที่ได้ก็จะได้เลขเดิมเสมอ ซึ่งมันจะช่วยในเรื่อง browser caching นั้นเอง

ต่อมาที่น่าสนใจคือ styles.bundle.js ถูก extract ออกมากลายมาเป็น styles.xxx.bundle.css แทน ก็เพื่อใช้แสดงผลตามปกติของ css ที่มันควรจะเป็น

นอกจากนี้เวลา build แบบ prod นี้ยังมีเรื่องการ Ahead-of-Time Compilation อีก ดังนั้นเวลาเราต้องการ build ของสำหรับใช้งานจริงควรจะใช้ option นี้

ตารางเปรียบเทียบ –dev กับ –prod

Flag --dev --prod
--aot false true
--environment dev prod
--output-hashing media all
--sourcemaps true false
--extract-css false true

สรุป

ก็น่าจะเห็นภาพมาขึ้นสำหรับเรื่องการ build โปรเจคทั้ง 2 แบบด้วย ng build ของ Angular CLI เหมือนเดิมครับ ถ้าใครมีเทคนิคแจ่มๆเอามาแบ่งกันได้นะครับ สวัสดีครับ (-/\-)

อ้างอิง : https://github.com/angular/angular-cli/wiki/build

Advertisements

เพิ่มความสนุกในการเขียน Angular ด้วย HMR (Hot Module Replacement)

299673_10151471144320809_1119982299_n

ปัญหาในการพัฒนา Angular

ผมเคยฟัง คุณจั๊ว ในหัวข้อ Hyper Productivity ด้วยสมองผมที่มีรอยหยักจำกัดเลยจำอะไรไม่ค่อยได้มากนัก แต่สิ่งที่จำได้ลางๆ คือ

การทำงานมันจะอยู่ในสภาวะไหลลื่น(Flow) นั้นการตอบสนอง(Feedback loop) ต้องสั้นทันใจ

การพัฒนาระบบก็เหมือนกันถ้าเรารู้ว่าสิ่งที่เราแก้ไขไปมันถูกต้องได้ไวขึ้นมันก็น่าจะทำให้ Productivity ดีขึ้นด้วย กลับมาที่ Angular ปัญหาอย่างนึงที่พบเวลาพัฒนาคือเวลาเราแก้ไขอะไรแม้จะเล็กน้อยมันจะต้อง reload ทั้งหน้า ซึ่งปัญหานี้แหละครับที่เราจะเอาเจ้า HMR มาช่วย

เริ่มที่ CLI

ในบทความนี้จะเป็นการใช้ HMR ร่วมกับเครื่องมือยอดนิยมของ Angular นั้นก็คือ Angular CLI นั้นเอง ดังนั้นเริ่มเลยครับ

ng new hmr-demo

hmr-demo-02

หลังจากนั้นก็แวะไปดื่มกาแฟ เข้าห้องน้ำ ดูหน้ากากนักร้องย้อนหลังไปซักแป๊บ ก็จะได้โปรเจค hmr-demo ที่พร้อมว่าแล้วก็ลอง run ซักดอกนึงก่อนครับว่ามันโอเคไหมด้วย

ng serve

hmr-demo-01
โอเคดูเรียบร้อยดีต่อมาเราจะมาเริ่ม configuration กัน

Environment สำหรับ HMR

ปกติเวลาเราพัฒนาระบบเราก็จะมีการแยก environment เป็นไปตามเงื่อนไขต่างๆกันเเช่นเป็น dev, uat หรือ prod ตัว HMR เราก็จะแยก environment ออกมาเหมือนกัน เพราะถ้าเราไป Hot Module replace กับที่ prod ก็อาจจะไม่เหมาะเท่าไหร่ โอเคเรามาเริ่มกัน เริ่มจากสร้างไฟล์ environment.hmr.ts แล้วเพิ่มส่วนของ hmr ลงไปเป็น true อย่างงี้

hmr-demo-03

ส่วน environment อื่นๆที่ไม่ใช่ hmr เราก็จะ set เป็น false ให้หมดแบบนี้เป็นต้น

hmr-demo-04

ต่อมาส่วนที่เราจะไป set เพิ่มเวลาเราเพิ่ม environment ขึ้นมาก็คือ .angular-cli.json ก็ตามนี้เลย

hmr-demo-05

Install ตัว HMR

ต่อมาก่อนที่เราจะใช้ HMR ได้เราก็ต้อง Install มันก่อนก็จาก

npm install --save-dev @angularclass/hmr

จากนั้นเราก็ไปสร้างไฟล์ที่ hmr.ts เพื่อ configuration ตัว HMR กันก็ตามนี้เลย

// src/hmr.ts
import { NgModuleRef, ApplicationRef } from '@angular/core';
import { createNewHosts } from '@angularclass/hmr';

export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
  let ngModule: NgModuleRef<any>;
  module.hot.accept();
  bootstrap().then(mod => ngModule = mod);
  module.hot.dispose(() => {
    let appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
    let elements = appRef.components.map(c => c.location.nativeElement);
    let makeVisible = createNewHosts(elements);
    ngModule.destroy();
    makeVisible();
  });
};

hmr-demo-06

เสร็จแล้วก็ไป set ใน main.ts อีกนิดเพื่อให้ตัว HMR ขึ้นมาทำงานในกรณีที่เรา run ด้วย hmr environment

// src/main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { hmrBootstrap } from './hmr';

if (environment.production) {
  enableProdMode();
}

const bootstrap = () => {
  return platformBrowserDynamic().bootstrapModule(AppModule);
};

if (environment.hmr) {
  if (module['hot']) {
    hmrBootstrap(module, bootstrap);
  } else {
    console.error('HMR is not enabled for webpack-dev-server!');
    console.log('Are you using the --hmr flag for ng serve?');
  }
} else {
  bootstrap();
}

hmr-demo-07
เมื่อเรียบร้อยดีแล้วก็ลองเลยครับ

ng serve --environment=hmr --hmr

ซึ่งถ้าตัว HMR มันทำงานก็จะขึ้นมาบอกประมาณนี้ Hot Module Replacement (HMR) is enabled for the dev server.
hmr-demo-08

พอเราแก้ไข code เช่นแก้ title เป็น Angular Developers Thailand ก็จะเปลี่ยนโดยไม่ต้อง reload ใหม่ทั้งหมด
hmr-demo-09

สรุป

ต้องออกตัวว่ายังไม่เคยลองใช้ในโปรเจคตัวเอง(แต่จะเอาไปลองเดี๋ยวนี้แหละ) แต่มีโปรเจคข้างๆของ คุณเน็ต กูโค้ดใช้อยู่ (ซึ่งก็เป็นคนเอาตัว HMR มาขายผม) แต่ดูแล้วตัว HMR จะทำให้การพัฒนาระบบด้วย Angular รวดเร็วและสนุกขึ้น ถ้าใครลองใช้กันแล้วชอบหรือติดอะไรยังมาแชร์กันได้นะครับ (-/\-)

จบปิ๊ง

เนื้อหาต้นฉบับ: Tutorial: Enable HMR in angular-cli apps