Dans mon article précédent, j'ai partagé quelques conseils pour éviter les outils de développement compliqués dans les projets Web modernes. J'ai expliqué comment importer des packages directement depuis le navigateur avec esm.sh.
Au fur et à mesure que vous accumulez des dépendances, et surtout lorsque vous assumez des dépendances qui elles-mêmes ont des dépendances (appelées dépendances transitives), vous constaterez peut-être que votre temps de chargement initial en souffre. Bien sûr, une fois la page chargée, tout est soigneusement mis en cache. Mais votre navigateur doit charger de nombreux fichiers différents (comme vous le dira votre onglet réseau dans les outils de développement) et une fois ces fichiers chargés, il doit charger encore un autre groupe de fichiers.
Bien sûr, c’est la seule raison pour laquelle les bundles existent ! La conclusion est donc qu’à un moment donné, vous avez besoin d’un bundler. Eh bien, peut-être. Mais vous n’avez pas besoin d’exécuter ce bundler vous-même. esm.sh a une fonctionnalité expérimentale qui créera en fait un bundle pour vous avec les packages que vous spécifiez. Voici comment je l'utilise.
Disons que nous avons besoin des packages suivants pour un éditeur que nous construisons.
import ts from typescript; import { tsSync, tsFacet, tsLinter, tsAutocomplete } from "@valtown/codemirror-ts"; import { basicSetup, EditorView } from "codemirror"; import { javascript } from "@codemirror/lang-javascript"; import { acceptCompletion, autocompletion } from "@codemirror/autocomplete"; import { Compartment, StateEffect } from "@codemirror/state"; import { oneDark } from "@codemirror/theme-one-dark"; import { indentWithTab } from "@codemirror/commands"; import { keymap, ViewPlugin } from "@codemirror/view"; import { createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, } from "@typescript/vfs";
Maintenant, vous pouvez simplement les ajouter à votre importmap dans index.html.
<script type="importmap"> { "imports": { "typescript": "https://esm.sh/typescript", "@valtown/codemirror-ts": "https://esm.sh/*@valtown/codemirror-ts", "style-mod": "https://esm.sh/style-mod", "w3c-keyname": "https://esm.sh/w3c-keyname", "crelt": "https://esm.sh/crelt", "@marijn/find-cluster-break": "https://esm.sh/@marijn/find-cluster-break", "@lezer/": "https://esm.sh/*@lezer/", "@codemirror/": "https://esm.sh/*@codemirror/", "codemirror": "https://esm.sh/*codemirror" } } </script>
Le * marque toutes les dépendances comme externes, ce qui est une autre fonctionnalité de esm.sh. J'ai également dû ajouter manuellement toutes les dépendances de codemirror. J'ai découvert que cela était nécessaire, car différents packages codemirror ont des versions légèrement différentes de dépendances translatives, et il importera différentes versions de ces dépendances transitives provoquant des conflits.
Cette approche fonctionne, mais comme décrit dans l'introduction, le temps de chargement initial en souffrira car le navigateur doit télécharger beaucoup de fichiers et il ne sait pas à l'avance quels fichiers il doit télécharger.
Vous pouvez utiliser cette approche pour laisser esm.sh créer un bundle sans utiliser vous-même un bundler. Je vais également vous expliquer comment faire fonctionner les types.
Tout d'abord j'ai créé un fichier /deps/editor.deps.js :
import build from "https://esm.sh/build"; const ret = await build({ dependencies: { "codemirror": "^6.0.1", "@valtown/codemirror-ts": "^2.3.1", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/autocomplete": "^6.18.4", "@codemirror/state": "^6.5.0", "@codemirror/theme-one-dark": "^6.1.2", "@codemirror/commands": "^6.7.1" }, source: ` import ts from "typescript"; import { tsSync, tsFacet, tsLinter, tsAutocomplete } from "@valtown/codemirror-ts"; import { basicSetup, EditorView } from "codemirror"; import { javascript } from "@codemirror/lang-javascript"; import { acceptCompletion, autocompletion } from "@codemirror/autocomplete"; import { Compartment, StateEffect } from "@codemirror/state"; import { oneDark } from "@codemirror/theme-one-dark"; import { indentWithTab } from "@codemirror/commands"; import { keymap, ViewPlugin } from "@codemirror/view"; import { createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, } from "@typescript/vfs"; export { ts, tsSync, tsFacet, tsLinter, tsAutocomplete, basicSetup, EditorView, javascript, acceptCompletion, autocompletion, Compartment, StateEffect, oneDark, indentWithTab, keymap, ViewPlugin, createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, };` }); const { ts, tsSync, tsFacet, tsLinter, tsAutocomplete, basicSetup, EditorView, javascript, acceptCompletion, autocompletion, Compartment, StateEffect, oneDark, indentWithTab, keymap, ViewPlugin, createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, } = await import(ret.bundleUrl); console.log({ret}); export { ts, tsSync, tsFacet, tsLinter, tsAutocomplete, basicSetup, EditorView, javascript, acceptCompletion, autocompletion, Compartment, StateEffect, oneDark, indentWithTab, keymap, ViewPlugin, createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, };
Il y a pas mal de répétitions ici. Et vous devrez mettre à jour les importations à plusieurs endroits si vous souhaitez les modifier. C'est certes assez compliqué. Je vous laisse décider si ça vaut le coup.
Dans tous les cas, vous verrez que lors de l'importation de ce fichier, ret sera imprimé sur la console. Voici ce qui est imprimé :
{ ret: { bundleUrl: "https://esm.sh/~e4d1ab3ba39fc16e6de014e6f19bd819605fdd95?bundle", id: "e4d1ab3ba39fc16e6de014e6f19bd819605fdd95", url: "https://esm.sh/~e4d1ab3ba39fc16e6de014e6f19bd819605fdd95" } }
Le bundleUrl est l'URL qui contient le bundle esm.sh créé pour nous ! Nous l'importons avec un import() dynamique puis le réexportons.
Vous pouvez donc simplement tout importer depuis /deps/editor.deps.js.
import { ts } from "/deps/editor.deps.js";
Et vous avez terminé !
Si vous voulez des importations comme
import { basicSetup, EditorView } from "codemirror";
pour travailler nous pouvons mettre à jour notre importmap comme suit :
import ts from typescript; import { tsSync, tsFacet, tsLinter, tsAutocomplete } from "@valtown/codemirror-ts"; import { basicSetup, EditorView } from "codemirror"; import { javascript } from "@codemirror/lang-javascript"; import { acceptCompletion, autocompletion } from "@codemirror/autocomplete"; import { Compartment, StateEffect } from "@codemirror/state"; import { oneDark } from "@codemirror/theme-one-dark"; import { indentWithTab } from "@codemirror/commands"; import { keymap, ViewPlugin } from "@codemirror/view"; import { createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, } from "@typescript/vfs";
Cela ne fonctionne pas pour les exportations par défaut (comme avec le package TypeScript). Pour cela, nous pouvons créer un fichier deps/editor.deps.d.ts pour faire fonctionner les types :
<script type="importmap"> { "imports": { "typescript": "https://esm.sh/typescript", "@valtown/codemirror-ts": "https://esm.sh/*@valtown/codemirror-ts", "style-mod": "https://esm.sh/style-mod", "w3c-keyname": "https://esm.sh/w3c-keyname", "crelt": "https://esm.sh/crelt", "@marijn/find-cluster-break": "https://esm.sh/@marijn/find-cluster-break", "@lezer/": "https://esm.sh/*@lezer/", "@codemirror/": "https://esm.sh/*@codemirror/", "codemirror": "https://esm.sh/*codemirror" } } </script>
Et voilà ! Regroupement sans bundler. Nous pouvons appeler
c'est sans bundle, car tout comme avec le sans serveur, il y a toujours un serveur/bundler impliqué, mais pas celui avec lequel vous devez vous occuper.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!