본문으로 건너뛰기

Next.js

이 안내서는 Next.js를 프론트엔드 빌드 도구로 사용해 첫 Tauri 앱을 만드는 과정을 설명합니다.

정보

Before we continue, make sure you have completed the prerequisites to have a working development environment.

Tauri는 모든 프론트엔드 프레임워크와 Rust 코어를 함께 사용해 데스크톱 앱을 빌드하기 위한 프레임워크입니다. 각 앱은 두 개의 부분으로 구성됩니다:

  1. 창을 만들고 그 창에 네이티브 기능을 내어주는 Rust 바이너리
  2. 창 안에서 사용자 인터페이스를 만들기 위해 선택한 프론트엔드

따라가다보면, 먼저 프론트엔드를 스캐폴딩하고, Rust 프로젝트를 설정한 다음, 마지막으로 어떻게 둘 사이 통신이 이루어지는지 볼 수 있습니다.

다음은 빌드하게 될 내용의 미리보기 입니다:

앱 미리 보기 앱 미리 보기

프론트엔드 만들기

Next.js는 서버 측 렌더링 (SSR)과 정적 사이트 생성 (SSG) 기능을 제공하는 React 프레임워크입니다. Next.js가 Tauri와 함께 잘 작동하도록 만들기 위해 SSG 모드를 사용해 최종 바이너리에 정적 파일만 생성해 포함시킵니다.

Next.js는 여러 정의된 템플릿에서 새 프로젝트를 빠르게 설정할 수 있는, create-tauri-app과 비슷한 스캐폴딩 유틸리티를 제공합니다. For this guide, we will use the suggested default for all questions, including TypeScript support and the new App Router feature stabilized in v13.4. In case you use the the old routes/ directory instead or on top of the app/ directory, you still need to change the config as explained in the Next.js Static Exports section but the way you use Tauri specific JS APIs will be different than described below.

npx create-next-app@latest --use-npm
  1. Project name
    This will be the name of your project. It corresponds to the name of the folder this utility will create but has otherwise no effect on your app. 원하는 이름이라면 무엇이든 적을 수 있습니다.

Next.js Static Exports

Because Tauri does not have a Node.js runtime you must set Next.js to SSG/SPA mode. This will typically result in faster page loads but also has a few caveats to be aware of, therefore we recommend to carefully read through Next.js' official docs on Static Exports.

These docs also show one required configuration change we will always have to change for a Tauri + Next.js app. To do this, edit the next.config.js file in the project's root directory and add the following:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
}

module.exports = nextConfig

This will change the behavior of the next build to produce an out/ folder containing the HTML/CSS/JS assets for your application instead of writing them to a .next/ directory specific to Next.js' runtime.

There are a few more possible configuration options, so make sure to read through the Static Exports docs as mentioned above and adapt the configuration file according to the needs of your project.

Rust 프로젝트 생성하기

모든 Tauri 앱의 중심에는 tauri라는 Rust crate를 통해 창, 웹뷰, 운영 체제의 호출을 관리하는 Rust 바이너리가 있습니다. 프로젝트는 Rust의 공식 패키지 관리자이자 범용 빌드 도구인 Cargo로 관리합니다.

Tauri CLI가 내부적으로 Cargo를 사용해, 직접 만져야 할 일은 적습니다. Cargo에는 CLI로는 접근할 수 없지만 유용한 기능이 많습니다. 예를 들어, 테스트나 린트, 포매팅 등이 있습니다. Cargo 공식 문서를 참조하시면 더 많이 알아보실 수 있습니다.

Tauri CLI 설치

Tauri CLI 미설치시 아래 중 하나의 명령어로 설치가능합니다. 무엇을 써야 하는지 잘 모르시겠나요? 자주 물어보는 질문 항목을 살펴보세요.

npm install --save-dev @tauri-apps/cli
For npm to detect Tauri correctly you need to add it to the "scripts" section in your package.json file:
package.json
"scripts": {
"tauri": "tauri"
}

Tauri와의 사용을 위해 미리 설정된 작은 Rust 프로젝트를 만드시려면, 터미널을 열어 다음 명령어를 입력하세요:

npm run tauri init

일련의 질문을 통해 프로젝트 구성을 진행해나갈 것입니다:

  1. What is your app name?
    최종 번들의 이름이자, 운영 체제가 부를 앱의 이름입니다. 원하는 이름이라면 무엇이든 적을 수 있습니다.

  2. What should the window title be?
    기본 메인 창의 제목입니다. 원하는 제목을 적으시면 됩니다.

  3. Where are your web assets (HTML/CSS/JS) located relative to the <current dir>/src-tauri/tauri.conf.json file that will be created?
    Tauri가 프로덕션으로 빌드할 때 프론트엔드 애셋을 불러올 경로입니다.
    Use ../out for this value.

  4. What is the URL of your dev server?
    개발 과정에서 Tauri가 불러올 URL이나 파일 경로입니다.
    Use http://localhost:3000 for this value.

  5. What is your frontend dev command?
    프론트엔드 개발 서버 실행에 쓰이는 명령어입니다.
    Use npm run dev for this value (make sure to adapt this to use the package manager of your choice).

  6. What is your frontend build command?
    프론트엔드 빌드에 쓰이는 명령어입니다.
    Use npm run build for this value (make sure to adapt this to use the package manager of your choice).
정보

만약 Rust에 익숙하시다면, tauri initcargo init과 매우 비슷하게 동작한다는 것을 눈치채셨을 것입니다. 만약 손수 설정하는 것을 선호하신다면 그냥 cargo init을 수행하고, 필요한 Tauri 의존성을 받으셔도 좋습니다.

tauri init 명령어는 src-tauri 폴더를 만듭니다. 그 폴더에 코어와 관련된 파일을 두는 것이 Tauri 앱의 규칙입니다. 이 폴더의 내용물을 빠르게 살펴봅시다:

  • Cargo.toml
    Cargo의 매니페스트 파일입니다. 앱에서 어떤 Rust crate에 의존하는지 정의하고, 앱에 대한 부가 정보를 기록하고, 그 외 다양한 일을 할 수 있습니다. 완전한 참고 자료로써 Cargo 매니페스트 형식 문서를 살펴보실 수 있습니다.

  • tauri.conf.json
    이름부터 허용된 API 목록까지, 이 파일을 통해 Tauri 앱의 다양한 부분을 맞춤 설정합니다. Tauri API 설정 문서에서 지원하는 옵션의 전체 목록과 각 옵션의 자세한 설명을 확인하실 수 있습니다.

  • src/main.rs
    이 부분은 Rust 프로그램의 시작점이자, Tauri를 구동하는 위치입니다. 두 부분으로 나누어 볼 수 있습니다:

    src/main.rs
     #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

    fn main() {
    tauri::Builder::default()
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
    }

    The line beginning with the cfg! 매크로로 시작합니다: 일반적으로 번들 앱을 실행할 때, Windows에서 나오는 명령 프롬프트 창을 비활성화합니다. 만약 Windows를 사용 중이시라면, 해당 줄을 주석 처리한 후 어떤 일이 일어나는지 살펴보세요.

    main 함수는 진입점으로 프로그램을 실행할 때 가장 먼저 불리는 함수입니다.

  • icons
    앱에 멋진 아이콘을 추가할 기회가 바로 여기에 있습니다! 빠른 시작을 위해, 기본 아이콘 묶음을 미리 포함시켜 두었습니다. 앱을 공개하기 전, 기본 아이콘을 교체하셔야 합니다. Tauri 아이콘 기능 안내서에서 다양한 아이콘 형식에 대해 알아보실 수 있습니다.

이제 프론트엔드를 스캐폴드했고 Rust 프로젝트도 초기화했으니 앱을 실행할 준비가 거의 끝났습니다. tauri.conf.json 파일 내용은 아래 내용처럼 만들어질 겁니다:

src-tauri/tauri.conf.json
{
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev",
"devPath": "http://localhost:3000",
"distDir": "../out"
},

이걸로 끝입니다! 이제 터미널에서 다음 명령어를 실행해 앱의 개발 빌드를 시작할 수 있습니다.

npm run tauri dev

응용 프로그램 창 응용 프로그램 창

명령 호출

Tauri는 네이티브 기능과 함께 프론트엔드를 향상시킬 수 있습니다. 명령이라고 불리는 이 기능은, 기본적으로 프론트엔드 JavaScript에서 호출할 수 있는 Rust 함수입니다. 이를 통해 성능이 뛰어난 Rust 코드로 오래 걸리는 작업이나 OS 기능 호출 등을 처리할 수 있습니다.

간단한 예제를 만들어봅시다:

src-tauri/src/main.rs
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}

명령은 일반적인 Rust 함수와 같지만, JavaScript 맥락과 통신하게 해주는 #[tauri::command 속성 매크로가 붙어 있습니다.

마지막으로, Tauri가 적절히 호출을 전달하도록 새로 만든 명령을 알려줘야 합니다. 아래와 같이, invoke_handler() 함수와 generate_handler![] 매크로를 조합해 줍니다.

src-tauri/src/main.rs
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

이제 프론트엔드에서 명령을 호출할 준비가 되었습니다!

새로 만든 명령을 호출하기 위해서 JavaScript 라이브러리 @tauri-apps/api를 사용할 것입니다. 이 라이브러리는 편리한 JavaScript 추상화를 통해 창, 파일시스템 등 핵심 기능으로 가는 진입로를 제공합니다. 좋아하는 JavaScript 패키지 관리자로 설치할 수 있습니다.

npm install @tauri-apps/api

One important thing to note is that all of Tauri's JS APIs require access to browser-only APIs which means they can only be used in Client Components. If you don't need Server Components you can add 'use client' at the very top of the app/page.tsx file, in this guide however, we will create a separate component so that we don't have to convert the whole app.

app/greet.tsx
'use client'

import { useEffect } from 'react'
import { invoke } from '@tauri-apps/api/tauri'

export default function Greet() {
useEffect(() => {
invoke<string>('greet', { name: 'Next.js' })
.then(console.log)
.catch(console.error)
}, [])

// Necessary because we will have to use Greet as a component later.
return <></>
}

Now we will use this component in the default Home component in app/page.tsx. Note that it must be in the actual component tree and can't be a simple function call as long as the parent (in this case the Home component) is a Server Component.

app/page.tsx
// ...
import Greet from './greet'

export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<Greet />
...
</main>
)
}

만약 Rust와 JavaScript 사이의 통신에 대해 더 알아보고 싶으시다면 Tauri 프로세스 간 통신 안내서를 읽어보세요.