Como implantar um aplicativo Bun?
Bun é um tempo de execução de JavaScript projetado para ser rápido, leve e fácil de usar. Ele é escrito em Zig e alimentado pelo JavaScriptCore, o mecanismo JavaScript que alimenta o Safari.
O Bun tem um gerenciador de pacotes, um executor de testes e um empacotador compatíveis com o Node.js incorporados. Ele também fornece um conjunto mínimo de APIs altamente otimizadas para executar tarefas comuns, como iniciar um servidor HTTP e gravar arquivos.
Neste artigo, você criará uma API da Web simples com o Bun e a implantará no Back4app usando os contêineres do Back4app. Continue lendo para saber mais sobre como hospedar um aplicativo Bun.
Contents
Vantagens do Bun
Desde o anúncio inicial do Bun, mesmo antes do lançamento da V1 em setembro de 2023, ele se tornou cada vez mais popular na comunidade JavaScript. Aqui estão alguns dos motivos.
Velocidade
O Bun é escrito em Zig, uma linguagem de programação de baixo nível projetada para a programação de sistemas, com foco no desempenho, na segurança e na legibilidade. Sua intenção é ser uma alternativa moderna ao C e ao C++.
Além disso, ao contrário do Node.js e do Deno, que usam o mecanismo JavaScript V8 do Chrome, ele usa o mecanismo JavaScriptCore, que alimenta o Safari.
Além do Zig e do JavaScript Core, o Bun também usa várias outras técnicas, como um alocador de memória personalizado que é otimizado para JavaScript e um compilador just-in-time (JIT) para otimizar o código à medida que ele é executado.
Em geral, a combinação do Zig, do JavaScript Core e de outras otimizações torna o Bun um tempo de execução de JavaScript muito rápido em comparação com outros tempos de execução.
Compatibilidade com o Node.js
O Bun foi projetado para ser um substituto imediato do Node.js e, como tal, é compatível com todas as APIs do Node.js.
Ele também tem todos os módulos internos do Node.js, como crypto, fs, path etc. Você pode verificar os módulos Node.js disponíveis e não disponíveis na documentação do Bun.js.
Além disso, o Bun é um gerenciador de pacotes compatível com o npm. Isso significa que você pode usar o Bun para instalar e gerenciar pacotes Node.js usando o Bun.
Suporte a TypeScript fora da caixa
O Bun tem suporte nativo e contínuo para TypeScript, o que o torna uma excelente opção se você preferir ou precisar do TypeScript em seus projetos.
O TypeScript, uma versão estendida e estaticamente tipada do JavaScript, apresenta recursos avançados de linguagem e tipagem estática para aprimorar o desenvolvimento do JavaScript.
Com o Bun, não há necessidade de configuração adicional, nem de procedimentos extras de instalação ou compilação para habilitar a funcionalidade do TypeScript.
Limitações do Bun
Apesar de suas vantagens, o Bun tem certas limitações que você precisa considerar antes de usá-lo em seu projeto.
Recursos limitados
O Bun ainda é relativamente novo, o que significa que a comunidade é pequena no momento. Não há muitos recursos que cubram o desenvolvimento específico do Bun-js, o que significa que você pode ter dificuldade em descobrir como usar o tempo de execução.
No entanto, a documentação do Bun é abrangente e serve como um ponto de referência valioso. Se você encontrar dificuldades, há também a opção de buscar assistência por meio do canal Discord.
Suporte para Windows
Atualmente, a Bun oferece suporte limitado ao sistema operacional Windows. No momento da redação deste documento, somente o tempo de execução é compatível com o Windows.
O executor de testes, o gerenciador de pacotes e o empacotador ainda estão em desenvolvimento e, portanto, não funcionam no Windows. Continue lendo para saber mais sobre como hospedar um aplicativo Bun.
Criação de um aplicativo Bun
Antes de poder usar o Bun, você precisa instalá-lo.
Para instalar o Bun no macOS, WSL e Linux, execute o comando abaixo:
curl -fsSL https://bun.sh/install | bash
Configuração de seu ambiente de desenvolvimento
Para criar um novo projeto Bun, execute o comando abaixo:
bun init
A execução do comando acima inicializa um projeto Bun vazio em seu diretório de projetos.
No tutorial, você criará uma API simples com o Elysia, uma das estruturas de servidor HTTP mais rápidas da Bun (de acordo com seus benchmarks).
Execute o comando abaixo para instalar o Elysia e outras dependências necessárias para este projeto:
bun add elysia knex dotenv pg
As outras dependências instaladas no comando incluem:
- Knex, um construtor de consultas. Você usará essa dependência para simplificar a interação com seu banco de dados.
- dotenv, esse pacote o ajuda a gerenciar variáveis ambientais em seu projeto.
- pg (driver de banco de dados Postgres) para interagir com seu banco de dados Postgres.
Em seguida, inicialize o knex em seu projeto executando:
knex init
O comando acima cria um arquivo knexfile.js
. Esse arquivo contém opções de configuração para seu banco de dados.
Substitua o código no arquivo pelo bloco de código abaixo:
require("dotenv").config();
export const development = {
client: "pg",
connection: process.env.DATABASE_URL,
migrations: {
directory: "./db/migrations",
}
};
Em seguida, crie um arquivo db.js
no diretório raiz do seu projeto e adicione o bloco de código abaixo a ele.
const knex = require("knex");
const knexFile = require("./knexfile.js");
const environment = process.env.NODE_ENV || "development";
export default knex(knexFile[environment]);
Em seguida, crie um arquivo .env
e adicione os detalhes da conexão do banco de dados ou o URI ao arquivo.
Por exemplo:
DATABASE_URL = <YOUR_DATABASE_URI>
Substitua “YOUR_DATABASE_URI” pelo URL do seu banco de dados.
Observação: Certifique-se de adicionar o arquivo .env
ao arquivo .gitignore
para garantir que não envie informações privadas para o controle de versão.
Criação do modelo de banco de dados
Para criar seu modelo de banco de dados usando o Knex, você criará um arquivo de migração e escreverá um comando SQL de criação usando o Knex.
Execute o comando abaixo para criar sua primeira migração:
knex migrate:make blog
Em seguida, substitua o código no arquivo de migração gerado pelo bloco de código abaixo:
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
export function up (knex) {
return knex.schema.createTable("blog", (table) => {
table.increments("id").primary();
table.string("title").notNullable();
table.string("content").notNullable();
table.string("author").notNullable();
table.timestamp("created_at").defaultTo(knex.fn.now());
});
}
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
export function down (knex) {
return knex.schema.dropTable("blog");
}
Por fim, execute o bloco de código abaixo para executar seu arquivo de migração:
knex migrate:latest
O comando acima executa o arquivo de migração que você gerou anteriormente, criando assim uma tabela Blog em seu banco de dados.
Criação de um servidor Bun-Elysia
Nesta etapa, você criará um servidor de API simples.
Abra seu arquivo index.ts
e adicione o bloco de código abaixo:
//index.ts
const { Elysia } = require("elysia");
let db = require("./db");
db = db.default;
const app = new Elysia();
No bloco de código abaixo, você importou o Elysia e criou uma instância da estrutura do Elysia (app).
Criação de manipuladores de rota
Em seguida, você criará manipuladores de rota para seu aplicativo. O manipulador que você criar será para as seguintes rotas:
- POST /posts/create-new-post
- GET /posts
- GET /posts/:id
- PATCH /posts/:id/update-post
- DELETE /posts/:id/delete-post
Adicione o bloco de código abaixo ao seu arquivo index.ts
para criar o manipulador para “/posts/create-new-post”:
app.post("/posts/create-new-post", async (context) => {
try {
//Extract the title, content and author from the request body
const { title, content, author } = context.body;
//Insert the post into the database
const post = await db("blog").insert({
title,
content,
author,
});
//Send response to the client
return new Response(JSON.stringify(post));
} catch (error: any) {
//Send error to the client
return new Response(error.message, { status: 500 });
}
});
O bloco de código acima é um manipulador de rota para seu endpoint que adiciona novos posts ao seu banco de dados.
Adicione o bloco de código abaixo ao seu arquivo index.ts
para criar o manipulador que busca todos os seus posts “/posts”:
app.get("/posts", async (context) => {
try {
//Get all posts from the database
const posts = await db.select("*").from("blog");
//Send response to the client
return new Response(JSON.stringify(posts));
} catch (error: any) {
//Send error to the client
return new Response(error.message, { status: 500 });
}
});
Adicione o bloco de código abaixo ao seu arquivo index.ts
para criar o manipulador que busca uma única publicação por id “/posts/:id”:
app.get("/posts/:id", async (context) => {
//Extract the id from the request params
const { id } = context.params;
//Get the post from the database
const post = await db("blog").where({ id });
//If the post is not found, send a 404 response
if (post.length === 0) {
return new Response("Post not found", { status: 404 });
}
//Send response to the client
return new Response(JSON.stringify(post));
});
Adicione o bloco de código abaixo ao seu arquivo index.ts
para criar o manipulador que atualiza um único post com os dados na carga útil por id “/posts/:id/update-post”:
app.patch("/posts/:id/update-post", async (context) => {
//Extract the id from the request params
const { id } = context.params;
//Extract the title and content from the request body
const { title, content } = context.body;
//Update the post in the database
const post = await db("blog").where({ id }).update(
{
title,
content,
},
["id", "title", "content"]
);
//Send response to the client
return new Response(JSON.stringify(post));
});
Adicione o bloco de código abaixo ao seu arquivo index.ts
para criar o manipulador que exclui um único post por id “/posts/:id/delete-post”:
app.delete("/posts/:id/delete-post", async (context) => {
//Extract the id from the request params
const { id } = context.params;
//Delete the post from the database
const post = await db("blog").where({ id }).del();
//Send response to the client
return new Response(JSON.stringify(post));
});
Por fim, adicione o bloco de código abaixo para definir o PORT para seu aplicativo.
app.listen(3000, () => {
console.log("Server running on port 3000");
});
Execute o comando abaixo para iniciar seu aplicativo:
bun --watch index.ts
Implantação de um aplicativo Bun em contêineres do Back4app
A implantação do aplicativo Bun requer algumas etapas.
Etapa 1: Escreva um Dockerfile
Para criar um Dockerfile, execute o comando abaixo em seu terminal.
touch Dockerfile
A execução do comando acima cria um Dockerfile no diretório raiz do seu projeto.
Em seguida, abra seu Dockerfile e adicione o bloco de código abaixo a ele:
FROM oven/bun
WORKDIR /app
COPY package.json .
COPY bun.lockb .
RUN bun install
COPY . .
EXPOSE 3000
CMD ["bun", "index.ts"]
No Dockerfile acima, a primeira linha, FROM oven/bun
, especifica a imagem base a ser usada. Essa imagem é uma imagem pré-criada que contém o tempo de execução do Bun e todas as suas dependências.
A próxima linha, WORKDIR /app
, define o diretório de trabalho para a imagem. Esse é o diretório em que o código do aplicativo será copiado e executado.
As duas linhas a seguir, COPY package.json .
e COPY bun.lockb .
, copiam os arquivos package.json
e bun.lockb
do diretório atual para a imagem. Esses arquivos são necessários para que o tempo de execução do Bun instale as dependências do aplicativo.
A próxima linha, RUN bun install
, instala as dependências do aplicativo usando o tempo de execução do Bun.
A próxima linha, COPY . .
, copia todo o diretório atual para a imagem. Isso inclui o código do aplicativo e quaisquer outros arquivos necessários.
A próxima linha, EXPOSE 3000
, expõe a porta 3000
do contêiner para o mundo externo. Essa é a porta em que o aplicativo escutará.
A última linha, CMD ["bun", "index.ts"]
, especifica o comando que será executado quando o contêiner for iniciado. Esse comando iniciará o tempo de execução do Bun e executará o arquivo index.ts
do aplicativo.
Por fim, envie seu código para o GitHub.
Etapa 2: Criar um aplicativo Back4app
A próxima etapa para hospedar um aplicativo Bun é criar um novo aplicativo no Back4App. Primeiro, faça login em sua conta do Back4App ou inscreva-se se ainda não tiver uma. Quando estiver conectado, você se encontrará no painel do Back4App.
Clique no botão “NEW APP” (novo aplicativo) e selecione a opção“Containers as a Service“(contêineres como serviço).
Como próxima etapa para hospedar um aplicativo Bun, conecte sua conta do GitHub à sua conta do Back4app. Conectar sua conta permite que a Back4app acesse os repositórios em sua conta.
Você pode decidir conceder acesso a todos os repositórios da sua conta ou a repositórios específicos. Escolha o aplicativo que deseja implantar, neste caso, o aplicativo que você criou neste tutorial, e clique em Select (Selecionar).
Depois de clicar no botão Select, você será direcionado para uma página de configuração, na qual preencherá os detalhes do seu aplicativo, como o PORT e as variáveis de ambiente.
Depois de preencher os detalhes, clique no botão Create App. Isso inicia o processo de implementação. Sua implantação deve ser bem-sucedida e você receberá uma URL para acessar seu aplicativo, mas, se ela falhar, você poderá aproveitar a integração do Back4app ChatGPT para resolver os problemas que tiver com seu Dockerfile.
Como alternativa, você pode solucionar manualmente os erros de implantação usando os registros detalhados e o guia de solução de problemas do Back4app.
Conclusão
Neste artigo, você explorou o tempo de execução do Bun JavaScript, suas vantagens e limitações aparentes. Você também explorou como criar um aplicativo Bun usando Elysia, Knex e PostgreSQL.
Por fim, você explorou os contêineres do Back4app e como implementar seus aplicativos Bun na plataforma.
Ao usar o Bun, é importante observar que ele ainda está em seus estágios iniciais e pode introduzir algumas mudanças importantes no futuro.
PERGUNTAS FREQUENTES
O que é Bun?
Bun é um runtime JavaScript que foi projetado para ser rápido e eficiente. Ele é construído sobre o mecanismo JavaScriptCore e usa uma série de otimizações (vantagens de usar a linguagem de baixo nível, Zig) para torná-lo mais rápido.
Como implantar um aplicativo Bun?
– Crie um aplicativo Bun.
– Escreva um Dockerfile.
– Envie seu aplicativo Bun para o GitHub.
– Abra uma conta Back4app ou faça login na sua conta existente.
– Crie um novo aplicativo “CaaS” no Back4app.
– Conceda ao Back4app acesso ao aplicativo que você deseja implementar.
– Selecione o aplicativo e preencha os detalhes da configuração.
– Clique em Implementar.