
นี่คือเทมเพลตโครงการ tauri โดยใช้ next.js, bootstrapped โดยการรวม create-next-app และ create tauri-app
เทมเพลตนี้ใช้ pnpm เป็นตัวจัดการการพึ่งพา Node.js
หลังจากโคลนนิ่งเป็นครั้งแรกตั้งค่า hooks git pre-commit:
pnpm prepareเพื่อพัฒนาและเรียกใช้ส่วนหน้าในหน้าต่าง Tauri:
pnpm dev สิ่งนี้จะโหลดส่วนหน้าต่อ Next.js โดยตรงในหน้าต่าง Tauri WebView นอกเหนือจากการเริ่มต้นเซิร์ฟเวอร์การพัฒนาบน localhost:3000
ในการส่งออกส่วนหน้าต่อไปต่อไปผ่าน SSG และสร้างแอปพลิเคชัน Tauri สำหรับการเปิดตัว:
pnpm build โปรดจำไว้ว่าให้เปลี่ยนตัวระบุชุดข้อมูลใน tauri.conf.json > tauri > bundle > identifier เนื่องจากค่าเริ่มต้นจะให้ข้อผิดพลาดที่ป้องกันไม่ให้คุณสร้างแอปพลิเคชันสำหรับการเปิดตัว
ไฟล์แหล่งที่มาของ Frontend Next.js อยู่ในไฟล์แหล่งที่มาของแอปพลิเคชัน src/ และ Tauri Rust ตั้งอยู่ใน src-tauri/ โปรดปรึกษาเอกสารต่อไป JS และ TAURI ตามลำดับสำหรับคำถามที่เกี่ยวข้องกับเทคโนโลยีทั้งสอง
Next.js เป็นเฟรมเวิร์กแนวหน้าที่ดีซึ่งรองรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR) รวมถึงการสร้างไซต์แบบคงที่ (SSG หรือการเรนเดอร์) สำหรับจุดประสงค์ในการสร้างส่วนหน้า Tauri สามารถใช้ SSG ได้เท่านั้นเนื่องจาก SSR ต้องการเซิร์ฟเวอร์ Node.js ที่ใช้งานอยู่
การใช้ Next.js และ SSG ช่วยในการมอบประสบการณ์ส่วนหน้า (SPA) ที่รวดเร็วและมีประสิทธิภาพ ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้สามารถดูได้ที่นี่: https://nextjs.org/docs/basic-features/pages#pre-rendering
next/image ส่วนประกอบ next/image คือการปรับปรุงมากกว่าองค์ประกอบ <img> HTML ปกติพร้อมการปรับให้เหมาะสมเพิ่มเติมในตัวอย่างไรก็ตามเนื่องจากเราไม่ได้ปรับใช้ส่วนหน้าลงบน Vercel โดยตรงการปรับให้เหมาะสมบางอย่างจะต้องถูกปิดใช้งานเพื่อสร้างและส่งออกส่วนหน้าผ่าน SSG ดังนั้นคุณสมบัติ unoptimized จะถูกตั้งค่าเป็น TRUE สำหรับส่วนประกอบ next/image ในการกำหนดค่า next.config.js สิ่งนี้จะช่วยให้ภาพได้รับการเสิร์ฟจากแหล่งที่มาโดยไม่มีการเปลี่ยนแปลงคุณภาพขนาดหรือรูปแบบ
#![feature] ไม่สามารถใช้กับช่องว่างที่เสถียร หากคุณได้รับปัญหานี้เมื่อพยายามเรียกใช้ pnpm tauri dev อาจเป็นไปได้ว่าคุณมีการพึ่งพาสนิมรุ่นใหม่ที่ใช้คุณสมบัติที่ไม่เสถียร pnpm tauri build ควรทำงานเพื่อสร้างการผลิต แต่เพื่อให้คำสั่ง dev ทำงานไม่ว่าจะลดระดับการพึ่งพาหรือใช้สนิมทุกคืนผ่าน rustup override set nightly
หากคุณใช้ฟังก์ชั่น invoke ของ Tauri หรือฟังก์ชั่น Tauri ที่เกี่ยวข้องกับระบบปฏิบัติการใด ๆ จากภายใน JavaScript คุณอาจพบข้อผิดพลาดนี้เมื่อนำเข้าฟังก์ชั่นในบริบทที่ไม่ใช่เบราว์เซอร์ทั่วโลก นี่เป็นเพราะลักษณะของเซิร์ฟเวอร์ dev next.js 'ใช้งานเซิร์ฟเวอร์ Node.js อย่างมีประสิทธิภาพสำหรับ SSR และ Hot Module Replacement (HMR) และ Node.js ไม่มีความคิดเกี่ยวกับ window หรือ navigator
ตรวจสอบให้แน่ใจว่าคุณกำลังเรียกใช้ฟังก์ชั่นเหล่านี้ภายในบริบทของเบราว์เซอร์เช่นภายในองค์ประกอบที่ตอบสนองภายใน hook useEffect เมื่อ DOM มีอยู่จริงในตอนนั้น หากคุณกำลังพยายามใช้ฟังก์ชั่น Tauri ในไฟล์แหล่งยูทิลิตี้ทั่วไปวิธีแก้ปัญหาคือการใช้การฉีดพึ่งพาสำหรับฟังก์ชั่นเองเพื่อชะลอการนำเข้าจริงของฟังก์ชั่นจริง (ดูตัวอย่างด้านล่างสำหรับข้อมูลเพิ่มเติม)
ตัวอย่างการใช้ฟังก์ชั่น invoke ของ Tauri:
src/lib/some_tauri_functions.ts (ปัญหา)
// Generalized file containing all the invoke functions we need to fetch data from Rust
import { invoke } from "@tauri-apps/api/tauri"
const loadFoo = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_foo" )
}
const loadBar = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_bar" )
}
const loadBaz = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_baz" )
}
// and so on ... src/lib/some_tauri_functions.ts (แก้ไข)
// Generalized file containing all the invoke functions we need to fetch data from Rust
//
// We apply the idea of dependency injection to use a supplied invoke function as a
// function argument, rather than directly referencing the Tauri invoke function.
// Hence, don't import invoke globally in this file.
//
// import { invoke } from "@tauri-apps/api/tauri" <-- remove this!
//
import { InvokeArgs } from "@tauri-apps/api/tauri"
type InvokeFunction = < T > ( cmd : string , args ?: InvokeArgs | undefined ) => Promise < T >
const loadFoo = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_foo" )
}
const loadBar = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_bar" )
}
const loadBaz = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_baz" )
}
// and so on ... จากนั้นเมื่อใช้ loadFoo / loadBar / loadBaz ภายในส่วนประกอบ React ของคุณนำเข้าฟังก์ชั่นการเรียกใช้จาก @tauri-apps/api และผ่าน invoke ใช้ฟังก์ชัน loadxxx เป็นอาร์กิวเมนต์ InvokeFunction สิ่งนี้ควรอนุญาตให้ Tauri API จริงมารวมอยู่ในบริบทของส่วนประกอบปฏิกิริยาดังนั้นจึงไม่ควรโหลดโดย next.js เมื่อเริ่มต้นเริ่มต้นจนกว่าเบราว์เซอร์จะโหลดหน้าเสร็จแล้ว
import() เนื่องจาก Tauri API จำเป็นต้องอ่านจาก window และวัตถุ navigator ของเบราว์เซอร์ข้อมูลนี้จึงไม่มีอยู่ในโหนดและสภาพแวดล้อม SSR หนึ่งสามารถสร้างฟังก์ชั่นที่ส่งออกซึ่งห่อหุ้ม Tauri API ที่อยู่ด้านหลังการเรียกใช้งาน Runtime import() แบบไดนามิก
ตัวอย่าง: สร้าง src/lib/tauri.ts เพื่อส่งออกอีกครั้ง invoke
import type { InvokeArgs } from "@tauri-apps/api/tauri"
const isNode = ( ) : boolean =>
Object . prototype . toString . call ( typeof process !== "undefined" ? process : 0 ) ===
"[object process]"
export async function invoke < T > (
cmd : string ,
args ?: InvokeArgs | undefined ,
) : Promise < T > {
if ( isNode ( ) ) {
// This shouldn't ever happen when React fully loads
return Promise . resolve ( undefined as unknown as T )
}
const tauriAppsApi = await import ( "@tauri-apps/api" )
const tauriInvoke = tauriAppsApi . invoke
return tauriInvoke ( cmd , args )
} จากนั้นแทนที่จะนำ import { invoke } from "@tauri-apps/api/tauri" ให้ใช้ Invoke จาก import { invoke } from "@/lib/tauri"
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ next.js ลองดูแหล่งข้อมูลต่อไปนี้:
และเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับ Tauri ลองดูแหล่งข้อมูลต่อไปนี้: