3 คะแนน โดย GN⁺ 2023-09-11 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เว็บไซต์สแตติกโฮสต์ได้ง่าย เร็ว และดูแลรักษาน้อย ดังนั้นถ้าเป็นเว็บไซต์เรียบง่าย ก็อาจสร้างได้ด้วย Makefile ไม่กี่บรรทัด โดยไม่ต้องไปเรียนรู้ตัวสร้างเว็บไซต์แยกต่างหาก
  • โครงสร้างหลักคือคงการจัดวางไฟล์ใน source ไว้ แล้วเติม header.html เข้าไปใน HTML ส่วนไฟล์ที่เหลือก็ คัดลอกตรง ๆ ไปที่ build
  • make build จับคู่ไฟล์นำเข้าและไฟล์ส่งออกด้วย find source -type f และ patsubst แล้วใช้ กฎของ make คนละแบบกับไฟล์ .html และไฟล์ประเภทอื่น
  • การไฮไลต์หน้าปัจจุบัน, การแปลง Markdown, เซิร์ฟเวอร์โลคัล, การรีบิลด์เมื่อมีการเปลี่ยนแปลง, และการดีพลอยไป GitHub Pages สามารถเพิ่มเป็น target เสริม ได้เมื่อจำเป็น
  • เพราะมี dependency น้อยและจุดที่ต้องแก้ชัดเจน สำหรับเว็บไซต์ที่มีความต้องการไม่มาก โฟลว์การ build ที่ทำเอง อาจเร็วกว่าเครื่องมือสร้างแบบอเนกประสงค์

พื้นฐานการทำเว็บไซต์สแตติกด้วย Makefile อย่างเดียว

  • เครื่องมือสร้างเว็บไซต์สแตติกให้ผลลัพธ์ที่ โฮสต์ได้ง่าย รวดเร็ว และมีภาระในการดูแลรักษาน้อยมาก
  • ถ้าเป็นเว็บไซต์เรียบง่าย การเขียนสคริปต์เองอาจทั้งเร็วกว่าและน่าพอใจกว่าการไปเรียนรู้และปรับใช้ตัวสร้างเว็บไซต์ที่มีอยู่
  • ถ้าเป็น เว็บไซต์ธรรมดา ที่ไม่มี timestamp อัปเดตอัตโนมัติหรือ RSS feed ก็ใช้โครงสร้างที่ง่ายกว่าสคริปต์ทำบล็อกได้เพียงพอ
  • ข้อกำหนดพื้นฐาน

    • เก็บไฟล์นำเข้าทั้งหมดไว้ในไดเรกทอรี source และคง โครงสร้างไดเรกทอรี เดิมไว้ในผลลัพธ์ด้วย
    • เพิ่ม header.html ไว้ด้านหน้าของไฟล์ HTML ทุกไฟล์
    • ไฟล์ที่ไม่ใช่ HTML ให้คัดลอกไปยังไดเรกทอรี build โดยไม่เปลี่ยนแปลง
  • กฎของ Makefile

    • target build มี dependency ที่จับคู่ไฟล์ทั้งหมดใต้ source ให้เป็นไฟล์ผลลัพธ์ใต้ build
    • แม้ตัวมันเองจะไม่มีงานโดยตรง แต่ทำหน้าที่เป็นจุดเริ่มให้กฎที่เหมาะกับแต่ละไฟล์ถูกนำไปใช้
    • กฎ build/%.html ขึ้นกับ source/%.html, header.html, และ Makefile
    • ใช้ mkdir -p $(dir $@) เพื่อสร้างไดเรกทอรีผลลัพธ์ และใช้ cat header.html $< > $@ เพื่อรวม header กับ HTML ต้นฉบับเป็นผลลัพธ์
    • กฎ build/% จะใช้ cp $< $@ เพื่อ คัดลอกตรง ๆ สำหรับไฟล์ที่ไม่ใช่ HTML
    • เพียงมี header.html และกฎเหล่านี้ ก็สามารถรัน make build เพื่อสร้างไดเรกทอรี build สำหรับเปิดดูในเครื่องหรืออัปขึ้นเว็บเซิร์ฟเวอร์ได้

ตัวอย่างการขยายความสามารถและ target เสริม

  • แสดงหน้าปัจจุบัน

    • ถ้าไฮไลต์หน้าปัจจุบันใน navigation ผู้เข้าชมจะเห็นตำแหน่งของตนในเว็บไซต์ได้ทันที
    • ในตัวอย่างจะค้นหาลิงก์ใน navigation แล้วเพิ่มคลาส current
    • sed -E 's|(href="$(subst source,,$<))|class="current" \1|' header.html | cat - $< > $@
    • วิธีแทนที่จริงควรปรับให้เข้ากับ โครงสร้างมาร์กอัป ที่ใช้งานอยู่
  • สร้าง HTML จาก Markdown

    • ถ้าไม่อยากเขียน HTML ตรง ๆ หรือมีคอนเทนต์เดิมเป็น Markdown ก็สามารถต่อท่อเข้ากับตัวแปลง Markdown-to-HTML ได้
    • ตัวอย่างใช้ smu
    • smu $< | cat header.html - > $@
    • กฎพื้นฐานยังคงสมมติว่า build/foo.html ถูกสร้างจาก source/foo.html
    • สำหรับไฟล์ Markdown ต้องคงนามสกุล .html ไว้เช่นเดิม หรือแก้กฎให้ค้นหาไฟล์ .md เป็นอินพุต
  • พรีวิวในเครื่อง

    • บางเว็บไซต์พรีวิวได้ไม่ถูกต้องเมื่อเปิดไฟล์โลคัลจากเบราว์เซอร์โดยตรง ซึ่งสาเหตุที่พบบ่อยคือใช้ ลิงก์แบบ absolute แทน relative
    • Python ติดตั้งมาอยู่แล้วในหลายระบบ และมีเว็บเซิร์ฟเวอร์ที่เหมาะกับงานนี้รวมมาให้
    • target serve: python -m http.server -d build
  • รีบิลด์อัตโนมัติเมื่อมีการเปลี่ยนแปลง

    • ระหว่างทำเว็บไซต์ การต้อง build ใหม่ด้วยมือทุกครั้งเป็นเรื่องยุ่งยาก
    • ถ้าใช้ entr ก็สามารถสั่งให้รัน make build อัตโนมัติเมื่อ source, header.html, หรือ Makefile เปลี่ยนแปลงได้
    • target watch: find source header.html Makefile | entr make build
    • ถ้าไม่อยากพึ่ง dependency เพิ่ม ก็สามารถใช้ inotifywait ได้เช่นกัน
  • ดีพลอยไป GitHub Pages

    • ถ้าใช้ GitHub เป็นที่เก็บ repository อยู่แล้ว การโฮสต์ HTML ที่สร้างเสร็จบน GitHub Pages ก็เป็นตัวเลือกที่เป็นธรรมชาติ
    • การจัดคำสั่งดีพลอยให้ทำงานโดยไม่ต้องกังวลรายละเอียดของ git อาจยุ่งยากเล็กน้อย แต่จัดการได้ด้วย git worktree
    • วิธีนี้อ้างอิงจาก บทความของ Sangsoo Nam
    • เพิ่มแบรนช์ gh-pages เป็น worktree ชื่อ public_html
    • คัดลอก build/* ไปยัง public_html
    • รัน git add --all, git commit -m "Deploy to github pages", และ git push origin gh-pages
    • สุดท้ายลบ worktree ด้วย git worktree remove public_html
  • ตัวอย่างใช้งานจริง

    • สามารถดูหน้าเว็บที่สร้างด้วยแนวทางนี้ได้ที่ karlb/astridbartel.de
    • เครื่องมือสร้างเว็บไซต์สแตติกทั้งชุดอาจเริ่มต้นได้ด้วย หกบรรทัดใน Makefile และสามารถปรับให้เข้ากับความต้องการได้อย่างรวดเร็ว โดยไม่มี dependency แปลก ๆ หรือภาระดูแลรักษามากนัก

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

 
GN⁺ 2023-09-11
ความคิดเห็นจาก Hacker News
  • เว็บไซต์ส่วนตัว (https://pablo.rauzy.name/) เมื่อก่อนสร้างด้วย Makefile แบบเรียบง่าย
    ต่อมาได้เพิ่มฟีเจอร์อย่างข่าวและฟีด RSS, รายการอัตโนมัติของบทความวิจัยและเอกสารประกอบการสอน, รวมถึงรายการหนังสือที่กรองด้วยแท็กได้ ตอนนี้ก็ยังเป็น Makefile อยู่ แต่ตัว Makefile เองกลับเรียบง่ายขึ้นเล็กน้อย และไปเรียกใช้สคริปต์ Bash ที่ใช้ยูทิลิตี xml2 และ 2xml ชั้นดีเพื่อจัดการ HTML แบบทีละบรรทัดแทน โดยส่วนใหญ่ใช้ core utilities อย่าง grep และ sed
    ยังติด git hook ไว้หลายตัวเพื่อเรียก make อัตโนมัติเมื่อจำเป็น โดยเฉพาะบนเซิร์ฟเวอร์ระยะไกลที่โฮสต์เว็บไซต์ เมื่อ push ไปยัง repository แล้วเวอร์ชันสาธารณะจะถูก build ใหม่
    ใช้งานได้ดีมากมาหลายปีแล้ว และประวัติ git ย้อนกลับไปได้ถึงปี 2009 พอดู commit แรก ๆ ก็มี beccad7 (FIRST_VERSION) Initial commit, d1cc6d7 adding link to Google Reader shared items, 6ccfd0c fix typo, d337959 adding link to Identi.ca account และนี่ก็ผ่านมาจริง ๆ 15 ปีแล้ว
  • ปัญหาของวิธีนี้คือ แม้จะลบไฟล์จาก source/ แล้ว ไฟล์นั้นก็จะไม่ถูกลบจาก build/
    ในโปรเจกต์ของผม การ build เว็บไซต์ทั้งหมดยังเร็วพอ จึงเลือก ลบโฟลเดอร์ build ทั้งหมด ก่อน build ใหม่
    https://github.com/jez/jez.github.io/blob/source/Makefile#L1...
    แบบนี้ทำให้ incremental build ซึ่งเป็นเหตุผลสำคัญอย่างหนึ่งของการใช้ build system ถูกลดทอนประโยชน์ไปมาก แต่ถ้ารู้ว่าต้องการสร้างหน้าไหนใหม่ ก็ยังสามารถ make เฉพาะไฟล์นั้นโดยตรงได้
    ถ้ามี workaround ที่ใช้กันทั่วไปสำหรับแพตเทิร์นแบบนี้ใน Makefile ก็อยากรู้
    • ไม่รู้ว่าเป็นแพตเทิร์นที่ใช้กันทั่วไปไหม แต่ทางแก้ของผมคือสั่งลบไฟล์ที่ “ไม่คาดคิด” ทุกครั้ง
      ใช้ฟังก์ชัน shell ของ GNU Make เพื่อไล่รายการไฟล์ แล้วใช้ฟังก์ชัน filter-out เพื่อกรอง output ที่ “คาดไว้” ออก เป็นแฮ็กที่ดูไม่สวย แต่ทำให้คำสั่งถูกเรียกเป็นส่วนหนึ่งของการขยายตัวแปรผ่านฟังก์ชัน shell จึงรับประกันได้ว่าจะรันทุกครั้ง
      ลิงก์ Makefile: https://github.com/jaredkrinke/make-blog/blob/main/Makefile
    • การลบไฟล์และเปลี่ยนชื่อเป็นปัญหาที่พบได้บ่อยใน ระบบควบคุมเวอร์ชัน/ระบบ build หลายแบบ
      นอกจากตัวเลือกแบบระเบิดนิวเคลียร์อย่าง make clean แล้ว ก็สามารถมี Make target เฉพาะสำหรับการลบและเปลี่ยนชื่อได้ เช่น ทำให้ make rm sourcefile หรือ make mv sourcefile newsourcefile จัดการลบ/เปลี่ยนชื่อทั้งไฟล์ต้นฉบับและผลลัพธ์ที่สร้างขึ้นพร้อมกัน
      ในทางปฏิบัติ แม้แต่บล็อกหรือโปรเจกต์ออนไลน์ที่ค่อนข้างใหญ่ วงจร make clean / make all ก็มักจะเร็วพอ และมักจำเป็นเมื่อต้องแก้ template หรือองค์ประกอบดีไซน์ของไซต์ ถ้าขนาดใหญ่จนต้องกังวลเรื่องเวลา build ใหม่จริง ๆ ก็ควรใช้ CMS จริงที่จัดการ source ในฐานข้อมูลและสร้างแบบไดนามิกเมื่อไคลเอนต์เข้าถึงมากกว่า
    • ใช้ make clean ก็พอไม่ใช่เหรอ?
    • แบบนี้น่าจะได้
      rm/%.html:
      @rm -f source/%.html build/%.html
      รันด้วย $ make rm/page.html
    • Shake ซึ่งเป็นระบบ build แบบอเนกประสงค์ มีฟีเจอร์ prune สำหรับจุดประสงค์นี้โดยตรง
      http://neilmitchell.blogspot.com/2015/04/cleaning-stale-file...
      แต่ผมคิดว่าวิธีที่ดีที่สุดที่ใช้ได้กับ make ก็คือมี target make dist ที่สร้าง archive .tar.gz สุดท้ายของผลลัพธ์ ถ้าเขียน rule ถูกต้อง ไฟล์เก่าจะไม่ถูกใส่เข้าไป ในโปรเจกต์ใหญ่ ๆ อาจช้าได้ แต่ตอนพัฒนาก็ไม่จำเป็นต้องใช้ และใช้เฉพาะตอน release ก็พอ incremental build ยังทำได้เหมือนเดิม แค่ .tar.gz สุดท้ายเท่านั้นที่ต้องสร้างใหม่ตั้งแต่ต้น
  • ได้แรงบันดาลใจโดยตรงจากงานสคริปต์เชลล์ blog.sh ของ Karl ที่กล่าวถึงในบทความนี้
    ผมนำมันมาปรับแก้จนกลายเป็น barf ซึ่งเป็น static site generator แบบมินิมอลของผมเอง ถ้า Karl ไม่ได้เผยแพร่งานเจ๋ง ๆ ของเขาออกมา มันก็คงไม่มีอยู่
    [0]: https://github.com/karlb/karl.berlin/blob/master/blog.sh
    [1]: https://barf.bt.ht
    • ดูเป็นคนคอเดียวกันนะ ของผมเรียกว่า shite และใช้มันสร้างเว็บไซต์ของผมเอง ชื่อนี้บอกใบ้ถึงคุณภาพซอฟต์แวร์ :)
      สิ่งที่ชอบที่สุดคือจนถึงตอนนี้ไม่เคยต้องอัปเกรดอะไรเลย และดูเหมือนอนาคตก็คงไม่ต้องด้วย สิ่งที่ดีรองลงมาคือมี hot reload ได้โดยไม่ใช้ JavaScript
      [1] https://github.com/adityaathalye/shite
      [2] https://evalapply.org
  • ถ้าผสม m4 เข้าไปนิดหน่อย ก็จะได้ความยืดหยุ่นเพิ่มขึ้นเล็กน้อยในขณะที่ยังคง แนวทางแบบโครงกระดูกเปล่า ๆ เดิมไว้

เคยดูแลเว็บไซต์เล็ก ๆ ที่ทำด้วยวิธีแบบนั้นเมื่อราว 20 ปีก่อน แต่ถ้าไม่นับเว็บไซต์ส่วนตัว ก็ไม่แน่ใจว่าทุกวันนี้โมเดลนี้จะเหมาะแค่ไหน เพราะโดยเนื้อแท้แล้ววิธีนี้บังคับให้กลับไปสู่บทบาทแบบ Web 1.0 ผู้ใช้ทุกคนที่มีส่วนร่วมต้องเชี่ยวชาญ HTML หรือไม่ก็ต้องมีใครสักคนรับงานจิปาถะในฐานะ “เว็บมาสเตอร์”
[1] https://en.wikipedia.org/wiki/M4_(computer_language)

  • ไม่มีสิ่งที่เรียกว่า “ใช้ m4 นิดหน่อย”
    เริ่มโปรเจกต์สะอาด ๆ พร้อมสาบานว่าคราวนี้จะไม่แตะ m4 แล้วก็ใส่การเรียก m4 เล็ก ๆ อันหนึ่งเข้าไปเพื่อลดโค้ดซ้ำ
    หนึ่งปีต่อมา ต้องขุดลงไปใน macro expansion 5 ชั้นเพื่อหาว่าทำไมคำว่า “cat” ถึงหายไปจากเว็บไซต์อย่างเงียบ ๆ และสุดท้ายก็พบว่านักพัฒนารุ่นจูเนียร์พยายามเขียนลูป for เองแทนที่จะคัดลอกจากคู่มือ แล้วทำเครื่องหมายคำพูดพัง
    พอแก้ปัญหาเฉพาะหน้าเสร็จ ก็สรุปว่า DSL ดีบักยากเกินไป เลยเอาไฟล์แมโคร M4 ที่คัดลอกข้ามโปรเจกต์กันมาตลอดเข้ามาใช้ จากนั้นใช้เวลาทั้งวันเปลี่ยนตำแหน่งที่ใช้ define ทั้งหมดให้เป็นแมโครที่สร้างแมโคร เพื่อเพิ่มคอมเมนต์ในเอาต์พุตให้สคริปต์สร้าง stack trace ทำงานได้
    โปรเจกต์หน้าจะตั้งกฎเด็ดขาดเลยว่า ห้าม m4! แน่นอน อาจมีข้อยกเว้นสักจุดหนึ่งก็ได้
  • แทนที่จะพึ่งการแทนที่ข้อความทั่วไปอย่าง m4 หรือ perl แนะนำให้ใช้ SGML ซึ่งเป็นรากฐานและ superset ร่วมของ HTML กับ XML
    SGML มีแมโครข้อความแบบตรวจชนิดง่าย ๆ หรือก็คือ entity expansion มาให้ในตัว และยังทำ parameterized macro expansion ที่รู้ชนิดได้ด้วย ในที่นี้ชนิดหมายถึงชนิดเนื้อหาทั่วไปขององค์ประกอบมาร์กอัป หรือก็คือลูกที่อนุญาตและลำดับของมัน รวมถึงพิจารณาการขยายหรือ escape ตามบริบทอย่าง attribute, CDATA, RCDATA ด้วย
    งานอย่างการขยายและ escape ความคิดเห็นผู้ใช้ที่อาจเป็นอันตรายอย่างเหมาะสม พร้อมบังคับใช้กฎของผู้ใช้ เช่น อนุญาตมาร์กอัประดับ inline แต่ห้ามองค์ประกอบ script มีเพียง SGML เท่านั้นที่ขยายได้ถูกต้อง นอกจากนี้ยังทำได้ทั้งการขยาย Markdown หรือไวยากรณ์วิกิเป็น HTML, นำเข้าเนื้อหา HTML ภายนอก/สำหรับ syndication, สร้าง RSS และ outline สำหรับการนำทาง เหมาะกับงานเตรียม static site ที่ค่อนข้างซับซ้อนบน command line
    [1]: https://sgmljs.net/docs/producing-html-tutorial/producing-ht...
    [2]: https://sgmljs.net/docs/sgmlproc-manual.html
  • ลองใช้ envsubst แทน m4 หรือการ find-and-replace ด้วย sed ก็น่าจะดี
    เป็นโปรแกรมที่แทนที่การอ้างอิงตัวแปรแบบ Bash เช่น $TITLE ด้วยค่าจาก environment variable
    export CURRENT="..."
    cat page.html | envsubt
  • “ใช้ m4 นิดหน่อย” น่ะเหรอ ขอร้อง อย่าเด็ดขาด
    m4 ยังห่วยแม้ในฐานะภาษาโปรแกรมแนวลึกลับอ่านยาก
  • เคยลองแล้ว และจะไม่ทำอีก
    แค่ข้อเท็จจริงว่ามันเคยรันใน sendmail ได้ ไม่เพียงพอจะเป็นเหตุผลรับรองอะไรทั้งนั้น
  • ชอบตรงที่บล็อกนักพัฒนาแทบทุกบล็อกที่เจอบน HN มี ฟีด RSS
    ทุกครั้งที่อ่านบทความน่าสนใจที่นี่ก็จะ subscribe ฟีดไว้ ไม่ว่าจะเป็นไซต์ Wordpress, Bear Blog, Micro.blog, บล็อก Havenweb หรือฟีดจากไซต์ที่ทำเอง ก็เพิ่มเข้าไปในโมดูล Really Social Sites ของ Hey Homepage
    สุดท้ายแล้วอยากเปิดเผยรายชื่อบล็อกเหล่านี้เหมือนที่ Kagi ทำในโครงการ Small Web แต่ถ้าจะเพิ่มคุณภาพ การคัดสรรคือหัวใจสำคัญ และพอคิดเรื่องการคัดสรรแล้ว การเริ่มนิตยสารออนไลน์สักอย่างก็ดูเป็นขั้นตอนที่เป็นธรรมชาติ
    • กำลังพยายามทำความเข้าใจอยู่ว่าแปลกไหมที่ในฐานะนักพัฒนา ผมไม่ได้อยากมีบล็อกของตัวเอง
      ผู้คนได้ “sense of entitlement” ในความหมายดี ๆ ว่าสิ่งนี้ควรแชร์ให้คนอื่นได้ จากที่ไหนกัน? ผมสงสัยว่าทำไมถึงสมมติว่าคนอื่นจะสนใจสิ่งที่ผมกำลังทำ บางครั้งมันรู้สึกเหมือนการแข่งขัน ประมาณว่า “ถ้าอยากได้ไลก์หรือยอดเห็นบนบล็อก ก็ต้องสร้างอะไรที่เจ๋งที่สุดเท่าที่จะทำได้”
      การร่วมมือนั้นดีแน่นอน และจะทำได้ก็ต้องเปิดเผยทั้งหมด เพียงแต่ผมไม่ค่อยเห็นเส้นแบ่งระหว่าง “ทำเพราะสิ่งนี้ดูเจ๋ง” กับ “พยายามแชร์ให้คนอื่นเพื่อให้ได้ปฏิกิริยาตอบกลับ”
    • ยังมี https://prose.sh ที่คล้ายกับ Bear Blog ด้วย
  • เพื่อนเคยอธิบายวิธี สร้างบทความวิทยาศาสตร์ด้วย make
    เขาบอกว่าแค่เปลี่ยนไฟล์ทดสอบหนึ่งไฟล์ ก็สามารถสร้างบทความทั้งฉบับใหม่ได้ด้วยคำสั่งเดียว รวมถึงการรันทดสอบและสร้างกราฟด้วย
  • เป็นไอเดียที่เรียบร้อยดี แต่ถ้าคุณ push ขึ้น GitHub อยู่แล้ว แค่เอา source ขึ้นไป GitHub ก็สามารถเผยแพร่ Markdown เป็นหน้าเว็บที่โฮสต์ให้ได้
    https://pages.github.com/
    • ถ้าอย่างนั้นก็จะ พึ่งพา GitHub มากกว่าแค่โฮสติ้งธรรมดา ตั้งแต่แรกควรทำให้การ generate ไซต์รันในเครื่องได้จะดีกว่า
  • ชอบโค้ดนี้
    ของผมออกแบบมากไปหน่อยเพราะอยากได้ hot reload แบบไม่มี JavaScript และเป็นการโกนขนจามรีที่สนุกดี
    ไอเดียพื้นฐานเหมือนกัน ใช้ heredoc ในเทมเพลต ใช้คอมไพเลอร์แปลงข้อความธรรมดาเป็น HTML ซึ่งในกรณีของผมคือ pandoc ใช้ CSV กลางเพื่อสร้างดัชนี และยังมีเทคนิค sed ที่มีประโยชน์สำหรับดึง front matter ออกมา คลาสสิกและดี
    [1] https://github.com/karlb/karl.berlin/blob/master/blog.sh
    [2] https://github.com/adityaathalye/shite
    [3] วิธีที่ผมทำ: https://github.com/adityaathalye/shite/blob/master/bin/templ...
    • แนวทาง GEMINI ของเขาค่อนข้างตลกดี ใช้ regex ลอกฟอร์แมตส่วนใหญ่ออก

แต่ก็มีข้อจำกัดอยู่บ้าง ผมจัดระเบียบบทความตามเนมสเปซและใส่วันที่ใน URL แต่ make จัดการเรื่องนี้เองได้ไม่ค่อยดี

  • เมื่อดูสคริปต์ประเภทนี้ ก็จะเข้าใจได้ชัดเจนว่าทำไมเราไม่ทำเอง แต่ใช้เครื่องมืออย่าง esbuild หรือ vite
  • ข้อดีของ make คือเมื่อมีการเปลี่ยนแปลงเล็กน้อยในโปรแกรมขนาดใหญ่ที่ต้อง build ด้วยคอมไพเลอร์ที่ช้า มันช่วยให้การ rebuild แบบ incremental เร็วขึ้นมาก
    งานที่ถ้า rebuild ทั้งหมดต้องใช้เวลา 40 นาที อาจเสร็จในราว 3 วินาที
    ถ้า static site ถูกสร้างขึ้นใหม่ตั้งแต่ต้นภายในไม่ถึง 1 วินาที เพียงแค่ cat เฮดเดอร์ร่วมกับไฟล์ HTML หลายร้อยไฟล์ ก็ไม่มีประโยชน์อะไรที่จะใช้ make แทนสคริปต์ มีแต่จะเพิ่มความเสี่ยงที่จะ build ได้ไม่สมบูรณ์เพราะบั๊กด้าน dependency
    • ถ้า dependency ของไฟล์ไม่ได้สำคัญจริง ๆ ก็ทำเครื่องหมาย target สำหรับ build เป็น .phony ได้
      ถึงอย่างนั้นก็ยังแยกคำสั่งอย่าง make build กับ make push ได้
  • ว้าว นี่แทบจะตรงกับสิ่งที่ผมตั้งใจจะทำกับไซต์ของผมเลย
    ในโปรเจกต์เล็ก ๆ อื่น ผมใช้ shell script ขนาดจิ๋วเป็น bundler แบบชั่วคราว โดยเป็นวิธีแทรก CSS และ JS เข้าไปใน HTML และมีเป้าหมายให้สามารถ serve ไฟล์ที่ยังไม่ได้ build ในเครื่องได้ด้วย