Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

importmap:require - Libs JS de terceros

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

En nuestro código, podemos utilizar declaraciones import con rutas relativas, clases ES6: todo a lo que estamos acostumbrados. Es lo de siempre. Excepto, ¿cómo podemos utilizar paquetes de terceros?

Como vimos antes, podemos importar cosas a través de una URL completa, como import _ from, y yo pegaré la URL CDN que usamos antes. Hecho esto, el resto es normal: añade _.camelCase() al registro.

6 lines assets/app.js
... line 1
import _ from 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm';
... lines 3 - 4
console.log(_.camelCase(mix.describe()));

Si refrescamos y comprobamos la consola... funciona. Pero no me gusta! No quiero tener que incluir esta URL loca en todas partes donde utilice lodash. ¿Y qué pasa si actualizamos Lodash... y tengo que cambiar la URL en 10 archivos diferentes? ¡Qué pena!

importmap:require para obtener paquetes de nodos

Si utilizáramos un sistema de compilación, como Webpack, podríamos simplemente decir

yarn add lodash

o

npm install lodash

No estamos utilizando yarn ni npm, pero podemos hacer casi lo mismo. En el terminal, abre una nueva pestaña y ejecutaphp bin/console importmap:require seguido del nombre del paquete NPM que queremos: lodash:

php bin/console importmap:require lodash

¡Listo! Ha añadido lodash a importmap.php y nos dice que podemos utilizar el paquete como de costumbre. Esto significa que podemos decir import _ from 'lodash'... y todo funcionará correctamente.

6 lines assets/app.js
... line 1
import _ from 'lodash';
... lines 3 - 6

¿Cómo? Cuando ejecutamos el comando, hizo un pequeño cambio: añadió esta sección a importmap.php. Y aunque esto sea genial, no es magia. Entre bastidores, el comando fue a la CDN de JSDelivr, encontró la última versión de lodash, y luego añadió el conjunto de claves lodash a esa URL.

Si te acercas y miras la fuente de la página... ¡no hay sorpresa! ¡Tenemos una nueva entrada lodashdentro de la importmap! Cuando nuestro navegador ve import _ from 'lodash', busca lodash dentro de importmap, encuentra esta URL y la descarga desde allí. ¡Nuestro navegador es el héroe!

Informar a tu editor sobre los paquetes

Una pega es que no tenemos autocompletado en nuestro editor. Dice "Módulo no instalado". Y si digo _.... en realidad no funciona. Autocompleta camelCase... pero sólo porque lo estoy usando aquí abajo.

Espero que PhpStorm lo soporte mejor pronto. Hay una solución, pero es un poco manual. Copia el paquete, entra en base.html.twig y añade una etiqueta temporal<script> que apunte a esto. Pulsa "alt" + "enter" y selecciona "Descargar biblioteca". Esto lo descarga en la sección "Bibliotecas externas" de aquí abajo: /lodash.

Vale, elimina la etiqueta script. De nuevo en app.js, seguirá subrayando la importación como si no supiera lo que es, pero autocompleta cuando usamos _. algo. Por ejemplo, tail() es de lodash.

Actualizar paquetes

¿Qué pasa con la actualización de las versiones de los paquetes dentro de importmap? Vaya, ¡hay un comando para eso!

php bin/console importmap:update

Eso hará un bucle a través de cada paquete y actualizará su URL a la última versión. Ésta ya es la última versión... pero si la cambiamos a .19... y luego ejecutamos el comando update... retrocede hasta .21. El comando podría ser más flexible -como permitirte actualizar sólo un paquete, o tener algunas restricciones de versión- y esas cosas podrían añadirse en el futuro.

25 lines importmap.php
... lines 1 - 15
return [
... lines 17 - 20
'lodash' => [
'url' => 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm',
],
];

Descargar paquetes localmente

Por último, si no quieres depender de la CDN, no tienes por qué hacerlo. Para evitarlo, cuando necesites el paquete -o en cualquier momento posterior- pasa la opción --download:

php bin/console importmap:require lodash --download

En importmap.php, esto sigue mostrando la URL de origen a la CDN, pero descarga ese archivo en un directorio assets/vendor/. Este downloaded_to apunta a la ruta lógica de ese archivo.

26 lines importmap.php
... lines 1 - 15
return [
... lines 17 - 20
'lodash' => [
'downloaded_to' => 'vendor/lodash.js',
... line 23
],
];

¿Cuál es el resultado? Cuando vamos y actualizamos .... y "Vemos la fuente de la página"... ¡el importmapapunta ahora al archivo local! Ya no dependemos de la CDN.

Pero... ¿y ahora qué? ¿Confirmamos este archivo vendor/lodash.js? La respuesta es... sí. Al menos en este momento, esa es la única forma de versionar ese archivo y mantenerlo en tu repositorio.

Así que, incluso sin npm ni yarn, podemos utilizar cualquier paquete npm que queramos. Pero a veces, en lugar de importar un paquete entero, puede que sólo queramos importar un archivo concreto. Hablemos de cómo podemos hacerlo a continuación.

Leave a comment!

0
Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^4.0", // v4.2.0
        "doctrine/doctrine-bundle": "^2.7", // 2.10.0
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.4
        "doctrine/orm": "^2.12", // 2.15.2
        "knplabs/knp-time-bundle": "^1.18", // v1.20.0
        "pagerfanta/doctrine-orm-adapter": "^4.0", // v4.1.0
        "pagerfanta/twig": "^4.0", // v4.1.0
        "stof/doctrine-extensions-bundle": "^1.7", // v1.7.1
        "symfony/asset": "6.3.*", // v6.3.0
        "symfony/asset-mapper": "6.3.*", // v6.3.0
        "symfony/console": "6.3.*", // v6.3.0
        "symfony/dotenv": "6.3.*", // v6.3.0
        "symfony/flex": "^2", // v2.3.1
        "symfony/framework-bundle": "6.3.*", // v6.3.0
        "symfony/http-client": "6.3.*", // v6.3.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/proxy-manager-bridge": "6.3.*", // v6.3.0
        "symfony/runtime": "6.3.*", // v6.3.0
        "symfony/stimulus-bundle": "^2.9", // v2.9.1
        "symfony/twig-bundle": "6.3.*", // v6.3.0
        "symfony/ux-turbo": "^2.9", // v2.9.1
        "symfony/web-link": "6.3.*", // v6.3.0
        "symfony/yaml": "6.3.*", // v6.3.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.6.1
        "twig/twig": "^2.12|^3.0" // v3.6.1
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.4
        "symfony/debug-bundle": "6.3.*", // v6.3.0
        "symfony/maker-bundle": "^1.41", // v1.49.0
        "symfony/stopwatch": "6.3.*", // v6.3.0
        "symfony/web-profiler-bundle": "6.3.*", // v6.3.0
        "zenstruck/foundry": "^1.21" // v1.33.0
    }
}
userVoice