การสร้าง SSG ที่ฉันต้องการมาตลอด: แซนด์วิช 11ty, Vite และ JAM

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ย้อนกลับไปในเดือนมกราคม 2020 Ben Holmes ตั้งใจจะทำอะไรที่นักพัฒนาเว็บทุกคนทำในแต่ละปี นั่นคือ สร้างเว็บไซต์ส่วนตัวของเขาใหม่ ในบทความนี้ เขาแบ่งปันเรื่องราวของเขาเกี่ยวกับวิธีที่เขาเริ่มสร้างไปป์ไลน์การบิลด์ของตัวเองจากศูนย์กราวด์ที่สมบูรณ์แบบและสร้าง Slinkity

ฉันไม่รู้เกี่ยวกับคุณ แต่ฉัน เคยชิน กับเครื่องมือพัฒนาเว็บทั้งหมดที่เรามีในทุกวันนี้ ไม่ว่าคุณจะชอบ Markdown, HTML ธรรมดา, React, Vue, Svelte, เทมเพลต Pug, Handlebars, Vibranium - คุณอาจจะผสมผสานกับข้อมูล CMS บางส่วนและรับค็อกเทลไซต์คงที่ที่ดี

ฉันจะไม่บอกคุณว่าควรใช้เครื่องมือพัฒนา UI ใดเพราะทั้งหมดนั้นยอดเยี่ยม — ขึ้นอยู่กับความต้องการของโครงการของคุณ โพสต์นี้เป็นเรื่องเกี่ยวกับการค้นหาเครื่องมือสร้างไซต์คงที่ที่สมบูรณ์แบบสำหรับ ทุก โอกาส บางอย่างที่ช่วยให้เราใช้เทมเพลตที่ไม่มี JS เช่น markdown เพื่อเริ่มต้น และนำ "เกาะ" ของการโต้ตอบที่ขับเคลื่อนด้วยคอมโพเนนต์เข้ามาตามความจำเป็น

ฉันกำลังกลั่นกรองการเรียนรู้หนึ่งปีในโพสต์เดียวที่นี่ ไม่เพียงแต่เราจะพูดถึงโค้ด (aka duct-taping 11ty และ Vite ด้วยกัน) แต่เราจะสำรวจด้วยว่า เหตุใด แนวทางนี้จึงเป็นสากลสำหรับปัญหา Jamstackian เราจะสัมผัสกับ:

  • สองแนวทางในการสร้างไซต์แบบคงที่ และเหตุผลที่เราควรเชื่อมช่องว่าง
  • ที่ซึ่งภาษาที่ใช้แม่แบบเช่น Pug และ Nunjucks ยังคงมีประโยชน์
  • เมื่อเฟรมเวิร์กส่วนประกอบเช่น React หรือ Svelte ควรเข้ามาเล่น
  • วิธีที่โลกใหม่ของการรีโหลดร้อนของ Vite ช่วยให้เรานำการโต้ตอบของ JS มาสู่ HTML ของเราด้วยการกำหนดค่าเกือบเป็นศูนย์ได้อย่างไร
  • วิธีนี้ช่วยเสริม data cascade ของ 11ty ได้อย่างไร โดยนำข้อมูล CMS ไปยังเฟรมเวิร์กส่วนประกอบหรือเทมเพลต HTML ที่คุณต้องการ

ดังนั้นโดยไม่ต้องกังวลใจอีกต่อไป นี่คือเรื่องราวของฉันเกี่ยวกับสคริปต์บิลด์ที่แย่มาก การพัฒนา Bundler และเทปปาเก็ตตี้โค้ดที่ (ในที่สุด) ให้ SSG ที่ฉันต้องการมาตลอด: แซนวิช 11ty, Vite และ Jam ที่เรียกว่า Slinkity!

การแบ่งแยกครั้งใหญ่ในการสร้างไซต์แบบคงที่

ก่อนดำดิ่ง ฉันต้องการพูดคุยถึงสิ่งที่จะเรียกว่า "แคมป์" สองแห่งในการสร้างไซต์แบบคงที่

ในแคมป์แรก เรามีเครื่องมือสร้าง ไซต์คงที่ "แบบง่าย" เครื่องมือเหล่านี้ไม่ได้รวมกลุ่ม JavaScript แอปแบบหน้าเดียว และคำศัพท์อื่นๆ ที่เราคาดหวัง พวกเขาเพียงแค่ตอกย้ำพื้นฐานของ Jamstack: ดึงข้อมูลจาก JSON blob ของ CMS ที่คุณต้องการ และเลื่อนข้อมูลนั้นลงในเทมเพลต HTML ธรรมดา + CSS เครื่องมืออย่าง Jekyll, Hugo และ 11ty ครองแคมป์นี้ ให้คุณเปลี่ยนไดเร็กทอรีของไฟล์มาร์กดาวน์และไฟล์ของเหลวให้เป็นเว็บไซต์ที่ใช้งานได้เต็มรูปแบบ ประโยชน์ที่สำคัญ:

  • เส้นโค้งการเรียนรู้ตื้น
    หากคุณรู้ HTML คุณก็พร้อมแล้ว!
  • เวลาสร้างอย่างรวดเร็ว
    เราไม่ได้ประมวลผลอะไรที่ซับซ้อน ดังนั้นแต่ละเส้นทางจึงถูกสร้างขึ้นในพริบตา
  • เวลาโต้ตอบทันที
    ไม่มี JavaScript (หรือน้อยมาก) ที่จะแยกวิเคราะห์ในไคลเอนต์

ตอนนี้ในแคมป์ที่ 2 เรามี "ไดนามิก" ตัวสร้างไซต์คงที่ สิ่งเหล่านี้แนะนำเฟรมเวิร์กส่วนประกอบเช่น React, Vue และ Svelte เพื่อนำการโต้ตอบมาสู่ Jamstack ของคุณ สิ่งเหล่านี้เป็นไปตามสัญญาหลักเดียวกันในการรวมข้อมูล CMS กับเส้นทางของไซต์ของคุณในเวลาที่สร้าง ประโยชน์ที่สำคัญ:

  • สร้างขึ้นเพื่อการโต้ตอบ
    ต้องการภาพหมุนภาพเคลื่อนไหวหรือไม่? แบบฟอร์มหลายขั้นตอน? เพียงเพิ่มนักเก็ตที่เป็นส่วนประกอบของ HTML, CSS และ JS
  • การจัดการของรัฐ
    บางอย่างเช่น React Context ของร้านค้า Svelte อนุญาตให้แชร์ข้อมูลระหว่างเส้นทางได้อย่างราบรื่น ตัวอย่างเช่น รถเข็นบนเว็บไซต์อีคอมเมิร์ซของคุณ

มีข้อดีที่ชัดเจนสำหรับแนวทางใดแนวทางหนึ่ง แต่ถ้าคุณเลือก SSG จากค่ายแรกอย่าง Jekyll เพียงเพื่อให้โครงการของคุณมีเวลา 6 เดือนว่าจำเป็นต้องมีการโต้ตอบระหว่างองค์ประกอบ หรือคุณเลือกบางอย่างเช่น NextJS สำหรับส่วนประกอบที่ทรงพลังเหล่านั้นเพียงเพื่อต่อสู้กับเส้นโค้งการเรียนรู้ของ React หรือ KB ที่ไม่จำเป็นของ JavaScript บนโพสต์บล็อกแบบคงที่?

มีโครงการไม่ กี่ โครงการที่เหมาะสมกับค่ายใดค่ายหนึ่งในความคิดของฉัน สิ่งเหล่านี้มีอยู่ในสเปกตรัมและนิยมชุดคุณลักษณะใหม่ ๆ อย่างต่อเนื่องเมื่อความต้องการของโครงการพัฒนาขึ้น แล้วเราจะหาวิธีแก้ไขที่ให้เรา เริ่มต้น ด้วยเครื่องมือง่ายๆ ของค่ายแรกและค่อยๆ เพิ่มฟีเจอร์จากส่วนที่สองเมื่อเราต้องการได้อย่างไร

มาดูเส้นทางการเรียนรู้ของฉันกันสักหน่อย

หมายเหตุ: หากคุณขายเทมเพลตสแตติกด้วย 11ty เพื่อสร้างไซต์สแตติกของคุณแล้ว คุณสามารถข้ามไปที่คำแนะนำการใช้งานโค้ดที่น่าสนใจได้

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

เปลี่ยนจากส่วนประกอบสู่เทมเพลตและเว็บ API

ย้อนกลับไปในเดือนมกราคม 2020 ฉันตั้งใจจะทำอะไรที่นักพัฒนาเว็บทุกคนทำในแต่ละปี นั่นคือ สร้างไซต์ส่วนตัวของฉันใหม่ แต่ครั้งนี้จะ แตกต่างออกไป ฉันท้าทายตัวเองให้สร้างไซต์ด้วยมือเปล่า ไม่อนุญาตให้ใช้เฟรมเวิร์กหรือไปป์ไลน์!

นี่ไม่ใช่งานง่ายในฐานะสาวกของ React แต่ด้วยความที่หัวสูง ฉันจึงตั้งใจที่จะสร้างไปป์ไลน์สำหรับบิลด์ของตัวเองจากศูนย์กราวด์ที่สมบูรณ์แบบ มีโค้ดที่เขียนไม่ดีมากมายที่ฉัน สามารถ แชร์จาก v1 ของไซต์ส่วนตัวของฉันได้… แต่ฉันจะช่วยให้คุณคลิก README นี้หากคุณกล้า แต่ฉันต้องการที่จะมุ่งเน้นไปที่ประเด็นในระดับที่สูงขึ้นซึ่งฉันได้เรียนรู้ว่าตัวเองหิวโหยจากความสุขที่มีความผิดของ JS

เทมเพลตไปได้ไกลกว่าที่คุณคิด

ฉันมาที่โครงการนี้ด้วย JavaScript ที่กู้คืนเป็นขยะ มีความต้องการที่เกี่ยวข้องกับไซต์สแตติกสองสามอย่างที่ฉันชอบโดยใช้เฟรมเวิร์กแบบคอมโพเนนต์เพื่อเติมเต็ม:

  1. เราต้องการแบ่งไซต์ของฉันออกเป็นส่วนประกอบ UI ที่นำกลับมาใช้ใหม่ได้ ซึ่งยอมรับอ็อบเจกต์ JS เป็นพารามิเตอร์ (หรือที่เรียกว่า "อุปกรณ์ประกอบฉาก")
  2. เราจำเป็นต้องดึงข้อมูลบางส่วนในเวลาสร้าง เพื่อตบเข้าไปในไซต์การผลิต
  3. เราจำเป็นต้องสร้างเส้นทาง URL จำนวน มากจากไดเรกทอรีของไฟล์หรือวัตถุ JSON ที่มีเนื้อหาอ้วน

รายการที่นำมาจากโพสต์นี้ในบล็อกส่วนตัวของฉัน

แต่คุณอาจสังเกตเห็น… สิ่งเหล่านี้ ไม่ ต้องการ JavaScript ฝั่งไคลเอ็นต์จริงๆ เฟรมเวิร์กของคอมโพเนนต์อย่าง React นั้นสร้างขึ้นเพื่อจัดการกับข้อกังวลด้านการจัดการสถานะเป็นหลัก เช่น เว็บแอป Facebook ที่สร้างแรงบันดาลใจให้กับ React ตั้งแต่แรก หากคุณเพียงแค่แบ่งไซต์ของคุณออกเป็นส่วนประกอบขนาดพอดีคำหรือองค์ประกอบของระบบการออกแบบ เทมเพลตอย่าง Pug ก็ใช้งานได้ดีเช่นกัน!

ยกตัวอย่างแถบนำทางนี้ ใน Pug เราสามารถกำหนด "mixin" ที่รับข้อมูลเป็นอุปกรณ์ประกอบฉาก:

 // nav-mixins.pug mixin NavBar(links) // pug's version of a for loop each link in links a(href=link.href) link.text

จากนั้น เราสามารถใช้มิกซ์อินนั้นได้ทุกที่บนเว็บไซต์ของเรา

 // index.pug // kinda like an ESM "import" include nav-mixins.pug html body +NavBar(navLinksPassedByJS) main h1 Welcome to my pug playground

หากเรา "แสดง" ไฟล์นี้ด้วยข้อมูลบางส่วน เราจะได้รับ index.html ที่สวยงามเพื่อให้บริการแก่ผู้ใช้ของเรา

 const html = pug.render('/index.pug', { navLinksPassedByJS: [ { href: '/', text: 'Home' }, { href: '/adopt', text: 'Adopt a Pug' } ] }) // use the NodeJS filesystem helpers to write a file to our build await writeFile('build/index.html', html)

แน่นอนว่าสิ่งนี้ไม่ได้ให้สิ่งที่ดีอย่างเช่น CSS ที่มีขอบเขตสำหรับมิกซ์อินของคุณ หรือจาวาสคริปต์แบบเก็บสถานะที่คุณต้องการ แต่มันมีประโยชน์ที่ทรงพลังมากกว่าบางอย่างเช่น React:

  1. เราไม่ต้องการเครื่องมัดแฟนซีที่เราไม่เข้าใจ
    เราเพิ่งเขียนการโทร pug.render ด้วยมือ และเรามีเส้นทางแรกของไซต์ที่พร้อมใช้งานแล้ว
  2. เราไม่จัดส่ง JavaScript ใด ๆ ไปยังผู้ใช้ปลายทาง
    การใช้ React มักจะหมายถึงการส่งรันไทม์ขนาดใหญ่เพื่อให้เบราว์เซอร์ของผู้คนทำงาน การเรียกใช้ฟังก์ชันเช่น pug.render ณ เวลาสร้าง เราเก็บ JS ทั้งหมดไว้ข้างเราในขณะที่ส่งไฟล์ .html ที่สะอาดในตอนท้าย

นี่คือเหตุผลที่ฉันคิดว่าเทมเพลตเป็น "ฐาน" ที่ยอดเยี่ยมสำหรับไซต์แบบคงที่ ถึงกระนั้น การเข้าถึงเฟรมเวิร์กคอมโพเนนต์ที่เรา ได้ รับประโยชน์จากเฟรมเวิร์กเหล่านั้นก็คงจะดี เพิ่มเติมในภายหลัง

การอ่านที่แนะนำ : วิธีสร้างเทมเพลตเชิงมุมที่ดีขึ้นด้วย Pug โดย Zara Cooper

คุณไม่จำเป็นต้องมีกรอบงานในการสร้างแอปหน้าเดียว

ในขณะที่ฉันอยู่ที่นั่น ฉันยังต้องการการเปลี่ยนหน้าแบบเซ็กซี่บนไซต์ของฉันด้วย แต่เราจะดึงสิ่งนี้ออกมาโดยไม่มีกรอบได้อย่างไร

Crossfade พร้อมการเปลี่ยนภาพในแนวตั้ง
Crossfade พร้อมการเปลี่ยนภาพในแนวตั้ง (ตัวอย่างขนาดใหญ่)

เราไม่สามารถทำเช่นนี้ได้หากทุกหน้าเป็นไฟล์ .html ของตัวเอง เบราว์เซอร์ทั้งหมดจะรีเฟรชเมื่อเราข้ามจากไฟล์ HTML หนึ่งไปยังอีกไฟล์หนึ่ง ดังนั้นเราจึงไม่สามารถมีเอฟเฟกต์ cross-fade ที่ดีได้ (เนื่องจากเราจะแสดงทั้งสองหน้าโดยย่อ)

เราต้องการวิธี "ดึง" HTML และ CSS สำหรับทุกที่ที่เรานำทางไป และทำให้เคลื่อนไหวในมุมมองโดยใช้ JavaScript ดูเหมือนงานสำหรับแอปหน้าเดียว! ฉันใช้เบราว์เซอร์ผสม API อย่างง่ายสำหรับสิ่งนี้:

  1. สกัดกั้นการคลิกลิงก์ทั้งหมดของคุณโดยใช้ตัวฟังเหตุการณ์
  2. fetch API : ดึงทรัพยากรทั้งหมดสำหรับหน้าใดก็ตามที่คุณต้องการเข้าชม และคว้าบิตที่ฉันต้องการทำให้เคลื่อนไหวในมุมมอง: เนื้อหาภายนอกแถบนำทาง (ซึ่งฉันต้องการให้หยุดนิ่งระหว่างแอนิเมชัน)
  3. API แอนิเมชั่นเว็บ : ทำให้เนื้อหาใหม่เคลื่อนไหวเพื่อดูเป็นคีย์เฟรม
  4. API ประวัติ : เปลี่ยนเส้นทางที่แสดงในแถบ URL ของเบราว์เซอร์ของคุณโดยใช้ window.history.pushState({}, 'new-route') มิฉะนั้น ดูเหมือนว่าคุณจะไม่ออกจากหน้าที่แล้ว!

เพื่อความชัดเจน นี่คือภาพประกอบของแนวคิดแอปหน้าเดียวโดยใช้การค้นหาและแทนที่อย่างง่าย ( บทความต้นฉบับ ):

กระบวนการกำหนดเส้นทางฝั่งไคลเอ็นต์ทีละขั้นตอน: 1. มีการส่งคืนแฮมเบอร์เกอร์ที่หายากปานกลาง 2. เราขอเบอร์เกอร์ที่ทำได้ดีโดยใช้การดึงข้อมูล API 3. เรานวดการตอบสนอง 4. เราดึงองค์ประกอบ 'แพตตี้' ออกแล้วนำไปใช้ ไปยังหน้าปัจจุบันของเรา
กระบวนการกำหนดเส้นทางฝั่งไคลเอ็นต์ทีละขั้นตอน: 1. มีการส่งคืนแฮมเบอร์เกอร์ที่หายากปานกลาง 2. เราขอเบอร์เกอร์ที่ทำได้ดีโดยใช้การดึงข้อมูล API 3. เรานวดการตอบสนอง 4. เราดึงองค์ประกอบ 'แพตตี้' ออกแล้วนำไปใช้ ไปยังหน้าปัจจุบันของเรา (ตัวอย่างขนาดใหญ่)

หมายเหตุ : คุณสามารถเยี่ยมชมซอร์สโค้ดได้จากเว็บไซต์ส่วนตัวของฉัน

แน่นอนว่าการจับคู่ React et al และไลบรารีแอนิเมชั่นที่คุณเลือกสามารถทำได้ แต่สำหรับกรณีการใช้งานที่ง่ายพอๆ กับการเปลี่ยนผ่านแบบเฟด ... API ของเว็บนั้นค่อนข้างมีประสิทธิภาพในตัวของมันเอง และถ้าคุณต้องการการเปลี่ยนหน้าที่มีประสิทธิภาพมากขึ้นในเทมเพลตคงที่เช่น Pug หรือ HTML ธรรมดา ไลบรารีอย่าง Swup จะให้บริการคุณเป็นอย่างดี

สิ่งที่ 11ty นำมาสู่โต๊ะ

ตอนนี้ฉันรู้สึกดีมากเกี่ยวกับ SSG ตัวน้อยของฉัน แน่นอนว่าไม่สามารถดึงข้อมูล CMS ใดๆ ได้ ณ เวลาบิลด์ และไม่รองรับเลย์เอาต์ที่แตกต่างกันตามหน้าหรือตามไดเร็กทอรี และไม่ได้ปรับรูปภาพของฉันให้เหมาะสมที่สุด และไม่มีบิลด์ที่เพิ่มขึ้น

โอเค ฉันอาจต้องการความช่วยเหลือ

จากการเรียนรู้ทั้งหมดของฉันจากเวอร์ชัน 1 ฉันคิดว่าฉันได้รับสิทธิ์ในการยกเลิกกฎ "ไม่มีไปป์ไลน์ของบุคคลที่สาม" และเข้าถึงเครื่องมือที่มีอยู่ ปรากฎว่า 11ty มีคุณสมบัติมากมายที่ฉันต้องการ!

  • การดึงข้อมูลเมื่อสร้างโดยใช้ไฟล์ . .11ydata.js
  • ข้อมูลส่วนกลางใช้ได้กับเทมเพลต ทั้งหมด ของฉันจากโฟลเดอร์ _data
  • โหลดซ้ำระหว่างการพัฒนาโดยใช้เบราว์เซอร์ซิงค์
  • รองรับการแปลง HTML แฟนซี
  • …และสินค้าอื่นๆ อีกนับไม่ถ้วน

หากคุณได้ลองใช้ SSG เปล่าๆ เช่น Jekyll หรือ Hugo คุณควรมีความคิดที่ดีทีเดียวว่า 11ty ทำงานอย่างไร ความแตกต่างเท่านั้น? 11ty ใช้ JavaScript ผ่านและผ่าน

11ty สนับสนุนโดยทั่วไปทุกไลบรารีเทมเพลตที่มีอยู่ ดังนั้นจึงยินดีที่จะแสดงหน้า Pug ทั้งหมดของฉันเป็นเส้นทาง .html มันเป็นตัวเลือกการโยงเลย์เอาต์ที่ช่วยตั้งค่าแอพ faux-sing-page-app ของฉันด้วย ฉันแค่ต้องการ script เดียวสำหรับเส้นทางทั้งหมดของฉัน และเค้าโครง "สากล" เพื่อนำเข้าสคริปต์นั้น:

 // _includes/base-layout.html <html> <body> <!--load every page's content between some body tags--> {{ content }} <!--and apply the script tag just below this--> <script src="main.js"></script> </body> </html> // random-blog-post.pug --- layout: base-layout --- article h2 Welcome to my blog p Have you heard the story of Darth Plagueis the Wise?

ตราบใดที่ main.js นั้นทำการสกัดกั้นลิงก์ทั้งหมดที่เราได้สำรวจ เราก็มีการเปลี่ยนหน้า!

โอ้และ Data Cascade

11ty ช่วยล้างรหัสสปาเก็ตตี้ทั้งหมดของฉันจาก v1.1 แต่มันนำส่วนสำคัญอีกอย่างหนึ่งมา นั่นคือ Clean API เพื่อโหลดข้อมูลลงในเลย์เอาต์ของฉัน นี่คือขนมปังและเนยของแนวทาง Jamstack แทนที่จะดึงข้อมูลในเบราว์เซอร์ด้วยการจัดการ JavaScript + DOM คุณสามารถ:

  1. ดึงข้อมูลในเวลาบิลด์โดยใช้ Node.js
    นี่อาจเป็นการเรียกใช้ API ภายนอก การนำเข้า JSON หรือ YAML ในเครื่อง หรือแม้แต่เนื้อหาของ เส้นทางอื่นๆ บนไซต์ของคุณ (ลองนึกภาพการอัปเดตสารบัญทุกครั้งที่มีการเพิ่มเส้นทางใหม่)
  2. เสียบข้อมูลนั้นลงในเส้นทางของคุณ จำได้ว่าฟังก์ชั่น .render ที่เราเขียนไว้ก่อนหน้านี้:
 const html = pug.render('/index.pug', { navLinksPassedByJS: [ { href: '/', text: 'Home' }, { href: '/adopt', text: 'Adopt a Pug' } ] })

…แต่แทนที่จะเรียก pug.render ด้วยข้อมูลของเราทุกครั้ง เราให้ 11ty ทำสิ่งนี้เบื้องหลัง

แน่นอนว่าฉันไม่มีข้อมูลมากมายสำหรับไซต์ส่วนตัวของฉัน แต่รู้สึกดีมากที่ได้สร้างไฟล์ .yaml สำหรับโครงการส่วนตัวทั้งหมดของฉัน:

 # _data/works.yaml - title: Bits of Good Homepage hash: bog-homepage links: - href: https://bitsofgood.org text: Explore the live site - href: https://github.com/GTBitsOfGood/bog-web text: Scour the Svelt-ified codebase timeframe: May 2019 - present tags: - JAMstack - SvelteJS - title: Dolphin Audio Visualizer ...

และเข้าถึงข้อมูลนั้นได้จากทุกเทมเพลต:

 // home.pug .project-carousel each work in works h3 #{title} p #{timeframe} each tag in tags ...

มาจากโลกของ "การเรนเดอร์ฝั่งไคลเอ็นต์" ด้วยแอป create-react-app นี่เป็นการเปิดเผยที่ค่อนข้างใหญ่ ไม่ต้องส่งคีย์ API หรือ JSON blobs ขนาดใหญ่ไปยังเบราว์เซอร์อีกต่อไป

ฉันยังเพิ่มสิ่งดีๆ สำหรับการดึง JavaScript และการปรับปรุงแอนิเมชั่นบนเวอร์ชัน 1 ของไซต์ของฉัน หากคุณสงสัย นี่คือจุดที่ README ของฉันยืนอยู่ ณ จุดนี้

ณ จุดนี้ฉันมีความสุข แต่มีบางอย่างขาดหายไป

ฉันทำได้ไกลอย่างน่าประหลาดใจโดยละทิ้งส่วนประกอบที่ใช้ JS และโอบกอดเทมเพลต (พร้อมการเปลี่ยนหน้าแบบเคลื่อนไหวเพื่อบูต) แต่ฉันรู้ว่าสิ่งนี้จะไม่สนองความต้องการของฉันตลอดไป จำความแตกแยกครั้งใหญ่ที่ฉันเตะเราออกไปได้ไหม? เห็นได้ชัดว่ายังคงมีช่องว่างระหว่างการตั้งค่างานสร้างของฉัน (ในค่าย #1 อย่างแน่นหนา) และสวรรค์ของการโต้ตอบแบบ JS-ified (รุ่นถัดไป, SvelteKit และค่ายอื่นๆ #2) บอกว่าฉันต้องการเพิ่ม:

  • โมดอลป๊อปอัปพร้อมสวิตช์เปิด/ปิด
  • ระบบการออกแบบตามส่วนประกอบ เช่น Material UI พร้อมด้วยการกำหนดรูปแบบที่มีขอบเขต
  • แบบฟอร์มหลายขั้นตอนที่ซับซ้อน อาจขับเคลื่อนด้วยเครื่องของรัฐ

หากคุณเป็นคนเจ้าระเบียบ JS ธรรมดา คุณอาจมีคำตอบแบบไม่มีกรอบสำหรับกรณีการใช้งานเหล่านั้นทั้งหมด แต่มีเหตุผลที่ JQuery ไม่ใช่บรรทัดฐานอีกต่อไป! มีบางอย่างที่น่าสนใจเกี่ยวกับการสร้างองค์ประกอบที่ไม่ต่อเนื่องและอ่านง่ายของ HTML สไตล์ที่มีขอบเขต และชิ้นส่วนของตัวแปร "สถานะ" ของ JavaScript React, Vue, Svelte และอื่น ๆ เสนอข้อดีมากมายสำหรับการดีบักและการทดสอบที่การจัดการ DOM แบบตรงไม่ตรงกัน

นี่คือคำถามล้านดอลลาร์ของฉัน:

เราสามารถใช้เทมเพลต HTML แบบตรงเพื่อเริ่มต้น และค่อยๆ เพิ่มส่วนประกอบ React/Vue/Svelte ในตำแหน่งที่เราต้องการได้หรือไม่

คำตอบคือ ใช่ มาลองดูกัน.

11ty + Vite: แมทช์ที่ลงตัวในสวรรค์ ️

นี่คือความฝันที่ฉันจินตนาการไว้ที่นี่ เมื่อใดก็ตามที่ฉันต้องการแทรกบางสิ่งแบบโต้ตอบ ฉันต้องการทิ้งแฟล็กเล็กน้อยในเทมเพลตของฉันเพื่อ "วางองค์ประกอบ X React ที่นี่" นี่อาจเป็นรูปแบบรหัสย่อที่ 11ty รองรับ:

 # Super interesting programming tutorial Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example! {% react './components/FancyLiveDemo.jsx' %}

แต่จำไว้ว่า 11ty ชิ้นเดียว (โดยเจตนา) หลีกเลี่ยง: วิธีรวม JavaScript ทั้งหมดของคุณ มาจากกิลด์ OG ของการรวมกลุ่ม สมองของคุณอาจกระโดดเพื่อสร้างกระบวนการ Webpack, Rollup หรือ Babel ที่นี่ สร้างไฟล์จุดเริ่มต้น ole ขนาดใหญ่และส่งออกโค้ดที่ปรับให้เหมาะสมที่สวยงามใช่ไหม

ใช่ แต่สิ่งนี้สามารถมีส่วนร่วมได้ ตัวอย่างเช่น หากเราใช้ส่วนประกอบ React เราอาจต้องการตัวโหลดสำหรับ JSX ซึ่งเป็นกระบวนการ Babel แฟนซีในการแปลงทุกอย่าง ล่ามสำหรับการนำเข้าโมดูล SASS และ CSS สิ่ง ที่ช่วยในการรีโหลดแบบสด และอื่นๆ

หากมีเพียงเครื่องมือที่สามารถเห็นไฟล์ .jsx ของเราและรู้ว่าต้องทำอย่างไรกับมัน

ใส่: Vite

ไวต์กลายเป็นทอล์คออฟเดอะทาวน์ไปแล้ว มีไว้เพื่อเป็นเครื่องมือแบบ all-in-one สำหรับสร้างอะไรก็ได้ใน JavaScript นี่คือตัวอย่างสำหรับคุณที่จะลองที่บ้าน มาสร้างไดเร็กทอรีว่างในเครื่องของเราและติดตั้งการพึ่งพา:

 npm init -y # Make a new package.json with defaults set npm i vite react react-dom # Grab Vite + some dependencies to use React

ตอนนี้ เราสามารถสร้างไฟล์ index.html เพื่อใช้เป็น "จุดเข้าใช้งาน" ของแอปได้ เราจะทำให้มันค่อนข้างง่าย:

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello Vite! (wait is it pronounced "veet" or "vight"...)</h1> <div></div> </body> </html>

สิ่งที่น่าสนใจเพียงอย่างเดียวคือ div id="root" อยู่ตรงกลาง นี่จะเป็นรากขององค์ประกอบ React ของเราในไม่ช้า!

หากต้องการ คุณสามารถเปิดเซิร์ฟเวอร์ Vite เพื่อดูไฟล์ HTML ธรรมดาของเราในเบราว์เซอร์ของคุณ เพียงเรียกใช้ vite (หรือ npx vite หากคำสั่งไม่ได้รับการกำหนดค่าในเทอร์มินัลของคุณ) และคุณจะเห็นผลลัพธ์ที่เป็นประโยชน์นี้:

 vite vX.XX dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose ready in Xms.

เช่นเดียวกับ Browsersync หรือเซิร์ฟเวอร์ dev ยอดนิยมอื่น ๆ ชื่อไฟล์ .html แต่ละไฟล์สอดคล้องกับเส้นทางบนเซิร์ฟเวอร์ของเรา ดังนั้น หากเราเปลี่ยนชื่อ index.html เป็น about.html เราจะไปที่ http://localhost:3000/about/ (ใช่ คุณจะต้องมีเครื่องหมายทับ!)

ทีนี้มาทำอะไรที่น่าสนใจกัน ข้างไฟล์ index.html นั้น ให้เพิ่มส่วนประกอบ React พื้นฐานของบางประเภท เราจะใช้ useState ของ React ที่นี่เพื่อสาธิตการโต้ตอบ:

 // TimesWeMispronouncedVite.jsx import React from 'react' export default function TimesWeMispronouncedVite() { const [count, setCount] = React.useState(0) return ( <div> <p>I've said Vite wrong {count} times today</p> <button onClick={() => setCount(count + 1)}>Add one</button> </div> ) }

ตอนนี้ มาโหลดส่วนประกอบนั้นบนหน้าของเรากัน นี่คือทั้งหมดที่เราต้องเพิ่มใน index.html ของเรา:

 <!DOCTYPE html> ... <body> <h1>Hello Vite! (wait is it pronounced "veet" or "vight"...)</h1> <div></div> <!--Don't forget type="module"! This lets us use ES import syntax in the browser--> <script type="module"> // path to our component. Note we still use .jsx here! import Component from './TimesWeMispronouncedVite.jsx'; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('root'); ReactDOM.render(React.createElement(Component), componentRoot); </script> </body> </html>

ใช่นั่นแหละ ไม่จำเป็นต้องแปลงไฟล์ .jsx ของเราเป็นไฟล์ . .js ที่พร้อมสำหรับเบราว์เซอร์! เมื่อใดก็ตามที่ Vite เห็นการนำเข้า .jsx มันจะแปลงไฟล์นั้นโดยอัตโนมัติเป็นสิ่งที่เบราว์เซอร์สามารถเข้าใจได้ ไม่มีแม้แต่ dist หรือโฟลเดอร์ build เมื่อทำงานในการพัฒนา Vite ประมวลผลทุกอย่างได้ทันที — สมบูรณ์ด้วยการโหลดโมดูลใหม่ทุกครั้งที่เราบันทึกการเปลี่ยนแปลง

โอเค เรามีเครื่องมือสร้างที่มีความสามารถอย่างเหลือเชื่อ เราจะนำสิ่งนี้มาสู่เทมเพลต 11 แบบของเราได้อย่างไร

วิ่ง Vite ข้าง 11ty

ก่อนที่เราจะพูดถึงเรื่องดีๆ เรามาคุยกันเรื่องการวิ่ง 11ty กับ Vite กันก่อนดีกว่า ไปข้างหน้าและติดตั้ง 11ty เป็นการพึ่งพา dev ในไดเร็กทอรีโครงการเดียวกันจากส่วนสุดท้าย:

 npm i -D @11ty/eleventy # yes, it really is 11ty twice

ตอนนี้ มาตรวจสอบเที่ยวบินก่อนบินกันสักหน่อย เพื่อดูว่า 11ty ทำงานได้หรือไม่ เพื่อหลีกเลี่ยงความสับสน เราขอแนะนำให้คุณ:

  1. ลบไฟล์ index.html นั้นจากก่อนหน้านี้
  2. ย้าย TimesWeMispronouncedVite.jsx นั้นไปไว้ในไดเร็กทอรีใหม่ พูด components/ ;
  3. สร้างโฟลเดอร์ src เพื่อให้เว็บไซต์ของเราใช้งานได้
  4. เพิ่มเทมเพลตไปยังไดเร็กทอรี src นั้นเพื่อให้ 11ty ดำเนินการ

ตัวอย่างเช่น ไฟล์ blog-post.md ที่มีเนื้อหาดังต่อไปนี้:

 # Hello world! It's markdown here

โครงสร้างโครงการของคุณควรมีลักษณะดังนี้:

 src/ blog-post.md components/ TimesWeMispronouncedVite.jsx

ตอนนี้เรียกใช้ 11ty จากเทอร์มินัลของคุณดังนี้:

 npx eleventy --input=src

หากทุกอย่างเป็นไปด้วยดี คุณจะเห็นผลลัพธ์ของบิลด์ดังนี้:

 _site/ blog-post/ index.html

โดยที่ _site คือไดเร็กทอรีเอาต์พุตเริ่มต้นของเรา และ blog-post/index.html คือไฟล์ markdown ของเราที่แปลงอย่างสวยงามสำหรับการเรียกดู

โดยปกติ เราจะเรียกใช้ npx eleventy --serve เพื่อหมุนเซิร์ฟเวอร์ dev และไปที่หน้า /blog-post แต่ตอนนี้เรากำลังใช้ Vite สำหรับเซิร์ฟเวอร์ dev ของเรา! เป้าหมายที่นี่คือ:

  1. ให้สิบเอ็ดสร้าง markdown, Pug, nunjucks และอื่นๆ ของเราในไดเร็กทอรี _site
  2. ชี้ Vite ที่ไดเร็กทอรี _site เดียวกันนั้นเพื่อให้สามารถประมวลผลส่วนประกอบ React การนำเข้ารูปแบบแฟนซี และสิ่งอื่น ๆ ที่ 11ty ไม่ได้รับ

ดังนั้น กระบวนการสร้างสองขั้นตอน โดย 11ty มอบ Vite ให้ นี่คือคำสั่ง CLI คุณจะต้องเริ่ม 11ty และ Vite ในโหมด "ดู" พร้อมกัน:

 (npx eleventy --input=src --watch) & npx vite _site

คุณยังสามารถเรียกใช้คำสั่งเหล่านี้ในเทอร์มินัลสองเครื่องแยกกันเพื่อการดีบักที่ง่ายขึ้น

หากโชคดี คุณควรจะสามารถไปที่ http://localhost:3000/blog-post/ (อย่าลืมเครื่องหมายทับอีกครั้ง!) เพื่อดูไฟล์ Markdown ที่ประมวลผลแล้ว

การให้ความชุ่มชื้นบางส่วนด้วยรหัสย่อ

มาทำสรุปสั้น ๆ เกี่ยวกับรหัสย่อ ถึงเวลาทบทวนไวยากรณ์นั้นจากก่อนหน้านี้:

 {% react '/components/TimesWeMispronouncedVite.jsx' %}

สำหรับผู้ที่ไม่คุ้นเคยกับรหัสย่อ: เกือบจะเหมือนกับการเรียกใช้ฟังก์ชัน โดยที่ฟังก์ชันจะส่งคืนสตริงของ HTML เพื่อเลื่อนเข้าสู่หน้าเว็บของคุณ “กายวิภาค” ของรหัสย่อของเราคือ:

  • {% … %}
    Wrapper หมายถึงจุดเริ่มต้นและจุดสิ้นสุดของรหัสย่อ
  • react
    ชื่อของฟังก์ชันรหัสย่อของเรา เราจะกำหนดค่าในอีกสักครู่
  • '/components/TimesWeMispronouncedVite.jsx'
    อาร์กิวเมนต์แรก (และเท่านั้น) ของฟังก์ชันรหัสย่อของเรา คุณสามารถมีข้อโต้แย้งได้มากเท่าที่คุณต้องการ

มาต่อสายย่อแรกของเรากันเถอะ! เพิ่มไฟล์ .eleventy.js ลงในฐานของโปรเจ็กต์ของคุณ และเพิ่มรายการกำหนดค่านี้สำหรับรหัสย่อ react ของเรา:

 // .eleventy.js, at the base of the project module.exports = function(eleventyConfig) { eleventyConfig.addShortcode('react', function(componentPath) { // return any valid HTML to insert return `<div>This is where we'll import ${componentPath}</div>` }) return { dir: { // so we don't have to write `--input=src` in our terminal every time! input: 'src', } } }

ตอนนี้ มาเพิ่มสีสันให้กับ blog-post.md ของเราด้วยรหัสย่อใหม่ของเรา วางเนื้อหานี้ลงในไฟล์ markdown ของเรา:

 # Super interesting programming tutorial Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example! {% react '/components/TimesWeMispronouncedVite.jsx' %}

และถ้าคุณเรียกใช้ npx eleventy แบบด่วน คุณควรเห็นผลลัพธ์นี้ในไดเร็กทอรี _site ของคุณภายใต้ /blog-post/index.html :

 <h1>Super interesting programming tutorial</h1> <p>Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example!</p> <div>This is where we'll import /components/TimesWeMispronouncedVite.jsx</div>

การเขียนรหัสย่อส่วนประกอบของเรา

ตอนนี้ มาทำสิ่งที่มีประโยชน์กับรหัสย่อนั้นกัน จำแท็ก script ที่เราเขียนขณะทดลองใช้ Vite ได้ไหม เราสามารถทำสิ่งเดียวกันในรหัสย่อของเราได้! คราวนี้เราจะใช้อาร์กิวเมนต์ componentPath เพื่อสร้างการนำเข้า แต่ส่วนที่เหลือให้เหมือนเดิม:

 // .eleventy.js module.exports = function(eleventyConfig) { let idCounter = 0; // copy all our /components to the output directory // so Vite can find them. Very important step! eleventyConfig.addPassthroughCopy('components') eleventyConfig.addShortcode('react', function (componentPath) { // we'll use idCounter to generate unique IDs for each "root" div // this lets us use multiple components / shortcodes on the same page idCounter += 1; const componentRootId = `component-root-${idCounter}` return ` <div></div> <script type="module"> // use JSON.stringify to // 1) wrap our componentPath in quotes // 2) strip any invalid characters. Probably a non-issue, but good to be cautious! import Component from ${JSON.stringify(componentPath)}; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('${componentRootId}'); ReactDOM.render(React.createElement(Component), componentRoot); </script> ` }) eleventyConfig.on('beforeBuild', function () { // reset the counter for each new build // otherwise, it'll count up higher and higher on every live reload idCounter = 0; }) return { dir: { input: 'src', } } }

ตอนนี้ การเรียกรหัสย่อของเรา (เช่น {% react '/components/TimesWeMispronouncedVite.jsx' %} ) ควรแสดงผลดังนี้:

 <div></div> <script type="module"> import Component from './components/FancyLiveDemo.jsx'; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('component-root-1'); ReactDOM.render(React.createElement(Component), componentRoot); </script>

เยี่ยมชมเซิร์ฟเวอร์ dev ของเราโดยใช้ (npx eleventy --watch) & vite _site เราควรหาองค์ประกอบตัวนับที่คลิกได้อย่างสวยงาม

Buzzword Alert — สถาปัตยกรรมแบบไฮเดรชั่นและหมู่เกาะบางส่วน

เราเพิ่งแสดง "สถาปัตยกรรมของเกาะ" ในรูปแบบที่ง่ายที่สุด นี่คือแนวคิดที่ว่าแผนผังองค์ประกอบเชิงโต้ตอบของเรา ไม่ จำเป็นต้องใช้ทั้งเว็บไซต์ ในทางกลับกัน เราสามารถหมุนต้นไม้เล็กๆ หรือ "เกาะ" ได้ทั่วทั้งแอปของเรา ขึ้นอยู่กับว่าเราต้องการการโต้ตอบนั้นจากจุดใด มีหน้า Landing Page พื้นฐานของลิงก์ที่ไม่มีสถานะให้จัดการหรือไม่ ยอดเยี่ยม! ไม่จำเป็นต้องใช้ส่วนประกอบแบบโต้ตอบ แต่คุณมีแบบฟอร์มหลายขั้นตอนที่อาจได้รับประโยชน์จากไลบรารี X React หรือไม่? ไม่มีปัญหา. ใช้เทคนิคต่างๆ เช่น รหัสย่อ react เพื่อหมุนเกาะ Form.jsx

สิ่งนี้สอดคล้องกับแนวคิดของ "การให้ความชุ่มชื้นบางส่วน" คุณคงเคยได้ยินคำว่า "ไฮเดรชั่น" หากคุณทำงานกับส่วนประกอบ-y SSG เช่น NextJS หรือ Gatsby กล่าวโดยย่อ เป็นวิธีการ:

  1. แสดงส่วนประกอบของคุณเป็น HTML แบบคงที่ก่อน
    สิ่งนี้ทำให้ผู้ใช้ดูบางอย่างได้เมื่อพวกเขาเข้าเยี่ยมชมเว็บไซต์ของคุณในครั้งแรก
  2. “เติมน้ำ” HTML นี้ด้วยการโต้ตอบ
    นี่คือจุดที่เราเชื่อมต่อ state hooks และ renderers ของเรา เพื่อทำให้การคลิกปุ่มทริกเกอร์บางสิ่งบางอย่างเกิดขึ้นจริง

1-2 หมัดนี้ทำให้เฟรมเวิร์กที่ขับเคลื่อนด้วย JS ทำงานได้สำหรับไซต์แบบคงที่ ตราบใดที่ผู้ใช้มีสิ่งที่จะดูก่อนที่จาวาสคริปต์ของคุณจะแยกวิเคราะห์เสร็จ คุณก็จะได้คะแนนที่ดีจากตัวชี้วัดประภาคารเหล่านั้น

จนกระทั่งคุณไม่ทำ การ “เติมน้ำ” ทั้งเว็บไซต์อาจมีราคาแพง เนื่องจากคุณจะต้องมีกลุ่ม JavaScript ที่พร้อมสำหรับการประมวล ผลทุกองค์ประกอบ DOM สุดท้าย แต่เทคนิคการใช้รหัสย่อของเรา ไม่ ครอบคลุมทั้งหน้า! แต่เรา "บางส่วน" เติมน้ำให้กับเนื้อหาที่มีอยู่ โดยแทรกส่วนประกอบเฉพาะเมื่อจำเป็นเท่านั้น

ไม่ต้องกังวล มีปลั๊กอินสำหรับทั้งหมดนี้: Slinkity

มาสรุปสิ่งที่เราค้นพบที่นี่:

  1. Vite เป็นบันเดิลที่มีความสามารถอย่างเหลือเชื่อที่สามารถประมวลผลไฟล์ได้เกือบทุกประเภท ( jsx , vue และ svelte เป็นต้น) โดยไม่ต้องกำหนดค่าเพิ่มเติม
  2. รหัสย่อเป็นวิธีที่ง่ายในการแทรกส่วน HTML ลงในเทมเพลตของเรา ซึ่งเป็นรูปแบบองค์ประกอบ
  3. เราสามารถใช้รหัสย่อเพื่อแสดงผลบันเดิล JS เชิงโต้ตอบแบบไดนามิกได้ทุกที่ที่เราต้องการโดยใช้ไฮเดรชั่นบางส่วน

แล้วบิลด์การผลิตที่ปรับให้เหมาะสมล่ะ? โหลดสไตล์ที่กำหนดขอบเขตอย่างเหมาะสมหรือไม่ เฮ็คใช้ .jsx เพื่อสร้างทั้งหน้าใช่หรือไม่ ฉันได้รวมข้อมูลทั้งหมดนี้ (และอีกมากมาย!) ไว้ในโปรเจ็กต์ชื่อ Slinkity ฉันตื่นเต้นที่ได้เห็นการต้อนรับอย่างอบอุ่นของชุมชนสำหรับโครงการนี้ และฉันอยากให้คุณผู้อ่านที่รัก ลองทำมันด้วยตัวเอง!

ลองใช้คู่มือการเริ่มต้นฉบับย่อ

Astro ก็เยี่ยมเหมือนกัน

ผู้อ่านที่มองหาเทคโนโลยีล้ำสมัย อาจ นึกถึง Astro อย่างน้อยหนึ่งครั้งในตอนนี้ และฉันไม่สามารถตำหนิคุณได้! สร้างขึ้นโดยมีเป้าหมายคล้ายกัน: เริ่มต้นด้วย HTML ธรรมดา และแทรกองค์ประกอบที่เก็บสถานะไว้ทุกที่ที่คุณต้องการ เฮ้ พวกเขายังให้คุณเริ่มเขียนส่วนประกอบ React ภายใน ส่วนประกอบ Vue หรือ Svelte ภายใน ไฟล์เทมเพลต HTML! มันเหมือนกับรุ่น MDX Xtreme

วิธีการของพวกเขามีค่าใช้จ่ายค่อนข้างมาก: คุณต้องเขียนแอปใหม่ตั้งแต่ต้น นี่หมายถึงรูปแบบเทมเพลตใหม่ที่อิงตาม JSX (ซึ่งคุณอาจไม่สะดวก) ไปป์ไลน์ข้อมูลใหม่ทั้งหมดที่ขาดหายไปสองสามข้อในตอนนี้ และความบกพร่องทั่วไปขณะแก้ไขข้อบกพร่อง

แต่การปั่นค็อกเทล 11ty + Vite ด้วยเครื่องมืออย่าง Slinkity? ถ้าคุณมีไซต์ 11ty อยู่แล้ว Vite ควรติดตั้งโดยไม่ต้องเขียนใหม่ และรหัสย่อควรครอบคลุมกรณีการใช้งานเดียวกันหลายๆ อย่าง เช่น ไฟล์ . .astro ฉันจะยอมรับว่าตอนนี้ ยังห่างไกล จากความสมบูรณ์แบบ แต่เดี๋ยวก่อน มันมีประโยชน์จนถึงตอนนี้ และฉันคิดว่ามันเป็นทางเลือกที่ค่อนข้างดี ถ้าคุณต้องการหลีกเลี่ยงการเขียนซ้ำทั่วทั้งไซต์!

ห่อ

การทดสอบ Slinkity นี้ตอบสนองความต้องการของฉันได้ค่อนข้างดี (และบางส่วนก็ทำได้เช่นกัน!) ใช้สแต็กอะไรก็ได้ที่เหมาะกับ JAM ของคุณ ฉันตื่นเต้นมากที่จะได้แชร์ผลลัพธ์ของปีแห่งการเลิกใช้เครื่องมือสร้างความเสียหาย และฉันก็รู้สึกตื่นเต้นมากที่ได้เห็นว่าเราจะสามารถเชื่อมโยง Jamstack ที่แตกแยกออกไปได้อย่างไร

อ่านเพิ่มเติม

ต้องการดำน้ำลึกลงไปในการให้น้ำบางส่วนหรือ ESM หรือ SSG โดยทั่วไปหรือไม่? ตรวจสอบสิ่งเหล่านี้:

  • สถาปัตยกรรมหมู่เกาะ
    โพสต์บล็อกนี้จาก Jason Format เป็นจุดเริ่มต้นของการอภิปรายเกี่ยวกับ "เกาะ" และ "การดื่มน้ำบางส่วน" ในการพัฒนาเว็บ เต็มไปด้วยไดอะแกรมที่มีประโยชน์และปรัชญาเบื้องหลังแนวคิดนี้
  • ลดความซับซ้อนของสแตติกของคุณด้วยตัวสร้างไซต์สแตติกแบบกำหนดเอง
    บทความอื่นของ SmashingMag ที่จะแนะนำคุณเกี่ยวกับการสร้างเว็บไซต์ที่ใช้ Node ตั้งแต่ต้น มันเป็นแรงบันดาลใจที่ยิ่งใหญ่สำหรับฉัน!
  • ES Modules ได้กำหนดนิยามใหม่ของการพัฒนาเว็บอย่างไร
    โพสต์ส่วนตัวเกี่ยวกับวิธีที่ ES Modules เปลี่ยนแปลงเกมการพัฒนาเว็บ ข้อมูลนี้จะเจาะลึกลงไปอีกเล็กน้อยใน "ตอนนั้นและตอนนี้" ของไวยากรณ์การนำเข้าบนเว็บ
  • การแนะนำส่วนประกอบเว็บ
    คำแนะนำที่ยอดเยี่ยมเกี่ยวกับองค์ประกอบของเว็บ วิธีการทำงานของ Shadow DOM และที่ซึ่งองค์ประกอบของเว็บพิสูจน์ได้ว่ามีประโยชน์ ใช้คู่มือนี้เพื่อใช้ส่วนประกอบที่กำหนดเองกับเฟรมเวิร์กของฉันเอง!