Um pacote simples
Criando o @napi-rs/cool
Vamos começar pelo @napi-rs/cli
.
Crie um novo projeto com napi new
:
napi new
? Package name: (The name field in your package.json)
Vamos dar ao pacote um nome maneiro @napi-rs/cool:
É recomendado usar um escopo npm para nomear seu pacote. Isso porque
@napi-rs/cli
irá criar e publicar muitos pacotes por plataforma para você.
Se esses pacotes não estiverem sob um escopo npm, isso pode acionar a
detecção de spam (opens in a new tab) do npm
enquanto você os publica pela primeira vez.
napi new
? Package name: (The name field in your package.json) @napi-rs/cool
? Dir name: (cool)
O próximo passo é escolher o nome do diretório para o seu pacote maneiro, o valor padrão é o sufixo do nome do seu pacote. Vamos apenas pressionar enter e usar o valor padrão.
napi new
? Package name: (The name field in your package.json) @napi-rs/cool
? Dir name: cool
? Choose targets you want to support (Press <space> to select, <a> to toggle all, <i> to invert selection,
and <enter> to proceed)
❯ ◯ aarch64-apple-darwin
◯ aarch64-linux-android
◯ aarch64-unknown-linux-gnu
◯ aarch64-unknown-linux-musl
◯ aarch64-pc-windows-msvc
◯ armv7-unknown-linux-gnueabihf
◉ x86_64-apple-darwin
(Move up and down to reveal more choices)
O próximo passo é escolher em quais plataformas você deseja dar suporte. Eu quero todas elas, então pressione A para escolher todos os alvos e pressione enter.
napi new
? Package name: (The name field in your package.json) @napi-rs/cool
? Dir name: cool
? Choose targets you want to support aarch64-apple-darwin, aarch64-linux-android, aarch64-unknown-linux-gnu
, aarch64-unknown-linux-musl, aarch64-pc-windows-msvc, armv7-unknown-linux-gnueabihf, x86_64-apple-darwin,
x86_64-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, x86_64-unknown-freebsd, i686-p
c-windows-msvc, armv7-linux-androideabi
? Enable github actions? (Y/n)
O próximo passo é escolher se deseja habilitar a configuração do GitHub CI
. Se o seu projeto estiver hospedado no GitHub
, então você precisa habilitá-lo. Vamos digitar Y e pressionar enter aqui:
napi new
? Package name: (The name field in your package.json) @napi-rs/cool
? Dir name: cool
? Choose targets you want to support aarch64-apple-darwin, aarch64-linux-android, aarch64-unknown-linux-gnu
, aarch64-unknown-linux-musl, aarch64-pc-windows-msvc, armv7-unknown-linux-gnueabihf, x86_64-apple-darwin,
x86_64-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, x86_64-unknown-freebsd, i686-p
c-windows-msvc, armv7-linux-androideabi
? Enable github actions? Yes
Writing Cargo.toml
Writing .npmignore
Writing build.rs
Writing package.json
Writing src/lib.rs
Writing .github/workflows/CI.yml
Writing .cargo/config.toml
Writing rustfmt.toml
E agora, o @napi-rs/cli
criou um novo pacote chamado @napi-rs/cool
dentro do diretório cool
.
Vamos entrar nele e fazer algumas preparações:
cd cool
yarn install
Estou usando yarn
para instalar as dependências, você pode substituí-lo pelo seu gerenciador de pacote favorito.
Agora, a estrutura do diretório está assim:
tree -a
.
├── .cargo
│ └── config.toml
├── .github
│ └── workflows
│ └── CI.yml
├── .npmignore
├── Cargo.toml
├── build.rs
├── npm
├── package.json
├── rustfmt.toml
└── src
└── lib.rs
Seus códigos nativos estão em src/lib.rs
. O arquivo .cargo/config.toml
é usado no GitHub CI
para compilação cruzada. Em geral, este arquivo não afeta seu desenvolvimento em sua máquina local.
O arquivo .github/workflows/CI.yml
é o arquivo de configuração para GitHub Actions
(opens in a new tab).
O arquivo build.rs
é necessário para construir um complemento(Addon) nativo para o Node.js
. Não o exclua ou mova para outro lugar.
Depois que a instalação do yarn
terminar, você pode executar o comando build
para construir seu primeiro pacote nativo:
yarn build
yarn run v1.22.17
$ napi build --platform --release
Updating crates.io index
Downloaded proc-macro2 v1.0.34
Downloaded once_cell v1.9.0
Downloaded napi v2.0.0-beta.7
Downloaded 3 crates (129.4 KB) in 2.35s
Compiling proc-macro2 v1.0.34
Compiling unicode-xid v0.2.2
Compiling memchr v2.4.1
Compiling syn v1.0.82
Compiling regex-syntax v0.6.25
Compiling convert_case v0.4.0
Compiling once_cell v1.9.0
Compiling napi-build v1.2.0
Compiling napi-sys v2.1.0
Compiling napi-rs_cool v0.0.0 (/cool)
Compiling quote v1.0.10
Compiling aho-corasick v0.7.18
Compiling regex v1.5.4
Compiling napi-derive-backend v1.0.17
Compiling ctor v0.1.21
Compiling napi-derive v2.0.0-beta.5
Compiling napi v2.0.0-beta.7
Finished release [optimized] target(s) in 37.11s
✨ Done in 37.80s.
E agora a estrutura de pastas está assim:
tree -a -I target
.
├── .cargo
│ └── config.toml
├── .github
│ └── workflows
│ └── CI.yml
├── .npmignore
├── Cargo.toml
├── build.rs
├── cool.darwin-x64.node
├── index.d.ts
├── index.js
├── node_modules
├── npm
├── package.json
├── rustfmt.toml
└── src
└── lib.rs
Aqui estão mais três arquivos que o comando yarn build
gerou para você.
cool.darwin-x64.node
é o arquivo binário do complemento(Addon) do Node.js, o index.js
é o arquivo de ligação JavaScript gerado que ajuda a exportar todas as coisas no complemento para o chamador do pacote. E o index.d.ts
é o arquivo de definição TypeScript gerado.
O comando new
gerou uma simples função sum
para você no src/lib.rs
:
#![deny(clippy::all)]
#[macro_use]
extern crate napi_derive;
#[napi]
fn sum(a: i32, b: i32) -> i32 {
a + b
}
E você pode inspecionar o arquivo index.d.ts
e ver a função sum
que foi gerada para você:
/* eslint-disable */
export class ExternalObject<T> {
readonly '': {
readonly '': unique symbol
[K: symbol]: T
}
}
export function sum(a: number, b: number): number
Vamos criar um arquivo test.mjs
para testar a função sum
gerada:
import { sum } from './index.js'
console.log('From native', sum(40, 2))
Execute isso!
node test.mjs
From native 42
Parabéns! Você criou com sucesso um complemento nativo para o Node.js
!
Publique-o!
Infelizmente, você não pode publicar o @napi-rs/cool
, porque você não tem permissão para publicar pacotes no escopo npm @napi-rs
.
No entanto, você pode criar seu próprio escopo npm
: https://docs.npmjs.com/creating-and-publishing-scoped-public-packages (opens in a new tab).
Assim que você tiver criado seu próprio escopo npm, você pode usar o comando napi rename
para renomear o projeto recém criado.
napi rename
? name: name field in package.json
Vamos supor que você acabou de criar um escopo npm chamado jarvis
, você pode digitar @jarvis/cool
aqui:
napi rename
? name: name field in package.json @jarvis/cool
? napi name: (cool)
Você não precisa alterar o campo napi name
no package.json
porque o sufixo do pacote não é alterado. Apenas pressione Enter para manter o nome cool
.
napi rename
? name: name field in package.json @jarvis/cool
? napi name: cool
? repository: Leave empty to skip
E você precisa de um repositório do GitHub
se quiser publicar um pacote NAPI-RS, porque você precisa das GitHub Actions
para realizar os trabalhos de compilação para você. Basta digitar a URL do seu repositório do GitHub aqui.
napi rename
? name: name field in package.json @jarvis/cool
? napi name: cool
? repository: Leave empty to skip
? description: Leave empty to skip
E o campo description
no arquivo package.json
. Deixe-o vazio para pular.
Agora que o nome do seu pacote foi renomeado para @jarvis/cool
, você finalmente pode publicá-lo.
Então inicie a configuração do git
e faça o push para o GitHub.
git init
git remote add origin git@github.com/yourname/cool.git
git add .
git commit -m "Init"
git push
Para publicar pacotes no GitHub Actions
, você precisa configurar a variável de ambiente NPM_TOKEN
no seu repositório do GitHub
.
No projeto vá em Settings -> Secrets, e adicione seu NPM_TOKEN nele.
Se tudo funcionar corretamente, você verá a seguinte matriz de CI:
Esta é apenas uma matriz de CI de teste, vamos finalmente publicar este pacote:
npm version patch
git push --follow-tags
E a matriz CI
irá construir e publicar o seu pacote @jarvis/cool
.