
这是一个使用Next.js的Tauri项目模板,通过组合create-next-app并create tauri-app来引导。
该模板将pnpm用作node.js依赖项管理器。
首次克隆后,设置Git Pre-Commit钩子:
pnpm prepare在陶里窗口中开发和运行前端:
pnpm dev除了在localhost:3000 ,这还将直接在Tauri WebView窗口中加载。
要通过SSG导出下一个。
pnpm build请记住要更改tauri.conf.json > tauri > bundle > identifier中的捆绑包标识符,因为默认值将产生一个错误,从而阻止您构建发布应用程序以进行发布。
Next.js前端源文件位于src/中,Tauri Rust应用程序源文件位于src-tauri/ 。请分别咨询Next.js和Tauri文档,以获取与任何两种技术有关的问题。
Next.js是一个很棒的React前端框架,它支持服务器端渲染(SSR)以及静态站点生成(SSG或Predendering)。为了创建Tauri Frontend,只能使用SSG,因为SSR需要一个Active node.js服务器。
使用Next.js和SSG有助于提供快速而性能的单页应用程序(SPA)前端体验。有关此信息的更多信息,请参见:https://nextjs.org/docs/basic-features/pages#pre-rendering
next/image next/image组件是对常规<img> HTML元素的增强功能,并内置了其他优化。但是,由于我们没有直接将前端部署到Vercel上,因此必须禁用一些优化来通过SSG正确构建和导出前端。因此,对于next.config.js配置中的next/image组件, unoptimized属性设置为true。这将使图像可以从源中提供,而不会改变其质量,大小或格式。
#![feature]不得在稳定版本频道上使用如果您在尝试运行pnpm tauri dev时会遇到此问题,则可能是您有使用不稳定功能的Rust依赖性版本的较新版本。 pnpm tauri build仍应用于生产构建,但是要使Dev命令正常工作,请降级依赖性或通过rustup override set nightly使用Rust。
如果您正在使用JavaScript中的Tauri的invoke函数或任何与OS相关的Tauri函数,则在全局,非浏览器上下文中导入该函数时,可能会遇到此错误。这是由于Next.js的开发服务器有效地运行了用于SSR和热模块替换(HMR)的Node.js服务器的性质,而Node.js则没有window或navigator的概念。
确保您在浏览器上下文中调用这些功能,例如,当DOM实际存在时,在useEffect挂钩内部的React组件中。如果您试图在广义实用程序文件中使用Tauri函数,则解决方法是使用依赖项注入该功能本身来延迟实际函数的实际导入(有关更多信息,请参见下面的示例)。
使用Tauri的invoke功能的示例:
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 ...然后,当在您的React组件中使用loadFoo / loadBar / loadBaz时,请从@tauri-apps/api导入Indoke函数,然后将invoke作为InvokeFunction参数传递到LOADXXX函数中。这应该允许实际的Tauri API仅在React组件的上下文中捆绑在一起,因此Next.js不应在初始启动时加载它,直到浏览器完成加载页面为止。
import()由于Tauri API需要从浏览器的window和navigator对象读取,因此该数据不存在于Node.js中,因此不存在SSR环境。可以创建一个导出的功能,该功能将Tauri API包裹在动态运行时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" ,而是import { invoke } from "@/lib/tauri"使用Invoke。
要了解有关Next.js的更多信息,请查看以下资源:
要了解有关Tauri的更多信息,请查看以下资源: