Importar archivos específicos de un paquete
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.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeA veces, en lugar de importar un paquete en sí, puedes querer importar sólo una parte de él: como un archivo concreto. Lodash es un buen ejemplo de ello.
Sin agitar el árbol en el navegador
Pero antes de llegar ahí, en lugar de importar todo desde lodash, deberías poder decir import { camelCase } from 'lodash'. Entonces, aquí abajo, utilizarías directamente camelCase.
| // ... line 1 | |
| import { camelCase } from 'lodash'; | |
| // ... lines 3 - 4 | |
| console.log(camelCase(mix.describe())); |
Sin embargo, cuando nos desplazamos e intentamos esto... ¡error!
El módulo solicitado
lodashno proporciona una exportación llamadacamelCase.
Esto debería funcionar... y la razón por la que no lo hace es complicada. Básicamente, debido a la forma en que esta biblioteca específica empaqueta su módulo, no puedes importar funciones específicas como ésta. Sin embargo, funcionará con la mayoría de los demás paquetes.
Por ejemplo, si dices import { Modal } from 'bootstrap' (si utilizas Bootstrap), funcionará. Bootstrap empaqueta sus archivos correctamente.
Sin embargo, utilizar esta sintaxis no siempre es lo ideal con AssetMapper.
El problema es el siguiente. Si pasáramos este código por Encore, Encore haría algo llamado "sacudir el árbol". Vería que sólo estamos importandocamelCase desde lodash. Y así, en el JavaScript final, sólo nos daría el código de camelCase, no todo el paquete lodash.
En un entorno de navegador, si importas import de lodash, obtendrás todo lodash... aunque sólo estés importando una parte de él. Ahora bien, puede que no sea para tanto. La compilación completa de lodash sigue siendo de sólo 24 kilobytes. Pero, ¿y si estamos utilizando un paquete grande... pero sólo necesitamos importar una cosa concreta?
Importar un archivo concreto
Muchas veces, hay un archivo específico que podemos importar, como /camelCase. Normalmente encontrarás detalles sobre estos archivos en la documentación... aunque también puedes ir a buscarlos. Vuelve a JSDelivr... y aquí abajo, busca "lodash". A continuación, haz clic en "Archivos" para ver todos los archivos que forman parte de este paquete.
Para lodash, es una lista enorme... porque se trata de una biblioteca enorme. Uno de ellos es camelCase.js.
¡Vale! Así que vamos a intentar importar lodash/camelCase.
| // ... line 1 | |
| import camelCase from 'lodash/camelCase'; | |
| // ... lines 3 - 6 |
No voy a incluir el .js... pero de todas formas no va a funcionar. Observa: cuando actualizamos... ¡error!
Error al resolver el especificador de módulo
lodash/camelCase. Las referencias relativas deben empezar por "/", "./" o "../"
Este error significa que estamos importando algo mediante una importación "desnuda", y no se encontró en el importmap. Si "Vemos la fuente de la página", sí tenemos un importmappara lodash, pero no lodash/camelCase. Sí, esa coincidencia se hace exactamente. Vale, hay una forma de hacer una coincidencia, más o menos, "difusa" - lodash/* - pero yo no la uso.
La cuestión es: si quieres utilizar lodash/camelCase, debes añadirlo a tu mapa de importación, no lodash.
Ejecuta: busca tu terminal y ejecuta:
php bin/console importmap:remove lodash
Eso eliminará lodash de importmap.php y borrará el archivo deassets/vendor/.
| // ... lines 1 - 15 | |
| return [ | |
| 'app' => [ | |
| 'path' => 'app.js', | |
| 'preload' => true, | |
| ], | |
| ]; |
¡Qué bien! Ahora ejecuta ./bin/console importmap:require con el nombre del paquete / la ruta que quieras: lodash/camelCase.js.
php bin/console importmap:require lodash/camelCase.js
camelCase.js es el nombre del archivo en la CDN. Pero te darás cuenta de que, muchas veces en los documentos, se hace referencia a lodash/camelCase sin el .js. Y en este caso, puedes dejar el .js: tú decides. Eso funciona porque jsDelivr es amigable y hace que funcionen ambas versiones de la URL.
¿El resultado del comando? El mismo que antes Obtenemos una nueva entrada enimportmap.php que coincide con lo que queremos importar y establecer en una URL.
| // ... lines 1 - 15 | |
| return [ | |
| // ... lines 17 - 20 | |
| 'lodash/camelCase' => [ | |
| 'url' => 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/camelCase/+esm', | |
| ], | |
| ]; |
Copia esa URL para que podamos verla. ¡Ya está! Es el código de sólo camelCase.js.
Y cuando probamos la página... ¡funciona!
Estas son las conclusiones: si necesitas importar un archivo concreto de un paquete, puedes hacerlo: sólo tienes que pasar el nombre del paquete + la ruta del archivo a importmap:require.
A continuación, ¡añadamos Stimulus a nuestra aplicación!
8 Comments
Hi,
I have trouble getting run a specific library. It is vis-timeline that can be accessed via jsdelivr.com.
Here is what I did:
First I installed vis-timeline via
php/bin importmap:require vis-timelinewhich gives me 3 items:So that seemed to be successful.
Now I want to use the libraries in one of my stimulus controllers:
However I run into errors:
So whats missing or what do I wrong?
Thanks for any help here.
Oliver
Hey Oliiver,
I personally haven't used this library, can't say much about it. But it seems like you're trying to import it incorrectly. Maybe try this way:
I wonder if it works this way, though it's mentioned as a legacy way, so probably there should be a better way. I also see it's imported as
vis-data/peerso probably you should import it that Peer way? See the docs: https://github.com/visjs/vis-timeline?tab=readme-ov-file#peer-buildI hope that helps!
Cheers!
Hi Victor,
thanks for your reply.
I figured out what the problem was. First I wondered why vis-data throwed the error but not vis-timeline. I removed all references to vis-data and then the error was gone. So I assumed that vis-timeline was importing correctly.
Then I checked importmap again and saw something interesting.
I used only one importmap:require vis-timeline, which imported three things:
In importmap I saw the following
So with that I concluded that I need to import 'vis-data/peer/esm/vis-data.js' and not something else.
And "tada" the error was gone.
I am not at the end. There is a subsequent error I need to take care of, but the initial error is gone, which seems, that the libs are loaded correctly.
Thank you
Oliver.
PS:
I might come back, if I need help with the next error.
Latest update:
remove all vis-timeline related libs
add vis-timeline/standalone
Use the following imports:
And thanks for sharing the final solution with others!
Cheers!
Hey Oliver,
Good thinking! I'm glad you were able to fix that, indeed it makes sense to include that path that exists after you install the package, good job!
Cheers!
i have a big Problem: how to install opencv.js ? thats not possible at my projects
hey @timm
What about
php bin/console importmap:require opencv.js? Does it work?Cheers!
"Houston: no signs of life"
Start the conversation!