Deno est super cool. Je l'ai vu ce matin et je veux maintenant migrer vers Deno. J'essayais de déplacer mon script nodejs existant vers Deno. Est-ce que quelqu'un peut m'aider sur comment utiliser les modules npm dans Deno. J'ai besoin du module esprima. Celui-ci a le package https://github.com/denoland/deno_third_party/tree/master/node_modules mais je n'arrive pas à comprendre comment l'utiliser.
Réponses
Trop de publicités?Deno fournit une Bibliothèque de compatibilité Node, qui permettra d'utiliser certains packages NPM qui n'utilisent pas les APIs non-polyfilled de Node.js. Vous pourrez require
le package en utilisant https://deno.land/std/node/module.ts
Le code suivant fonctionne sur deno 1.0.0
import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);
const esprima = require("esprima");
const program = 'const answer = 42';
console.log(esprima.tokenize(program))
Le code ci-dessus utilisera esprima
depuis node_modules/
.
Pour l'exécuter, vous aurez besoin du drapeau --allow-read
deno run --allow-read esprima.js
Vous pouvez le restreindre uniquement à node_modules
deno run --allow-read=node_modules esprima.js
ce qui donne en sortie:
[
{ type: "Keyword", value: "const" },
{ type: "Identifier", value: "answer" },
{ type: "Punctuator", value: "=" },
{ type: "Numeric", value: "42" }
]
Note : de nombreuses APIs utilisées par std/
sont encore instables, vous devrez donc peut-être l'exécuter avec le drapeau --unstable
.
Après tout, ce projet est déjà écrit en TypeScript entièrement, et il n'utilise aucune dépendance, il leur sera donc très facile de l'adapter à Deno. Tout ce qu'ils ont à faire est d'utiliser l'extension .ts
sur leurs imports. Vous pouvez également bifurquer le projet et apporter les modifications.
// import { CommentHandler } from './comment-handler';
import { CommentHandler } from './comment-handler.ts';
// ...
Une fois qu'ils l'auront fait, vous pourrez simplement faire:
// Idéalement, ils publieraient une version taguée et vous l'utiliseriez au lieu de master
import esprima from 'https://raw.githubusercontent.com/jquery/esprima/master/src/esprima.ts';
const program = 'const answer = 42';
console.log(esprima.tokenize(program))
Alternative
Vous pouvez également utiliser https://jspm.io/
qui convertira les modules NPM en modules ES
Tous les modules sur npm sont convertis en modules ES en gérant la compatibilité totale avec CommonJS, y compris les conversions de mode strict.
import esprima from "https://dev.jspm.io/esprima";
const program = 'const answer = 42';
console.log(esprima.tokenize(program))
Pour les packages qui utilisent des modules Node.js non pris en charge par jspm, une erreur sera lancée:
Uncaught Error: Le module fs de Node.js n'est pas supporté par le cœur jspm.
Le support de Deno est suivi ici
https://github.com/jspm/jspm-core/issues/4, les +1 sont appréciés!
Pour l'instant, vous pouvez utiliser des packages qui n'utilisent que Buffer
, pour cela vous devrez inclure std/node
.
// import so polyfilled Buffer is exposed
import "https://deno.land/std/node/module.ts";
import BJSON from 'https://dev.jspm.io/buffer-json';
const str = BJSON.stringify({ buf: Buffer.from('hello') })
console.log(str);
Problème
En général, il y a deux problèmes avec les paquets npm dans Deno :
- La conformité au module ES (ESM) n'est pas garantie.
- Les imports bruts comme
import _ from "lodash"
ne fonctionnent pas - pas de résolution "magique" desnode_modules
- Tous les spécificateurs d'importation doivent inclure l'extension de fichier -
.ts
,.js
, etc. - Le système de module CommonJS n'est pas utilisable dans Deno
- Le paquet npm utilise des fonctionnalités natives de Node.js telles que
fs
oupath
.
Solutions au problème 1
1.1: Modules tiers
La section des Modules Tiers est le moyen le plus rapide de découvrir des paquets compatibles.
1.2: Fournisseurs de CDN ESM
Jetez également un œil aux fournisseurs de CDN, qui peuvent convertir automatiquement les paquets npm en modules ES (ESM) :
- Skypack CDN
- jspm.io
- unpkg.com avec le paramètre de requête
?module
Skypack CDN peut fournir des paquets convertis automatiquement, qui ont par exemple défini un "module" point d'entrée dans package.json
. Pour les utilisateurs de TypeScript : Il récupère les définitions de type .d.ts
avec les fichiers .js
(via les en-têtes HTTP X-TypeScript-Types
utilisés par Deno).
unpkg.com décrit son drapeau ?module
comme suit : "Développe tous les spécificateurs d'importation 'bruts' dans les modules JavaScript vers des URL unpkg. Cette fonctionnalité est expérimentale".
Esprima ne dépend pas des fonctionnalités natives de Node.js, donc nous pouvons simplifier son importation par une URL de CDN :
import esprima from "https://cdn.skypack.dev/esprima@^4.0.1"; // Option 1 : Skypack
import esprima from "https://dev.jspm.io/esprima"; // Option 2 : jspm
// votre programme
const tokens = esprima.tokenize("const foo = 'bar'"); // fonctionne
jspm serait un bon choix ici - les types Skypack TS n'ont pas fonctionné pour moi dans ce cas particulier.
1.3: Autres approches
Vous pouvez également essayer d'importer directement une version compatible avec ESM à partir des sources du dépôt (par exemple, une branche ESM). Cependant, pour Esprima, cela ne fonctionnera pas en raison de l'absence d'extensions de fichier dans le code.
Snowpack et jspm remplacent une approche plus manuelle pour convertir CommonJS en ESM. Le plugin rollup @rollup/plugin-commonjs
(utilisé en interne par Snowpack) est même un outil plus bas niveau.
Solution au problème 2
Deno fournit une couche de compatibilité Node, voir la réponse de Marcos Casagrande. Cependant, toutes les fonctionnalités natives de Node.js ne sont pas entièrement prises en charge.
Comme Esprima ne dépend pas des fonctionnalités natives de Node, vous pouvez opter pour l'option CDN plus simple.
0 votes
deno.land/manuel#comparaison-avec-nodejs