Comment déployer une application Bun ?

How to Deploy an Bun Application_
How to Deploy an Bun Application_

Bun est un moteur d’exécution JavaScript conçu pour être rapide, léger et facile à utiliser. Il est écrit en Zig et fonctionne avec JavaScriptCore, le moteur JavaScript de Safari.

Bun dispose d’un gestionnaire de paquets, d’un exécuteur de tests et d’un bundler compatibles avec Node.js. Il fournit également un ensemble minimal d’API hautement optimisées pour effectuer des tâches courantes, telles que le démarrage d’un serveur HTTP et l’écriture de fichiers.

Dans cet article, vous allez construire une API web simple avec Bun et la déployer sur Back4app en utilisant les conteneurs Back4app. Continuez à lire pour en savoir plus sur l’hébergement d’une application Bun.

Avantages de la Bun

Depuis l’annonce initiale de Bun, avant même la sortie de la V1 en septembre 2023, Bun est devenu de plus en plus populaire dans la communauté JavaScript. En voici quelques raisons.

Vitesse

Bun est écrit en Zig, un langage de programmation de bas niveau conçu pour la programmation de systèmes, axé sur la performance, la sécurité et la lisibilité. Il se veut une alternative moderne aux langages C et C++.

En outre, contrairement à Node.js et Deno, qui utilisent le moteur JavaScript V8 de Chrome, il utilise le moteur JavaScriptCore, qui équipe Safari.

Outre Zig et JavaScript Core, Bun utilise également un certain nombre d’autres techniques, telles qu’un allocateur de mémoire personnalisé optimisé pour JavaScript et un compilateur juste à temps (JIT) pour optimiser le code au fur et à mesure de son exécution.

Dans l’ensemble, la combinaison de Zig, de JavaScript Core et d’autres optimisations fait de Bun un moteur d’exécution JavaScript très rapide par rapport à d’autres moteurs d’exécution.

Compatibilité Node.js

Bun est conçu pour remplacer Node.js et, à ce titre, il est compatible avec toutes les API de Node.js.

Il dispose également de tous les modules Node.js intégrés, tels que crypto, fs, path, etc. Vous pouvez vérifier les modules Node.js disponibles et non disponibles dans la documentation de Bun.js.

De plus, Bun est un gestionnaire de paquets compatible avec npm. Cela signifie que vous pouvez utiliser Bun pour installer et gérer des paquets Node.js en utilisant Bun.

Prise en charge de TypeScript en dehors de la boîte

Bun prend en charge TypeScript de manière native et transparente, ce qui en fait un excellent choix si vous préférez ou avez besoin de TypeScript dans vos projets.

TypeScript, une version étendue et statiquement typée de JavaScript, présente des caractéristiques de langage avancées et un typage statique pour améliorer le développement JavaScript.

Avec Bun, il n’y a pas besoin de configuration supplémentaire, ni de procédures d’installation ou de construction supplémentaires pour activer les fonctionnalités TypeScript.

Limites de Bun

Malgré ses avantages, Bun présente certaines limites que vous devez prendre en compte avant de l’utiliser dans votre projet.

Ressources limitées

Bun est encore relativement nouveau, ce qui signifie que la communauté est actuellement petite. Il n’y a pas beaucoup de ressources couvrant le développement spécifique à Bun-js, ce qui signifie que vous pourriez avoir du mal à comprendre comment utiliser le runtime.

Cependant, la documentation de Bun est complète et constitue un point de référence précieux. Si vous rencontrez des difficultés, vous pouvez également demander de l’aide via leur canal Discord.

Support pour Windows

Bun offre actuellement un support limité pour le système d’exploitation Windows. Au moment de la rédaction du présent document, seul le moteur d’exécution est pris en charge sous Windows.

Le gestionnaire de tests, le gestionnaire de paquets et le bundler sont encore en cours de développement et, en tant que tels, ne fonctionnent pas sous Windows. Continuez à lire pour en savoir plus sur l’hébergement d’une application Bun.

Création d’une application Bun

Avant de pouvoir utiliser Bun, vous devez l’installer.

Pour installer Bun sur macOS, WSL et Linux, exécutez la commande ci-dessous :

curl -fsSL https://bun.sh/install | bash

Mise en place de l’environnement de développement

Pour créer un nouveau projet Bun, exécutez la commande ci-dessous :

bun init

L’exécution de la commande ci-dessus initialise un projet Bun vide dans votre répertoire de projets.

Pour ce tutoriel, vous allez construire une API simple avec Elysia, l’un des frameworks de serveur HTTP Bun les plus rapides (selon leurs benchmarks).

Exécutez la commande ci-dessous pour installer Elysia et les autres dépendances nécessaires à ce projet :

bun add elysia knex dotenv pg

Les autres dépendances installées dans la commande incluent :

  • Knex, un constructeur de requêtes. Vous utiliserez cette dépendance pour simplifier l’interaction avec votre base de données.
  • dotenv, ce paquetage vous aide à gérer les variables environnementales dans votre projet.
  • pg (pilote de base de données Postgres) pour interagir avec votre base de données Postgres.

Ensuite, initialisez knex dans votre projet en exécutant :

knex init

La commande ci-dessus crée un fichier knexfile.js. Ce fichier contient des options de configuration pour votre base de données.

Remplacez le code dans le fichier par le bloc de code ci-dessous :

require("dotenv").config();

export const development = {
  client: "pg",
  connection: process.env.DATABASE_URL,
  migrations: {
    directory: "./db/migrations",
  }
};

Ensuite, créez un fichier db.js dans le répertoire racine de votre projet et ajoutez-y le bloc de code ci-dessous.

const knex = require("knex");
const knexFile = require("./knexfile.js");

const environment = process.env.NODE_ENV || "development";

export default knex(knexFile[environment]);

Ensuite, créez un fichier .env et ajoutez-y les détails de connexion à votre base de données ou l’URI.

Par exemple :

DATABASE_URL = <YOUR_DATABASE_URI>

Remplacez “YOUR_DATABASE_URI” par l’URL de votre base de données.

Note : Assurez-vous d’ajouter votre fichier .env à votre fichier .gitignore afin de vous assurer que vous ne livrez pas d’informations privées au contrôle de version.

Création du modèle de base de données

Pour créer votre modèle de base de données à l’aide de Knex, vous allez créer un fichier de migration et écrire une commande SQL de création à l’aide de Knex.

Exécutez la commande ci-dessous pour créer votre première migration :

knex migrate:make blog

Ensuite, remplacez le code du fichier de migration généré par le bloc de code ci-dessous :

/**
 * @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");
}

Enfin, exécutez le bloc de code ci-dessous pour exécuter votre fichier de migration :

knex migrate:latest

La commande ci-dessus exécute le fichier de migration que vous avez généré précédemment, créant ainsi une table Blog dans votre base de données.

Création d’un serveur Bun-Elysia

Dans cette étape, vous allez créer un serveur API simple.

Ouvrez votre fichier index.ts et ajoutez le bloc de code ci-dessous :

//index.ts
const { Elysia } = require("elysia");
let db = require("./db");

db = db.default;

const app = new Elysia();

Dans le bloc de code ci-dessous, vous avez importé Elysia et créé une instance du framework Elysia (app).

Création de gestionnaires d’itinéraires

Ensuite, vous allez créer des gestionnaires de routes pour votre application. Le gestionnaire que vous créerez sera destiné aux routes suivantes :

  • POST /posts/create-new-post
  • GET /posts
  • GET /posts/:id
  • PATCH /posts/:id/update-post
  • DELETE /posts/:id/delete-post

Ajoutez le bloc de code ci-dessous à votre fichier index.ts pour créer le gestionnaire pour “/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 });
  }
});

Le bloc de code ci-dessus est un gestionnaire de route pour votre point de terminaison qui ajoute de nouveaux messages à votre base de données.

Ajoutez le bloc de code ci-dessous à votre fichier index.ts pour créer le gestionnaire qui récupère tous vos articles “/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 });
  }
});

Ajoutez le bloc de code ci-dessous à votre fichier index.ts pour créer le gestionnaire qui récupère un seul message par son identifiant “/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));
});

Ajoutez le bloc de code ci-dessous à votre fichier index.ts pour créer le gestionnaire qui met à jour un seul message avec les données contenues dans le payload par 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));
});

Ajoutez le bloc de code ci-dessous à votre fichier index.ts pour créer le gestionnaire qui supprime un seul message par l’identifiant “/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));
});

Enfin, ajoutez le bloc de code ci-dessous pour définir le PORT de votre application.

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

Exécutez la commande ci-dessous pour démarrer votre application :

bun --watch index.ts

Déploiement d’une application Bun sur des conteneurs Back4app

Le déploiement de votre application Bun se fait en quelques étapes.

Étape 1 : Écrire un fichier Docker

Pour créer un Dockerfile, exécutez la commande ci-dessous dans votre terminal.

touch Dockerfile

L’exécution de la commande ci-dessus crée un fichier Docker dans le répertoire racine de votre projet.

Ensuite, ouvrez votre fichier Docker et ajoutez-y le bloc de code ci-dessous :

FROM oven/bun

WORKDIR /app

COPY package.json .
COPY bun.lockb .

RUN bun install

COPY . .

EXPOSE 3000

CMD ["bun", "index.ts"]

Dans le fichier Docker ci-dessus, la première ligne, FROM oven/bun, spécifie l’image de base à utiliser. Cette image est une image préconstruite qui contient le runtime Bun et toutes ses dépendances.

La ligne suivante, WORKDIR /app, définit le répertoire de travail de l’image. Il s’agit du répertoire dans lequel le code de l’application sera copié et exécuté.

Les deux lignes suivantes, COPY package.json . et COPY bun.lockb ., copient les fichiers package.json et bun.lockb du répertoire courant dans l’image. Ces fichiers sont nécessaires à l’exécution de Bun pour installer les dépendances de l’application.

La ligne suivante, RUN bun install, installe les dépendances de l’application à l’aide du moteur d’exécution Bun.

La ligne suivante, COPY ..., copie l’ensemble du répertoire courant dans l’image. Cela inclut le code de l’application et tous les autres fichiers nécessaires.

La ligne suivante, EXPOSE 3000, expose le port 3000 du conteneur au monde extérieur. C’est le port sur lequel l’application écoutera.

La dernière ligne, CMD ["bun", "index.ts"], spécifie la commande qui sera exécutée au démarrage du conteneur. Cette commande lancera le moteur d’exécution Bun et exécutera le fichier index.ts de l’application.

Enfin, publiez votre code sur GitHub.

Étape 2 : Créer une application Back4app

L’étape suivante pour héberger une application Bun est de créer une nouvelle application sur Back4App. Tout d’abord, connectez-vous à votre compte Back4App ou inscrivez-vous si vous n’en avez pas encore. Une fois connecté, vous vous retrouverez sur le tableau de bord de Back4App.

Cliquez sur le bouton “NEW APP” et sélectionnez l’option“Containers as a Service“.

Back4app BaaS vs CaaS

Pour héberger une application Bun, connectez votre compte GitHub à votre compte Back4app. La connexion de votre compte permet à Back4app d’accéder aux dépôts de votre compte.

Vous pouvez décider d’accorder l’accès à tous les référentiels de votre compte ou à des référentiels spécifiques. Choisissez l’application que vous souhaitez déployer, dans ce cas, l’application que vous avez créée dans ce tutoriel, et cliquez sur Sélectionner.

Nouvelle application back4app

Après avoir cliqué sur le bouton Sélectionner, vous serez dirigé vers une page de configuration, où vous remplirez les détails de votre application, tels que le PORT et les variables d’environnement.

Après avoir rempli les détails, cliquez sur le bouton Créer une application. Ceci démarre le processus de déploiement. Votre déploiement devrait réussir, et vous obtiendrez une URL pour accéder à votre application, mais s’il échoue, vous pouvez profiter de l’intégration de Back4app ChatGPT pour résoudre les problèmes que vous avez avec votre Dockerfile.

Alternativement, vous pouvez résoudre manuellement vos erreurs de déploiement en utilisant les journaux détaillés et le guide de dépannage de Back4app.

Conclusion

Dans cet article, vous avez exploré le moteur d’exécution JavaScript Bun, ses avantages et ses limites apparentes. Vous avez également découvert comment construire une application Bun en utilisant Elysia, Knex et PostgreSQL.

Enfin, vous avez exploré les conteneurs Back4app et la manière de déployer vos applications Bun sur la plateforme.

Lors de l’utilisation de Bun, il est important de noter qu’il n’en est qu’à ses débuts et qu’il est susceptible d’introduire des changements majeurs à l’avenir.

FAQ

Qu’est-ce que Bun?

Bun est un environnement d’exécution JavaScript conçu pour être rapide et efficace. Il repose sur le moteur JavaScriptCore et bénéficie de plusieurs optimisations (avantages du langage bas niveau Zig) pour le rendre plus rapide.

Comment déployer une application Bun?

– Créez une application Bun.
– Écrivez un Dockerfile.
– Déployez votre application Bun sur GitHub.
– Ouvrez un compte Back4app ou connectez-vous à votre compte existant.
– Créez une nouvelle application « CaaS » sur Back4app.
– Accordez à Back4app l’accès à l’application que vous souhaitez déployer.
– Sélectionnez l’application et renseignez les informations de configuration.
– Cliquez sur « Déployer ».


Leave a reply

Your email address will not be published.