Esta página foi traduzida automaticamente e pode conter erros. Ler o original em inglês

Documentação

Empacotamento

nsh package transforma um app em algo que você pode instalar: um .app para o simulador do iOS, um .ipa assinado para dispositivos iOS, um .apk assinado para Android, um .app com assinatura ad hoc para macOS, um diretório e .tar.gz para Linux, um diretório e .zip para Windows, ou um site estático para a web. Não precisa de projeto Xcode nem de Gradle.

  • Um app Rust (nsh.json nomeia o seu "root") é empacotado a partir do seu diretório. nsh compila o runner do alvo em modo release, com o seu crate compilado junto e a raiz montada, sem QuickJS. São necessários: Cargo, o alvo Rust da plataforma (rustup target add …) e, para Android, o NDK.
  • Um app TSX nomeia a sua entrada. Seu build de release (minificado, compilado para bytecode do QuickJS, exatamente como nsh build --release o compila) vai junto com o runtime pré-compilado que acompanha o NSH, portanto não precisa de toolchain Rust. Um app com um crate próprio ("rust" sem "root") recebe runners compilados com o seu crate.
# A Rust app, from its directory
nsh package --target ios-simulator --run     # build, install and launch in the simulator
nsh package --target android --run           # build, install and launch on a device or emulator
nsh package --target macos --run             # build and launch on this Mac
nsh package --target linux --run             # build and launch on this machine
nsh package --target windows --run           # build and launch on this machine
nsh package --target web --run               # build, serve on this machine and open in the browser
nsh package --target ios --sign "Apple Development: Jane Doe (ABCDE12345)" --profile Dev.mobileprovision

# A TSX app: the same with its entry
nsh package App.tsx --target ios-simulator --run

A saída vai para .nsh/out/, a menos que você passe --out. As seções abaixo mostram o comando de cada alvo para um app Rust; um app TSX acrescenta a sua entrada (nsh package App.tsx --target …).

#Metadados do app: nsh.json

nsh package lê nsh.json no diretório do app (ao lado do arquivo de entrada, no caso de um app TSX). nsh init cria um:

{
  "name": "Gallery",
  "id": "com.example.gallery",
  "version": "1.0.0",
  "build": 1,
  "icon": "icon.png"
}
Chave Tipo Padrão Usado para
name string o nome do diretório da entrada O nome exibido sob o ícone (CFBundleDisplayName, android:label no Android) e o nome do arquivo de saída.
id string obrigatório O identificador do bundle / nome do pacote Android, no formato DNS reverso sob um domínio que você possui. Também nomeia o local onde o app guarda seu armazenamento, de modo que cada app tenha o seu. nsh package e nsh publish avisam sobre o placeholder com.example..
version string "1.0.0" A versão visível ao usuário (CFBundleShortVersionString, versionName).
build número 1 O número do build (CFBundleVersion, versionCode). Aumente-o a cada release que você enviar.
icon string nenhum Um PNG quadrado, idealmente de 1024×1024, relativo a nsh.json.

nsh.json também contém rust e root (os crates do app e seu componente raiz, Desenvolvendo com Rust), theme e appearance, tailwind (veja Tailwind) e capabilities (veja Sandbox e capabilities); Estrutura do projeto lista todas as chaves. Chaves desconhecidas causam erro.

Toda chave acima pode ser sobrescrita na linha de comando, o que é útil em CI:

nsh package --target android --app-version 1.4.0 --build 42

#Opções

Flag Descrição
--target <ios | ios-simulator | android | macos | linux | windows | web> Para o que compilar (obrigatório).
-o, --out <dir> Diretório de saída. Padrão: .nsh/out.
--name <name> Nome exibido.
--id <id> Identificador do bundle, como com.example.app.
--app-version <version> Versão, como 1.2.0.
--build <n> Número do build.
--icon <png> Ícone do app: um PNG quadrado, idealmente de 1024×1024.
--sign <identity> iOS: a identidade de assinatura de código para dispositivos.
--profile <file> iOS: o provisioning profile para dispositivos (.mobileprovision).
--keystore <file> Android: um keystore de release (padrão: a chave de debug).
--key-alias <alias> Android: o alias da chave no keystore.
--keystore-password <password> Android: a senha do keystore; também lida de NSH_KEYSTORE_PASSWORD.
--abi <abi> Android: as ABIs do APK, repetidas ou separadas por vírgulas (padrão: arm64-v8a e armeabi-v7a).
--run Instala e executa em seguida: no simulador do iOS, ou no dispositivo ou emulador Android que adb enxerga; apps macOS, Linux e Windows são executados nesta máquina; um site web é servido nesta máquina e aberto no navegador. Não se aplica a --target ios.

#Simulador do iOS

nsh package --target ios-simulator --run

Gera .nsh/out/<Name>.app, com assinatura ad hoc (o simulador exige uma assinatura, mas não uma identidade). Com --run, ele inicia um simulador se nenhum estiver em execução, instala o app e o executa. Requer o Xcode.

#Dispositivos iOS

nsh package --target ios \
  --sign "Apple Distribution: Example Inc (ABCDE12345)" \
  --profile AppStore.mobileprovision

Gera .nsh/out/<Name>.ipa, pronto para o TestFlight, para as ferramentas de envio à App Store ou para instalação direta (dependendo do profile). O que acontece:

  • O provisioning profile é copiado para dentro do app como embedded.mobileprovision.
  • Os entitlements vêm do profile. O NSH verifica se o application identifier do profile cobre o id do app (profiles curinga, como TEAMID.* ou TEAMID.com.example.*, funcionam) e, caso contrário, para com um erro.
  • O app é assinado com codesign usando a identidade e depois compactado em um .ipa (Payload/<Name>.app).

Encontre suas identidades com:

security find-identity -v -p codesigning

Sem --sign e --profile, o NSH gera um .nsh/out/<Name>.app não assinado e avisa você; ele não pode ser instalado em um dispositivo dessa forma.

O app oferece suporte a iPhone e iPad, em retrato e paisagem (retrato de cabeça para baixo apenas no iPad), e exige iOS 15.0 ou mais recente.

#Android

nsh package --target android --run

Gera .nsh/out/<Name>.apk. O APK é montado diretamente com as ferramentas de build do SDK (aapt2, zipalign, apksigner), sem Gradle. Requisitos:

  • O Android SDK, localizado por meio de ANDROID_HOME (ou ANDROID_SDK_ROOT, ou ~/Library/Android/sdk), com build tools e o pacote platforms;android-35. O NSH informa o comando sdkmanager quando algum está faltando.
  • Um JDK, para criar o keystore de debug na primeira vez.
  • Para um app Rust, o Android NDK (sdkmanager "ndk;<version>" ou ANDROID_NDK_HOME), que compila o libnsh.so dele.

O app tem como alvo a API 35 e exige a API 28 (Android 9) ou mais recente. Ele contém código nativo para as ABIs de celulares, arm64-v8a e armeabi-v7a; com --run, também a do dispositivo, como o x86_64 de um emulador. --abi escolhe as ABIs por conta própria, por exemplo --abi arm64-v8a apenas para celulares de 64 bits, o menor APK:

nsh package --target android --abi arm64-v8a

#Assinatura para release

Sem --keystore, o APK é assinado com a chave de debug padrão (~/.android/debug.keystore, criada se não existir), e o NSH avisa que ele não serve para releases em lojas. Para um release, crie um keystore uma única vez e passe-o:

keytool -genkeypair -v -keystore release.jks -alias upload -keyalg RSA -keysize 2048 -validity 10000

NSH_KEYSTORE_PASSWORD=… nsh package --target android \
  --keystore release.jks --key-alias upload

Prefira a variável de ambiente a --keystore-password, para que a senha não fique no histórico do seu shell.

#macOS

nsh package --target macos --run

Gera .nsh/out/<Name>.app: o executável em Contents/MacOS/, e nsh/assets/…, nsh/app.json (o título da janela e a aparência do app) e o nsh/bundle.nshc de um app TSX em Contents/Resources/. O app é assinado ad hoc e exige macOS 14 ou posterior; para distribuí-lo, assine-o com um Developer ID e faça a notarização. Veja macOS.

#Linux

nsh package --target linux --run

Gera .nsh/out/<Name>/ (o executável <Name>, nsh/assets/…, nsh/app.json com o título da janela e o id do aplicativo, o nsh/bundle.nshc de um app TSX, <id>.desktop e o ícone <id>.png) e o mesmo que .nsh/out/<Name>.tar.gz. Empacote no Linux: o runner é compilado para a máquina em que é gerado. GTK 4 (4.14 ou posterior), Pango e WebKitGTK 6.0 (para web views) devem estar instalados onde o app for executado. Instalação e entrada de desktop: Linux.

#Windows

nsh package --target windows --run

Gera .nsh\out\<Name>\ (o executável <Name>.exe com o ícone do app, nsh\assets\…, nsh\app.json com o título da janela, o id do app, a versão e a aparência, e o nsh\bundle.nshc de um app TSX) e o mesmo que .nsh\out\<Name>.zip. Um app TSX não precisa de ferramentas; o runner de um app Rust é compilado com o Visual Studio Build Tools. Empacote no Windows: o runner é compilado para a máquina em que é gerado, e somente o Windows consegue incorporar o ícone. O app é executado de onde quer que seu diretório seja copiado; nada é instalado. Veja Windows.

#Web

nsh package --target web --run

Gera .nsh/out/<Name>/, um site estático: index.html, manifest.webmanifest, o script da página (nsh.<digest>.js) e nsh.<digest>.wasm (o engine e o crate de um app Rust; para um app TSX, o runtime, ao lado do módulo ES do app app.<digest>.js), seus assets e ícones, cada um nomeado a partir do seu conteúdo para que os hosts possam fazer cache deles indefinidamente. Publique o diretório em qualquer servidor web ou CDN; --run o serve em http://127.0.0.1:4173/ para você abrir. Cabeçalhos de cache e incorporação: Web.

#Ícones

Forneça um PNG quadrado, idealmente de 1024×1024, em nsh.json ("icon": "icon.png") ou com --icon:

  • iOS: compilado pelo actool do Xcode no catálogo de assets do app (Assets.car), que gera todos os tamanhos de que o iOS precisa.
  • Android: redimensionado para 192×192 e usado como ícone do launcher (mipmap-xxxhdpi).
  • macOS: convertido por sips em AppIcon.icns.
  • Linux: copiado como <id>.png, que o arquivo .desktop indica como seu Icon.
  • Windows: redimensionado para de 16 a 64 pixels e para 256 pixels e incorporado ao executável como seu ícone, que a janela, o Explorer e a barra de tarefas exibem.
  • Web: redimensionado para 32 pixels (o favicon), 180 (apple-touch-icon), 192 e 512 (o web app manifest).

Sem um ícone, o sistema exibe o seu padrão.

#O que há dentro

O pacote de um app Rust é o seu runner, compilado com o seu crate e a raiz montada, mais os assets que seus crates registram (assets!()). O pacote de um app TSX contém o seu bytecode, o seu capabilities.json (quando declara capabilities) e os assets que ele importa, ao lado do runtime pré-compilado:

Alvo Runtime Um app TSX
iOS o executável nsh-ios-app <Name>.app/nsh/bundle.nshc, nsh/assets/…
Android classes.dex, lib/<abi>/libnsh.so (sem símbolos, armazenadas sem compressão, alinhadas a 16 KB) assets/nsh/bundle.nshc, assets/nsh/assets/…
macOS o executável nsh-macos-app, renomeado para <Name> <Name>.app/Contents/Resources/nsh/bundle.nshc, nsh/assets/…
Linux o executável nsh-linux-app, renomeado para <Name> <Name>/nsh/bundle.nshc, nsh/assets/…
Windows o executável nsh-windows-app.exe, renomeado para <Name>.exe <Name>\nsh\bundle.nshc, nsh\assets\…
Web nsh.<digest>.wasm, nsh.<digest>.js <Name>/app.<digest>.js, assets/…, index.html

Um app empacotado não registra componentes nativos; para isso, incorpore o NSH ao seu próprio app.

#Localizando o runtime

Um app Rust compila seus próprios runners. Para apps TSX, nsh package procura o runtime pré-compilado ao lado da CLI (bin/../runtime na distribuição). Em um checkout do NSH, ele usa target/<triple>/<profile> e target/android/<profile>, com o perfil da própria CLI (uma CLI de debug usa runtimes de debug): compile-os com cargo build -p nsh-ios-app --target aarch64-apple-ios-sim (ou aarch64-apple-ios para dispositivos) e cargo xtask android (acrescente --release para uma CLI de release); nsh-macos-app (no macOS), nsh-linux-app (no Linux) e nsh-windows-app (no Windows) são compilados para esta máquina em target/<profile> (cargo build -p nsh-macos-app, cargo build -p nsh-linux-app, cargo build -p nsh-windows-app); o runtime web é compilado com o perfil web, seja qual for o da CLI, em target/wasm32-unknown-unknown/web/. A variável de ambiente NSH_RUNTIME aponta a CLI para outro diretório organizado como o runtime/ da distribuição (ios/iphoneos, ios/iphonesimulator, android/release, macos, linux, windows, gpui, web, …).

#Veja também