Bun 1.1, une boîte à outils rapide et tout-en-un pour exécuter, construire, tester et déboguer Javascript et TypeScript, du simple script à l'application complète

La version 1.1 de Bun, la boîte à outils rapide et tout-en-un pour exécuter, construire, tester et déboguer JavaScript et TypeScript, est désormais disponible. Cette nouvelle version représente une mise à jour majeure de Bun depuis la version 1.0, et offre plusieurs nouvelles fonctionnalités et API ainsi que la prise en charge de Windows.

L'objectif de Bun est simple : éliminer la lenteur et la complexité sans renoncer à tout ce qui fait le charme de JavaScript. Vos bibliothèques et frameworks préférés devraient toujours fonctionner, et vous ne devriez pas avoir à désapprendre les conventions qui vous sont familières.

Bun 1.1 est une énorme mise à jour. Il y a eu plus de 1700 commits depuis Bun 1.0, et un travail acharné a été réalisé pour rendre Bun plus stable et plus compatible avec Node.js. Des milliers de bugs ont été corrigés, des tonnes de nouvelles fonctionnalités et APIs ont été ajoutées, et maintenant, Bun prend en charge Windows !


Prise en charge de Windows

Vous pouvez désormais faire fonctionner Bun sur Windows 10 et les versions ultérieures ! C'est une étape importante, et l'équipe est ravie d'apporter Bun à un tout nouveau groupe de développeurs.

Bun sur Windows réussit 98 % de la suite de tests qui a été mise en place pour Bun sur macOS et Linux. Cela signifie que tout, depuis le runtime, le test runner, le package manager, le bundler, fonctionne sous Windows.

Pour commencer à utiliser Bun sous Windows, exécutez la commande suivante dans votre terminal :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
powershell -c "irm bun.sh/install.ps1 | iex"

bun install sur Windows

Bun dispose d'un gestionnaire de paquets intégré, compatible avec npm, qui installe les paquets. Lors de l'installation d'une application Vite React, bun install fonctionne 18 fois plus vite que yarn et 30 fois plus vite que npm sur Windows.

Nom : bun-install-on-windows.png
Affichages : 17615
Taille : 10,9 Ko
Temps passé à installer des dépendances dans une application vite react en utilisant `--ignore-scripts` sur Windows.

bun run sur Windows

Vous pouvez également exécuter des scripts en utilisant bun run, qui est une alternative plus rapide à npm run. Pour rendre bun run encore plus rapide sous Windows, un nouveau format de fichier a été créé : .bunx.

Le fichier .bunx est un lien symbolique inter-fichiers qui permet de lancer des scripts ou des exécutables utilisant Bun ou Node.js. Ce fichier a été créé pour plusieurs raisons :
  • Le fonctionnement des liens symboliques n'est pas garanti sous Windows.
  • Les shebangs en tête de fichier (#!/usr/bin/env bun) ne sont pas lus sous Windows.
  • Pour éviter de créer trois permutations de chaque exécutable : .cmd, .sh et .ps1.
  • Pour éviter de confondre les messages "Terminate batch job ? (O/n)".

Le résultat final est que bun run est 11x plus rapide que npm run, et bunx est également 11x plus rapide que npx.

Nom : bun-run-on-windows.png
Affichages : 4211
Taille : 6,0 Ko
Temps passé à exécuter "bunx cowsay" contre "npx cowsay" sous Windows.

Même si vous n'utilisez Bun que comme un gestionnaire de paquets et non comme un moteur d'exécution, .bunx fonctionne avec Node.js. Cela résout également l'ennuyeux message "Terminate batch job ?" auquel les développeurs Windows sont habitués lorsqu'ils envoient ctrl-c à un script en cours d'exécution.

Nom : terminate-batch-job-bun-red.gif
Affichages : 4193
Taille : 15,2 Ko
Nom : terminate-batch-job-npm-red.gif
Affichages : 4199
Taille : 20,2 Ko

bun --watch sur Windows

Bun dispose d'un support intégré pour le mode --watch. Cela vous permet d'avoir un cycle d'itération rapide entre le moment où vous faites des changements et le moment où ces changements affectent votre code. Sous Windows, le temps nécessaire entre le contrôle-s et le rechargement du processus a été optimisé.

Nom : bun-test-watch-windows-red.gif
Affichages : 4279
Taille : 403,3 Ko
À gauche, modification d'un fichier de test. A droite, `bun test --watch` sous Windows.

API Node.js sur Windows

Les API Node.js ont également été optimisées pour utiliser les appels de système les plus rapides disponibles sous Windows. Par exemple, fs.readdir() sur Bun est 58 % plus rapide que Node.js sur Windows.

Nom : fs-readdir-windows.png
Affichages : 4161
Taille : 6,1 Ko
Temps passé à lister les fichiers d'un répertoire, 1000 fois sous Windows.

Bun est un moteur d'exécution JavaScript

Le support de Windows n'est qu'une anecdote par rapport aux dizaines de nouvelles fonctionnalités, API et améliorations qui ont été apportées depuis la version 1.0 de Bun.

Les grands projets démarrent deux fois plus vite

Bun dispose d'un support intégré pour JavaScript, TypeScript et JSX, alimenté par le propre transpileur de Bun écrit en code natif hautement optimisé.

Depuis Bun 1.0, un cache adressable par le contenu a été mis en place pour les fichiers de plus de 50 Ko afin d'éviter les surcoûts de performance liés à la transposition répétée des mêmes fichiers.

Cela permet aux outils en ligne de commande, comme tsc, de fonctionner jusqu'à deux fois plus vite qu'avec Bun 1.0.

Nom : tsc-2x-faster.png
Affichages : 4164
Taille : 8,1 Ko
Temps passé à exécuter "tsc --help" dans Bun et Node.js.

Le shell Bun

Bun est désormais un shell multiplateforme - comme bash, mais aussi sous Windows.

JavaScript est le langage de script le plus populaire au monde. Alors, pourquoi est-il si compliqué d'exécuter des scripts shell ?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
import { spawnSync } from "child_process";
 
// this is a lot more work than it could be
const { status, stdout, stderr } = spawnSync("ls", ["-l", "*.js"], {
  encoding: "utf8",
});

Les différentes plates-formes ont également des interpréteurs de commandes différents, chacun ayant des règles de syntaxe, un comportement et même des commandes légèrement différents. Par exemple, si vous souhaitez exécuter un script shell à l'aide de cmd sous Windows :
  • rm -rf ne fonctionne pas.
  • FOO=bar <command> ne fonctionne pas.
  • which n'existe pas. (il est appelé where à la place)

Le Bun Shell est un lexateur, un analyseur et un interpréteur qui implémente un langage de programmation de type bash, ainsi qu'une sélection d'utilitaires de base tels que ls, rm et cat.

Le shell peut également être exécuté à partir de JavaScript et TypeScript, en utilisant l'API Bun.$.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
import { $ } from "bun";
 
// pipe to stdout:
await $`ls *.js`;
 
// pipe to string:
const text = await $`ls *.js`.text();

La syntaxe permet de passer facilement des arguments, des buffers et des pipes entre l'interpréteur de commandes et JavaScript.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
const response = await fetch("https://example.com/");
 
// pipe a response as stdin,
// pipe the stdout back to JavaScript:
const stdout = await $`gzip -c < ${response}`.arrayBuffer();

Les variables sont également échappées pour éviter l'injection de commandes.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
const filename = "foo.js; rm -rf /";
 
// ls: cannot access 'foo.js; rm -rf /':
// No such file or directory
await $`ls ${filename}`;

Vous pouvez exécuter des scripts shell à l'aide du Bun Shell en lançant bun run.


Le Bun Shell est activé par défaut sous Windows lors de l'exécution de scripts package.json avec bun run.

Bun.Glob

Bun dispose désormais d'une API Glob intégrée pour faire correspondre des fichiers et des chaînes de caractères à l'aide de motifs globaux. Elle est similaire aux bibliothèques Node.js populaires telles que fast-glob et micromatch, sauf qu'elle fait correspondre les chaînes trois fois plus vite.

Utilisez glob.match() pour faire correspondre une chaîne de caractères à un motif global.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
import { Glob } from "bun";
 
const glob = new Glob("**/*.ts");
const match = glob.match("src/index.ts"); // true

Utiliser glob.scan() pour lister les fichiers qui correspondent à un motif global, en utilisant un AsyncIterator.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
const glob = new Glob("**/*.ts");
 
for await (const path of glob.scan("src")) {
  console.log(path); // "src/index.ts", "src/utils.ts", ...
}

Bun.Semver

Bun dispose d'une nouvelle API Semver pour analyser et trier les chaînes Semver. Elle est similaire au paquetage populaire node-semver, sauf qu'elle est 20 fois plus rapide.

Utilisez semver.satisfies() pour vérifier si une version correspond à un range.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
import { semver } from "bun";
 
semver.satisfies("1.0.0", "^1.0.0"); // true
semver.satisfies("1.0.0", "^2.0.0"); // false

Utilisez semver.order() pour comparer deux versions ou trier un tableau de versions.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
const versions = ["1.1.0", "0.0.1", "1.0.0"];
versions.sort(semver.order); // ["0.0.1", "1.0.0", "1.1.0"]

Bun.stringWidth()

Bun supporte également une nouvelle API string-width pour mesurer la largeur visible d'une chaîne de caractères dans un terminal. C'est utile lorsque vous voulez savoir combien de colonnes une chaîne de caractères occupera dans un terminal.

C'est similaire au paquetage populaire string-width, mais c'est 6000 fois plus rapide.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
import { stringWidth } from "bun";
 
stringWidth("hello"); // 5
stringWidth("👋"); // 2
stringWidth("你好"); // 4
stringWidth("👩*👩*👧*👦"); // 2
stringWidth("\u001b[31mhello\u001b[39m"); // 5

Il supporte les codes d'échappement ANSI, les caractères pleine largeur, les graphèmes et les emojis. Il supporte également les encodages Latin1, UTF-16 et UTF-8, avec des implémentations optimisées pour chacun d'entre eux.

server.url

Lorsque vous créez un serveur HTTP à l'aide de Bun.serve(), vous pouvez désormais obtenir l'URL du serveur à l'aide de la propriété server.url. Ceci est utile pour obtenir l'URL formatée d'un serveur dans les tests.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
import { serve } from "bun";
 
const server = serve({
  port: 0, // random port
  fetch(request) {
    return new Response();
  },
});
 
console.log(`${server.url}`); // "http://localhost:1234/"

server.requestIP()

Vous pouvez également obtenir l'adresse IP d'une requête HTTP en utilisant la méthode server.requestIP(). Cette méthode ne lit pas les en-têtes tels que X-Forwarded-For ou X-Real-IP. Elle renvoie simplement l'adresse IP du socket, qui peut correspondre à l'adresse IP d'un proxy.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
import { serve } from "bun";
 
const server = serve({
  port: 0,
  fetch(request) {
    console.log(server.requestIP(request)); // "127.0.0.1"
    return new Response();
  },
});

subprocess.resourceUsage()

Lorsque vous créez un sous-processus à l'aide de Bun.spawn(), vous pouvez désormais accéder à l'utilisation du processeur et de la mémoire d'un processus à l'aide de la méthode resourceUsage(). Cette méthode est utile pour surveiller les performances d'un processus.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { spawnSync } from "bun";
 
const { resourceUsage } = spawnSync([
  "bun",
  "-e",
  "console.log('Hello world!')",
]);
 
console.log(resourceUsage);
// {
//   cpuTime: { user: 5578n, system: 4488n, total: 10066n },
//   maxRSS: 22020096,
//   ...
// }

import.meta.env

Bun prend désormais en charge les variables d'environnement grâce à import.meta.env. Il s'agit d'un alias de process.env et Bun.env, qui existe pour des raisons de compatibilité avec d'autres outils de l'écosystème JavaScript, tels que Vite.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
import.meta.env.NODE_ENV; // "development"

Compatibilité avec Node.js

Bun a pour objectif de remplacer Node.js.

La compatibilité avec Node.js reste une priorité absolue pour Bun. De nombreuses améliorations et corrections ont été apportées au support des APIs Node.js par Bun. En voici quelques-unes :

Client HTTP/2

Bun supporte maintenant les API node:http2 client, qui vous permettent de faire des requêtes HTTP/2 sortantes. Cela signifie également que vous pouvez utiliser des paquets comme @grpc/grpc-js pour envoyer des requêtes gRPC via HTTP/2.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { connect } from "node:http2";
 
const client = connect("https://example.com/");
const request = client.request({ ":path": "/" });
 
request.on("response", (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
    // "cache-control: max-age=604800", ...
  }
});
 
request.on("end", () => {
  client.close();
});
 
request.end();

Date.parse() compatible avec Node.js

Bun utilise JavaScriptCore comme moteur JavaScript, contrairement à Node.js qui utilise V8. L'analyse de Date est compliquée, et son comportement varie grandement d'un moteur à l'autre.

Par exemple, dans Bun 1.0, la Date suivante fonctionnerait dans Node.js, mais pas dans Bun :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
const date = "2020-09-21 15:19:06 +00:00";
 
Date.parse(date); // Bun: Invalid Date
Date.parse(date); // Node.js: 1600701546000

Pour corriger ces incohérences, le parser Date a été porté de V8 à Bun. Cela signifie que Date.parse et new Date() se comportent de la même manière dans Bun que dans Node.js.

fs.readdir() récursif

Dans Bun 1.0, il n'y avait pas de support pour l'option recursive dans fs.readdir(). Il s'agissait d'un oubli qui a causé des bogues subtils avec de nombreux paquets.

Non seulement le support de l'option recursive a été ajouté, mais il est également 22 fois plus rapide que Node.js.

Nom : fs-readdir-recursive.png
Affichages : 4147
Taille : 6,0 Ko
Temps passé à lister les fichiers en utilisant la fonction récursive "fs.readdir()`" dans un grand répertoire.

Support IPC entre Bun et Node.js

Vous pouvez maintenant envoyer des messages IPC entre Bun et les processus Node.js en utilisant l'option ipc. Ceci corrige également un bug qui faisait que Bun se bloquait lors de l'utilisation de Next.js 14.1.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if (typeof Bun !== "undefined") {
  const prefix = `[bun ${process.versions.bun} 🐇]`;
  const node = Bun.spawn({
    cmd: ["node", __filename],
    ipc({ message }) {
      console.log(message);
      node.send({ message: `${prefix} 👋 hey node` });
      node.kill();
    },
    stdio: ["inherit", "inherit", "inherit"],
    serialization: "json",
  });
 
  node.send({ message: `${prefix} 👋 hey node` });
} else {
  const prefix = `[node ${process.version}]`;
  process.on("message", ({ message }) => {
    console.log(message);
    process.send({ message: `${prefix} 👋 hey bun` });
  });
}

API non documentées de Node.js

Node.js possède de nombreuses API non documentées que vous ne trouveriez pas en lisant sa documentation.

Il y a des millions de paquets npm, inévitablement certains d'entre eux dépendront d'API obscures ou non documentées. Au lieu de laisser ces paquets cassés ou oubliés, ces API sont ajoutées à Bun pour que vous n'ayez pas à réécrire votre code.

Par exemple, ServerResponse a une propriété _headers non documentée qui permet de modifier les en-têtes HTTP en tant qu'objet.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
import { createServer } from "node:http";
 
createServer((req, res) => {
  const { _headers } = res;
  delete _headers["content-type"];
  res._implicitHeader();
  res.end();
});

Cette API a été utilisée dans une version récente d'Astro, qui a été corrigée dans Bun. Il y avait également une fonction _implicitHeader(), utilisée par Express, qui a également été corrigée.

Lire la suite

Source : Bun 1.1

Et vous ?

Qu'en pensez-vous ?
Quelles sont les fonctionnalités ou améliorations que vous trouvez intéressantes ?

Voir aussi :

La version 0.6.0 de Bun, la boite à outils pour les applications JavaScript et TypeScript, est désormais disponible, et s'étoffe d'un bundler et d'un minifier JavaScript intégrés

Bun, un nouveau moteur d'exécution JavaScript, livré avec un client SQLite3 rapide, il apporte un peu de concurrence pour Node et Deno