คุณคงเคยได้ยินข่าวลือมากมายเกี่ยวกับเด็กใหม่ล่าสุดในกลุ่มเฟรมเวิร์กอย่าง Remix อาจเป็นเรื่องน่าแปลกใจที่เริ่มกลับมาในปี 2019 แต่เดิมมีให้ใช้งานเป็นเฟรมเวิร์กพรีเมียมแบบสมัครสมาชิกเท่านั้น ในปี 2021 ผู้ก่อตั้งได้ระดมทุนเมล็ดพันธุ์และเปิดเฟรมเวิร์กเพื่อให้ผู้ใช้เริ่มใช้ Remix ได้ฟรี ประตูระบายน้ำเปิดออกและดูเหมือนว่าทุกคนจะพูดถึงเรื่องนี้ไม่ว่าจะดีหรือไม่ดี มาดูข้อมูลเบื้องต้นเกี่ยวกับ Remix กัน
Remix เป็นเฟรมเวิร์ก JavaScript แรกของเซิร์ฟเวอร์ "edge" ใช้ React, อย่างน้อยก็ตอนนี้, สำหรับส่วนหน้าและจัดลำดับความสำคัญของการเรนเดอร์แอปพลิเคชันฝั่งเซิร์ฟเวอร์ บนขอบ. แพลตฟอร์มสามารถใช้โค้ดฝั่งเซิร์ฟเวอร์และเรียกใช้เป็น ฟังก์ชันไร้เซิร์ฟเวอร์หรือขอบ ทำให้ราคาถูกกว่าเซิร์ฟเวอร์แบบเดิมและทำให้ใกล้ชิดกับผู้ใช้มากขึ้น ผู้ก่อตั้ง Remix ชอบเรียกมันว่าเฟรมเวิร์ก "สแต็กกลาง" เพราะมันปรับคำขอและการตอบสนองระหว่างเซิร์ฟเวอร์และไคลเอนต์สำหรับแพลตฟอร์มที่กำลังใช้งานอยู่
กำลังปรับใช้ Remix
เนื่องจาก Remix ต้องใช้เซิร์ฟเวอร์ มาพูดถึงวิธีการปรับใช้กันเถอะ Remix ไม่ได้จัดเตรียมเซิร์ฟเวอร์เอง - คุณนำเซิร์ฟเวอร์มา - อนุญาตให้เรียกใช้ในใดก็ได้ Node.js or ดีโน่ สิ่งแวดล้อม รวมทั้ง Netlify Edge และ แพลตฟอร์มแอพของ DigitalOcean. รีมิกซ์ตัวเองคือ ผู้รวบรวมซึ่งเป็นโปรแกรมที่แปลคำขอสำหรับแพลตฟอร์มที่กำลังทำงานอยู่ กระบวนการนี้ใช้ สร้าง เพื่อสร้างตัวจัดการสำหรับการร้องขอไปยังเซิร์ฟเวอร์ ตัวจัดการ HTTP ที่ใช้นั้นสร้างขึ้นบน API ดึงข้อมูลเว็บ และถูกรันบนเซิร์ฟเวอร์โดย การปรับตัว สำหรับแพลตฟอร์มที่พวกเขาจะนำไปใช้
กองรีมิกซ์
สแต็ค Remix คือโปรเจ็กต์ที่มีเครื่องมือทั่วไปบางอย่างที่กำหนดค่าไว้ล่วงหน้าสำหรับคุณ มี สามกองอย่างเป็นทางการ ที่ดูแลโดยทีม Remix และทั้งหมดได้รับการตั้งชื่อตามแนวดนตรี นอกจากนี้ยังมีสแต็ค Remix ของชุมชนจำนวนหนึ่งรวมถึง กองเคป็อป สร้างโดยทีมเทมเพลตที่ Netlify กองนี้เป็นโรงไฟฟ้าและรวมถึง a ศุภเบส ฐานข้อมูลและการรับรองความถูกต้อง องศาเซลเซียส สำหรับการจัดแต่งทรงผม ต้นไซเปรซ การทดสอบแบบ end-to-end, สวย การจัดรูปแบบโค้ด, ESLint ผ้าสำลีและ สิ่งที่พิมพ์ด้วยพิมพ์ดีด การพิมพ์แบบคงที่ ตรวจสอบโพสต์ของ Tara Manicsic เกี่ยวกับการปรับใช้ K-Pop Stack
เส้นทางแคช
แม้ว่า Remix จะต้องการเซิร์ฟเวอร์ แต่ก็ยังสามารถใช้ประโยชน์จาก กองแยม ประโยชน์จากการแคชเส้นทาง ไซต์สแตติกหรือการสร้างไซต์สแตติก (SSG) คือเมื่อเนื้อหาทั้งหมดของคุณแสดงผล ณ เวลาสร้างและคงอยู่ คงที่ จนกว่าจะสร้างใหม่อีกครั้ง เนื้อหาถูกสร้างไว้ล่วงหน้าและสามารถใส่ลงใน CDN ได้ สิ่งนี้มีประโยชน์มากมายและการโหลดไซต์ที่รวดเร็วสำหรับผู้ใช้ปลายทาง อย่างไรก็ตาม Remix ไม่ได้ทำ SSG ทั่วไปเหมือนกับเฟรมเวิร์ก React ยอดนิยมอื่น ๆ รวมถึง Next.js และ Gatsby เพื่อรับประโยชน์บางประการของ SSG คุณสามารถใช้เนทีฟ ส่วนหัว HTTP ของการควบคุมแคช ในรีมิกซ์ ฟังก์ชันส่วนหัว เพื่อแคชเส้นทางเฉพาะหรือโดยตรงใน root.tsx
ไฟล์
[[headers]]
for = "/build/*"
[headers.values]
"Cache-Control" = "public, max-age=31536000, s-maxage=31536000"
จากนั้นเพิ่มในของคุณ ฟังก์ชันส่วนหัว ที่คุณต้องการ แคชนี้เป็นเวลาหนึ่งชั่วโมง:
export function headers() {
return {
"Cache-Control": "public, s-maxage=360",
};
};
การกำหนดเส้นทางการรีมิกซ์
กรอบงานจำนวนมากได้พึ่งพาการกำหนดเส้นทางตามระบบไฟล์ นี่เป็นเทคนิคที่ใช้โฟลเดอร์ที่กำหนดเพื่อกำหนดเส้นทางสำหรับแอปพลิเคชันของคุณ โดยทั่วไปจะมีรูปแบบพิเศษสำหรับการประกาศเส้นทางและปลายทางแบบไดนามิก ความแตกต่างที่ใหญ่ที่สุดในปัจจุบันระหว่าง Remix และเฟรมเวิร์กยอดนิยมอื่นๆ คือความสามารถในการใช้ การกำหนดเส้นทางที่ซ้อนกัน.
ทุกแอป Remix เริ่มต้นด้วย root.tsx
ไฟล์. นี่คือตำแหน่งที่แสดงผลฐานทั้งหมดของแอป คุณจะพบเค้าโครง HTML ทั่วไปบางส่วนที่นี่ เช่น <html>
แท็ก, the <head>
แท็กแล้ว <body>
แท็กด้วยองค์ประกอบที่จำเป็นในการแสดงผลแอป สิ่งหนึ่งที่จะชี้ให้เห็นที่นี่คือ <Scripts>
องค์ประกอบคือสิ่งที่เปิดใช้งาน JavaScript บนไซต์ บางสิ่งจะทำงานโดยปราศจากมัน แต่ไม่ใช่ทุกอย่าง ดิ root.tsx
file ทำหน้าที่เป็นรูปแบบหลักสำหรับทุกสิ่งที่อยู่ภายใน routes
ไดเร็กทอรีทุกอย่างในเส้นทางจะแสดงโดยที่ <Outlet/>
ส่วนประกอบอยู่ใน root.tsx
. นี่คือพื้นฐานของการกำหนดเส้นทางแบบซ้อนใน Remix
การกำหนดเส้นทางที่ซ้อนกัน
Remix ไม่เพียงแต่ก่อตั้งโดยทีมงานบางส่วนจาก ตอบสนองเราเตอร์มันยัง ใช้ ตอบสนองเราเตอร์ อันที่จริงพวกมันคือ นำสิ่งดีๆ บางอย่างเกี่ยวกับ Remix กลับมาที่ React Router. ปัญหาที่ซับซ้อนที่ผู้ดูแล Next.js และ SvelteKit กำลังพยายามแก้ไขอยู่ในขณะนี้คือการกำหนดเส้นทางแบบซ้อน
การกำหนดเส้นทางแบบซ้อนไม่เหมือนกับการกำหนดเส้นทางแบบเดิม เส้นทางใหม่จะนำผู้ใช้ไปยังหน้าใหม่ แต่ละเส้นทางที่ซ้อนกันเป็นส่วนที่แยกจากกันของหน้าเดียวกัน อนุญาตให้แยกข้อกังวลโดยการรักษาตรรกะทางธุรกิจที่เกี่ยวข้องกับไฟล์ที่ต้องการเท่านั้น Remix สามารถจัดการข้อผิดพลาดที่แปลเป็นภาษาท้องถิ่นได้เฉพาะส่วนของหน้าที่เส้นทางที่ซ้อนอยู่เท่านั้น เส้นทางอื่นๆ บนหน้ายังคงใช้งานได้ และเส้นทางที่เสียหายสามารถให้บริบทที่เกี่ยวข้องกับข้อผิดพลาดโดยไม่ทำให้ทั้งหน้าหยุดทำงาน
Remix ทำสิ่งนี้เมื่อไฟล์รูทใน app/routes
มีชื่อเหมือนกับไดเร็กทอรีของไฟล์ที่จะโหลดภายในไฟล์ฐาน ไฟล์รูทจะกลายเป็น a แบบ สำหรับไฟล์ในไดเร็กทอรีโดยใช้ an <Outlet />
คอมโพเนนต์เพื่อบอก Remix ว่าจะโหลดเส้นทางอื่นได้ที่ไหน
ส่วนประกอบทางออก
พื้นที่ <Outlet />
คอมโพเนนต์เป็นสัญญาณไปยัง Remix ว่าควรแสดงเนื้อหาสำหรับเส้นทางที่ซ้อนกัน มันถูกวางไว้ในไฟล์ที่รูทของ app/routes
ไดเร็กทอรีที่มีชื่อเดียวกับเส้นทางที่ซ้อนกัน รหัสต่อไปนี้จะอยู่ในa app/routes/about.tsx
ไฟล์และรวมถึงช่องสำหรับไฟล์ภายใน app/routes/about
โฟลเดอร์:
import { Outlet } from "@remix-run/react";
export default function About() {
return (
<>
<section>
I am the parent layout. I will be on any page inside of my named directory.
</section>
{ /* All of my children, the files in the named directory, will go here. */ }
<Outlet />
</>
)
}
โครงสร้างโฟลเดอร์
ไฟล์ใด ๆ ใน app/routes/
ไดเร็กทอรีกลายเป็นเส้นทางที่ URL ของชื่อ ไดเร็กทอรียังสามารถเพิ่มด้วย an index.tsx
ไฟล์
app/
├── routes/
│ │
│ └── blog
| | ├── index.tsx ## The /blog route
│ └── about.tsx ## The /about route
│ ├── index.tsx ## The / or home route
└── root.tsx
หากเส้นทางมีชื่อเดียวกับไดเร็กทอรี ไฟล์ที่มีชื่อจะกลายเป็นไฟล์เลย์เอาต์สำหรับไฟล์ภายในไดเร็กทอรีและไฟล์เลย์เอาต์ต้องการ ส่วนประกอบทางออก เพื่อวางเส้นทางที่ซ้อนกัน
app/
├── routes/
│ │
│ └── about
│ │ ├── index.tsx
│ ├── about.tsx ## this is a layout for /about/index.tsx
│ ├── index.tsx
└── root.tsx
เลย์เอาต์ยังสามารถสร้างได้โดยนำหน้าด้วยขีดล่างคู่ (__
).
app/
├── routes/
│ │
│ └── about
│ │ ├── index.tsx
│ ├── index.tsx
│ ├── about.tsx
│ ├── __blog.tsx ## this is also a layout
└── root.tsx
https://your-url.com/about
จะยังคงทำให้ app/routes/about.tsx
ไฟล์ แต่จะแสดงผลสิ่งที่อยู่ใน .ด้วย app/routes/about/index.tsx
ที่ ส่วนประกอบทางออก อยู่ในมาร์กอัปของ app/routes/about.tsx
.
เส้นทางแบบไดนามิก
เส้นทางแบบไดนามิกคือเส้นทางที่เปลี่ยนแปลงตามข้อมูลใน URL นั่นอาจเป็นชื่อบล็อกโพสต์หรือรหัสลูกค้า แต่ไม่ว่าจะเป็น $
ไวยากรณ์ที่เพิ่มที่ด้านหน้าของเส้นทางส่งสัญญาณไปยัง Remix ว่าเป็นไดนามิก ชื่อไม่สำคัญนอกจาก $
คำนำหน้า
app/
├── routes/
│ │
│ └── about
│ │ ├── $id.tsx
│ │ ├── index.tsx
│ ├── about.tsx ## this is a layout for /about/index.tsx
│ ├── index.tsx
└── root.tsx
ดึงข้อมูลนั้น!
เนื่องจาก Remix แสดงข้อมูลทั้งหมดบนเซิร์ฟเวอร์ คุณจึงไม่เห็นอะไรมากมายที่เป็นมาตรฐานของแอป React เช่น useState()
และ useEffect()
ตะขอใน Remix ไม่จำเป็นต้องมีสถานะฝั่งไคลเอ็นต์เนื่องจากได้รับการประเมินบนเซิร์ฟเวอร์แล้ว
ไม่ว่าคุณจะใช้เซิร์ฟเวอร์ประเภทใดในการดึงข้อมูลก็ตาม เนื่องจาก Remix อยู่ระหว่างคำขอและการตอบกลับ และแปลอย่างเหมาะสม คุณสามารถใช้มาตรฐาน API ดึงข้อมูลเว็บ. Remix ทำสิ่งนี้ใน loader
ฟังก์ชั่นที่ เพียง ทำงานบนเซิร์ฟเวอร์และใช้ useLoaderData()
ขอเพื่อแสดงข้อมูลในองค์ประกอบ นี่คือตัวอย่างการใช้ Cat เป็นบริการ API เพื่อแสดงภาพแมวแบบสุ่ม
import { Outlet, useLoaderData } from '@remix-run/react'
export async function loader() {
const response = await fetch('<https://cataas.com/cat?json=true>')
const data = await response.json()
return {
data
}
}
export default function AboutLayout() {
const cat = useLoaderData<typeof loader>()
return (
<>
<img
src={`https://cataas.com/cat/${cat}`}
alt="A random cat."
/>
<Outlet />
</>
)
}
พารามิเตอร์เส้นทาง
ในเส้นทางแบบไดนามิก เส้นทางที่นำหน้าด้วย $
ต้องสามารถเข้าถึงพารามิเตอร์ URL เพื่อจัดการข้อมูลที่ควรแสดงผล ดิ loader
ฟังก์ชั่นเข้าถึงสิ่งเหล่านี้ได้ผ่าน a params
ข้อโต้แย้ง.
import { useLoaderData } from '@remix-run/react'
import type { LoaderArgs } from '@remix-run/node'
export async function loader({ params }: LoaderArgs) {
return {
params
}
}
export default function AboutLayout() {
const { params } = useLoaderData<typeof loader>()
return <p>The url parameter is {params.tag}.</p>
}
ฟังก์ชันรีมิกซ์อื่นๆ
Remix มีฟังก์ชันตัวช่วยอื่นๆ สองสามอย่างที่เพิ่มฟังก์ชันพิเศษให้กับองค์ประกอบและแอตทริบิวต์ HTML ปกติใน โมดูลเส้นทาง API. แต่ละเส้นทางสามารถกำหนดฟังก์ชันประเภทนี้ได้เอง
ฟังก์ชั่นการดำเนินการ
An action
ฟังก์ชันช่วยให้คุณเพิ่มฟังก์ชันพิเศษให้กับการดำเนินการของแบบฟอร์มโดยใช้เว็บมาตรฐาน API ของฟอร์มดาต้า.
export async function action({ request }) {
const body = await request.formData();
const todo = await fakeCreateTodo({
title: body.get("title"),
});
return redirect(`/todos/${todo.id}`);
}
ฟังก์ชันส่วนหัว
ใด ส่วนหัวมาตรฐาน HTTP สามารถไปใน headers
การทำงาน. เนื่องจากแต่ละเส้นทางสามารถมีส่วนหัว เพื่อหลีกเลี่ยงความขัดแย้งกับเส้นทางที่ซ้อนกัน เส้นทางที่ลึกที่สุด — หรือ URL ที่มีเครื่องหมายทับ (/
) — ชนะ คุณยังสามารถส่งส่วนหัวผ่าน actionHeaders
, loaderHeaders
,หรือ parentHeaders
export function headers({
actionHeaders,
loaderHeaders,
parentHeaders,
}) {
return {
"Cache-Control": loaderHeaders.get("Cache-Control"),
};
}
ฟังก์ชันเมตา
ฟังก์ชันนี้จะตั้งค่าเมตาแท็กสำหรับเอกสาร HTML หนึ่งตั้งอยู่ใน root.tsx
โดยค่าเริ่มต้น แต่สามารถอัปเดตสำหรับแต่ละเส้นทางได้
export function meta() {
return {
title: "Your page title",
description: "A new description for each route.",
};
};
ฟังก์ชั่นลิงค์
HTML link
องค์ประกอบอาศัยอยู่ใน <head>
ของเอกสาร HTML และนำเข้า CSS เหนือสิ่งอื่นใด ดิ links
ฟังก์ชั่นเพื่อไม่ให้สับสนกับ <Link />
ส่วนประกอบอนุญาตให้คุณนำเข้าสิ่งของในเส้นทางที่ต้องการเท่านั้น ตัวอย่างเช่น ไฟล์ CSS สามารถกำหนดขอบเขตและนำเข้าได้เฉพาะบนเส้นทางที่ต้องการไฟล์เฉพาะเหล่านั้น ดิ link
องค์ประกอบถูกส่งกลับจากa links()
ทำหน้าที่เป็นอาร์เรย์ของวัตถุและสามารถเป็น a HtmlLinkDescriptor
จาก link
API หรือ PageLinkDescriptor
ที่สามารถดึงข้อมูลล่วงหน้าสำหรับหน้า
export function links() {
return [
// add a favicon
{
rel: "icon",
href: "/favicon.png",
type: "image/png",
},
// add an external stylesheet
{
rel: "stylesheet",
href: "<https://example.com/some/styles.css>",
crossOrigin: "true",
},
// add a local stylesheet,
{ rel: "stylesheet", href: stylesHref },
// prefetch a page's data
{ page: "/about/community" }
]
}
เชื่อมระหว่างเส้นทาง
Remix จัดเตรียมองค์ประกอบเพื่อไประหว่างเส้นทางต่างๆ ในแอปของคุณที่เรียกว่า <Link/>
. หากต้องการรับการกำหนดเส้นทางฝั่งไคลเอ็นต์ ให้ใช้ <Link to="">Name</Link>
ส่วนประกอบแทน <a href="">Name</a>
. <Link />
ส่วนประกอบยังใช้เสาของ prefetch
ด้วยการยอมรับ none
โดยค่าเริ่มต้น, intent
เพื่อดึงข้อมูลล่วงหน้าหาก Remix ตรวจพบว่าผู้ใช้วางเมาส์เหนือหรือเน้นที่ลิงก์ หรือ render
ซึ่งจะดึงข้อมูลของเส้นทางทันทีที่มีการแสดงลิงก์
import { Link } from "@remix-run/react";
export default function Nav() {
return (
<nav>
<Link to="/">Home</Link>{" "}
<Link to="/about">About</Link>{" "}
<Link to="/about/community" prefetch="intent">Community</Link>
</nav>
);
}
ขั้นตอนถัดไป
ตอนนี้คุณรู้พื้นฐานของ Remix แล้ว และคุณพร้อมที่จะเริ่มต้นสร้างแอปพลิเคชันแล้วใช่ไหม เรียบเรียงให้ แอพเรื่องตลก และ กวดวิชาบล็อก เพื่อให้คุณเริ่มใช้ความรู้พื้นฐานนี้ คุณยังสามารถเริ่มต้นจากศูนย์และสร้างแอป Remix ใหม่ได้ หรือถ้าคุณพร้อมที่จะดำน้ำ ให้ กองเคป็อป ลอง. ฉันสนุกกับเวลาของฉันกับ Remix มาก และชอบการมุ่งเน้นที่มาตรฐานเว็บและนำมันกลับไปสู่พื้นฐาน ตอนนี้ถึงตาคุณแล้วที่จะเริ่มสร้าง!