{}const=>[]async()letfn</>var
DéveloppementWeb

Passer de Node.js à Bun : problèmes réels, bugs et pièges

Vous avez décidé d'essayer Bun au lieu de Node.js ? Découvrez les véritables pièges de la migration : incompatibilité des paquets, problèmes de base de données, débogage et autres bogues que vous rencontrerez certainement.

К

Kodik

Auteur

9 min de lecture

Introduction : qu'est-ce que Bun et pourquoi tout le monde en parle

Bun est un nouveau runtime JavaScript qui promet d'être beaucoup plus rapide que Node.js et Deno. Ses développeurs affirment que l'installation des paquets est 10 à 20 fois plus rapide et que le lancement des applications est 3 à 4 fois plus rapide. Cela semble tentant, n'est-ce pas ? Mais que se passe-t-il lorsque vous décidez de transférer un vrai projet sur Bun ?

Dans cet article, je vais vous parler des vrais problèmes auxquels les développeurs sont confrontés lors de la migration et comment les résoudre.

🔥 100 000+ étudiants déjà avec nous

Marre de lire la théorie ?
Il est temps de coder !

Kodik — une appli où tu apprends à coder par la pratique. Mentor IA, leçons interactives, projets réels.

🤖 IA 24/7
🎓 Certificats
💰 Gratuit
🚀 Commencer
Ont rejoint aujourd'hui

Que promet Bun ?

Avant de parler des problèmes, voyons ce que Bun propose en général :

  • Vitesse: Écrit en Zig, utilise JavaScriptCore au lieu de V8

  • Outils intégrés: bundler, transpiler, gestionnaire de paquets en un seul flacon

  • Compatibilité: Prise en charge déclarée de la plupart des API Node.js

  • TypeScript prêt à l'emploi: Aucun compilateur séparé n'est nécessaire

  • Web API: Prise en charge des API de navigateur modernes sur le serveur

Cela semble parfait. Mais la pratique montre autre chose.

Problème n° 1 : compatibilité incomplète avec Node.js

Qu'est-ce qui est attendu ?

Les développeurs de Bun promettent une compatibilité avec l'API Node.js à 90 %+. En théorie, votre code devrait simplement fonctionner.

Réalité :

// Ce code fonctionne dans Node.js
const fs = require('fs');
fs.watch('./files', { recursive: true }, (event, filename) => {
  console.log(`${filename} changed`);
});

Dans Bun, l'option recursive pour fs.watch() ne fonctionne pas sur certains systèmes d'exploitation. Vous obtiendrez une erreur ou un refus tacite de fonctionnement.

Solution :

Vérifiez la documentation Bun pour chaque API utilisée. Il est souvent nécessaire d'utiliser des bibliothèques alternatives :

// Alternative pour Bun
import { watch } from 'chokidar';

watch('./files', { 
  ignoreInitial: true 
}).on('all', (event, path) => {
  console.log(`${path} changed`);
});

Problème n°2 : paquets npm avec modules natifs.

Qu'est-ce qui est attendu ?

Bun doit prendre en charge la plupart des paquets npm, y compris ceux qui utilisent des modules natifs.

Réalité :

De nombreux packages populaires ne fonctionnent tout simplement pas :

bun install sharp  # Bibliothèque populaire pour travailler avec des images

Lorsque vous essayez d'utiliser :

import sharp from 'sharp';
const image = sharp('input.jpg');
// Error: Cannot find module "sharp"

Problèmes avec d'autres paquets :

  • bcrypt — les bindings natifs ne sont pas pris en charge

  • node-gyp dépendance - nécessite un réassemblage complet

  • sqlite3 — fonctionne de manière instable

Solution :

Recherchez des alternatives en JavaScript pur :

// Utilisez bcryptjs au lieu de bcrypt
import bcrypt from 'bcryptjs';
const hash = await bcrypt.hash('password', 10);

// Au lieu de sharp, vous pouvez utiliser Bun.file() + Canvas API
import { createCanvas, loadImage } from 'canvas';

Problème n°3 : Différences de comportement d'EventEmitter

Qu'est-ce qui est attendu ?

EventEmitter doit fonctionner exactement comme dans Node.js.

Réalité :

const EventEmitter = require('events');
const emitter = new EventEmitter();

// Dans Node.js, cela fonctionne
emitter.on('event', async () => {
  await someAsyncOperation();
});

emitter.emit('event');
console.log('Event emitted');
// Node.js: "Event emitted" → async operation
// Bun : peut tomber ou s'exécuter dans un ordre différent

La gestion des erreurs dans les gestionnaires d'événements asynchrones est différente, ce qui peut entraîner un rejet de promesse non traité.

Solution :

Toujours envelopper les gestionnaires asynchrones :

emitter.on('event', (data) => {
  (async () => {
    try {
      await someAsyncOperation(data);
    } catch (error) {
      console.error('Error in event handler:', error);
    }
  })();
});

Problème n° 4 : Différences dans le travail avec les voies

Réalité :

import path from 'path';
import { fileURLToPath } from 'url';

// Node.js + ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Bun se comporte différemment
console.log(__dirname); // Peut être undefined ou incorrect

Solution :

Utilisez les fonctionnalités intégrées de Bun :

// La bonne façon pour Bun
const currentFile = import.meta.path;
const currentDir = import.meta.dir;

console.log('Current file:', currentFile);
console.log('Current directory:', currentDir);

Problème n° 5 : Variables d'environnement et dotenv

Qu'est-ce qui est attendu ?

Bun télécharge automatiquement les fichiers .env, donc dotenv n'est pas nécessaire.

Réalité :

// Dans Node.js avec dotenv
require('dotenv').config();
console.log(process.env.DATABASE_URL);

// Dans Bun
console.log(process.env.DATABASE_URL); // Peut ne pas fonctionner

Bun charge .env, mais l'ordre des priorités est différent et certaines valeurs peuvent ne pas être récupérées.

Solution :

// Télécharger la configuration de manière explicite
import { config } from 'dotenv';
config({ path: '.env' });

// Ou utilisez l'API Bun
const env = Bun.env;
console.log(env.DATABASE_URL);

Problème n° 6 : Travail avec les bases de données

La réalité avec PostgreSQL :

// Node.js + pg
import pg from 'pg';
const { Pool } = pg;

const pool = new Pool({
  connectionString: process.env.DATABASE_URL
});

// Peut fonctionner de manière instable dans Bun
const result = await pool.query('SELECT * FROM users');
// Parfois, il se bloque ou tombe avec un timeout

Solution :

Utilisez la prise en charge native de SQLite dans Bun ou des pilotes alternatifs :

// Bun a un support intégré pour SQLite
import { Database } from 'bun:sqlite';

const db = new Database('mydb.sqlite');
const query = db.query('SELECT * FROM users');
const users = query.all();

// Pour PostgreSQL, utilisez postgres.js
import postgres from 'postgres';
const sql = postgres(process.env.DATABASE_URL);
const users = await sql`SELECT * FROM users`;

Problème n° 7 : Test

Réalité :

// La configuration Jest ne fonctionne pas directement
// package.json
{
  "scripts": {
    "test": "jest"
  }
}

// bun test lance son propre test runner

Bun a un test runner intégré, mais il n'est pas entièrement compatible avec Jest.

Solution :

Réécrire les tests sous Bun :

// test/example.test.ts
import { expect, test, describe } from 'bun:test';

describe('Math operations', () => {
  test('addition', () => {
    expect(2 + 2).toBe(4);
  });
  
  test('async operation', async () => {
    const result = await fetchData();
    expect(result).toBeDefined();
  });
});

Lancement :

bun test

Problème n° 8 : Hot Reload et Watch Mode

Réalité :

# Node.js avec nodemon
nodemon server.js

# Bun
bun --watch server.ts
# Fonctionne, mais peut ne pas redémarrer lorsque certains fichiers sont modifiés

Le mode Watch dans Bun ignore parfois les modifications ou redémarre trop souvent.

Solution :

Ajoutez des motifs explicites :

// bunfig.toml
[watch]
ignore = ["node_modules", "dist", ".git"]
include = ["src/**/*.ts", "src/**/*.js"]

Ou utilisez des outils externes :

npm install -D nodemon
nodemon --exec bun run server.ts

Problème n° 9 : Debugging

Réalité :

Node.js dispose d'excellents outils de débogage via Chrome DevTools ou VS Code. Dans Bun, cela fonctionne... différemment.

# Node.js
node --inspect-brk server.js

# Bun
bun --inspect server.ts
# N'affiche pas toujours correctement la pile d'appels

Solution :

Utilisez le débogage et la journalisation de la console :

// Ajoutez une journalisation détaillée
console.log('Debug point 1:', { variable1, variable2 });

// Utilisez des outils de formatage
import util from 'util';
console.log(util.inspect(complexObject, { depth: null, colors: true }));

// Ou Bun.inspect()
console.log(Bun.inspect(complexObject));

Problème n° 10 : Taille du bundle et tree-shaking

Qu'est-ce qui est attendu ?

Bun doit créer des bundles optimisés avec un tree-shaking automatique.

Réalité :

bun build ./src/index.ts --outdir ./dist
# Le paquet peut être plus grand que prévu

Le Tree-shaking ne fonctionne pas toujours efficacement, en particulier avec les modules CommonJS.

Solution :

Utilisez uniquement les modules ES et vérifiez le résultat :

// ❌ Mauvais
const lodash = require('lodash');

// ✅ Bien
import { map, filter } from 'lodash-es';

// Configuration de l'assemblage
bun build ./src/index.ts \
  --outdir ./dist \
  --minify \
  --splitting \
  --target browser

Recommandations pratiques pour la migration

Étape 1 : Commencez petit

Ne transférez pas l'ensemble du projet en une seule fois. Créez un petit projet test :

mkdir bun-test && cd bun-test
bun init

Étape 2 : Vérifier les dépendances

Créez une liste de tous les paquets npm et vérifiez leur compatibilité :

# Définissez les dépendances
bun install

# Lancer les tests
bun test

Étape 3 : Migration progressive

// Créer une couche de transition
// adapter.ts
export const runtime = {
  isNode: typeof process !== 'undefined' && !process.versions.bun,
  isBun: typeof process !== 'undefined' && !!process.versions.bun
};

export function getAdapter() {
  if (runtime.isBun) {
    return import('./adapters/bun');
  }
  return import('./adapters/node');
}

Étape 4 : Test dans un environnement de type production

# Dockerfile pour Bun
FROM oven/bun:1 as base
WORKDIR /app

COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

COPY . .
RUN bun run build

CMD ["bun", "run", "start"]

Quand ne PAS passer à Bun

Ne passez pas si :

  1. Le projet utilise de nombreux modules natifs — vous perdrez le temps gagné sur la vitesse à chercher des alternatives

  2. La stabilité est d'une importance capitale — Bun est encore jeune, des bugs peuvent se produire

  3. L'équipe n'est pas prête pour les expériences — vous devrez faire face à de nouveaux problèmes

  4. Utilisez des fonctionnalités Node.js spécifiques — flux, workers, API spéciales

  5. Besoin de prise en charge des anciennes versions — Bun ne prend pas en charge le code hérité

Quand faut-il essayer Bun

Passez si :

  1. Créer un nouveau projet — pas de bagage de l'ancien code

  2. Focus sur la vitesse de développement - l'installation rapide des paquets accélère vraiment le travail

  3. Utilisez une pile moderne — TypeScript, modules ES, bibliothèques modernes

  4. Prêts à expérimenter — vous pouvez passer du temps à résoudre des problèmes

  5. Besoin d'un bundler intégré — vous ne voulez pas configurer webpack/vite

Un exemple réel de migration d'une application Express simple

Version Node.js

// server.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.json({ message: 'Hello from Node.js' });
});

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

Version Bun (ce qui fonctionne)

// server.ts
import { serve } from 'bun';

serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    
    if (url.pathname === '/') {
      return new Response(
        JSON.stringify({ message: 'Hello from Bun' }),
        { headers: { 'Content-Type': 'application/json' } }
      );
    }
    
    return new Response('Not Found', { status: 404 });
  },
});

console.log('Server running on port 3000')

Bun est une technologie intéressante, mais elle est encore humide. Les vrais problèmes de migration incluent :

Conseils pour les débutants : Utilisez Bun pour de nouveaux projets et expériences. Pour les applications de production, il est préférable de rester sur Node.js, sauf si vous avez des raisons spécifiques de changer.

Dans le Codex nous ne nous contentons pas de vous expliquer la théorie, vous vous obtenez des compétences pratiques à travers des tâches et des projets réels.

Ce que vous obtiendrez :

  • Cours structurés — des bases aux sujets avancés

  • Travaux pratiques — consolidez vos connaissances avec des exemples réels

  • Analyses étape par étape — comprendre comment et pourquoi le code fonctionne

  • Technologies actuelles — étudiez ce qui est utilisé dans l'industrie

Besoin de soutien et de communication ?

Rejoignez notre chaîne Telegram active — déjà plus de 2000 personnes partageant les mêmes idéesqui :

  • Discuter de la technologie et partager l'expérience

  • S'entraider pour résoudre les problèmes

  • Partage de matériel et de découvertes utiles

  • Ensemble, ils grandissent en tant que développeurs

Accédez à Kodik — commencez votre parcours de programmation avec le soutien de la communauté et des matériaux de qualité ! 🚀

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte