CSS y JavaScript con Asset Mapper
¿Qué pasa con las imágenes, CSS y JavaScript? ¿Cómo funciona eso en Symfony?
Las cosas públicas son... Público
En primer lugar, el directorio public/ se conoce como la raíz de tu documento. Cualquier cosa dentro de public/ es accesible para tu usuario final. Todo lo que no esté en public/ no es accesible, ¡lo cual es genial! Ninguno de nuestros archivos fuente de alto secreto puede ser descargado por nuestros usuarios.
Así que si quieres crear un archivo CSS o un archivo de imagen o cualquier otra cosa, la vida puede ser tan simple como ponerlo en public/. Ahora puedo ir a /foo.txt... y vemos el archivo.
Hola Mapeador de Activos
Sin embargo, Symfony tiene un gran componente llamado Asset Mapper que nos permite hacer efectivamente lo mismo... pero con algunas características importantes y extra. Tenemos unos cuantos tutoriales que profundizan en este tema: uno sobre el Mapeador de Activos específicamente y otro sobre cómo construir cosas con el Mapeador de Activos llamado LAST Stack. Échales un vistazo para profundizar.
¡Pero vamos a sumergirnos en las amistosas aguas del Mapeador de Activos! Confirma todos tus cambios -yo ya lo he hecho- e instálalo con:
composer require symfony/asset-mapper
Esta receta hace varios cambios... y recorreremos cada uno poco a poco, ya que son importantes.
Pero ya, si nos desplazamos y actualizamos, ¡nuestro fondo es azul! Inspecciona Element en tu navegador y ve a la consola. ¡También tenemos un registro de consola!
Este log viene de
assets/app.js. Bienvenido al mapeador de activos.
¡Muchas gracias!
Los 2 superpoderes de Asset Mapper
Asset Mapper tiene dos grandes superpoderes. El primero es que nos ayuda a cargar CSS y JavaScript. La receta nos ha proporcionado un nuevo directorio assets/ con un archivo app.js y otro styles/app.css. Como hemos visto, el registro de la consola procede de app.js.
| /* | |
| * Welcome to your app's main JavaScript file! | |
| * | |
| * This file will be included onto the page via the importmap() Twig function, | |
| * which should already be in your base.html.twig. | |
| */ | |
| import './styles/app.css'; | |
| console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉'); |
Así que este archivo se está cargando. Al parecer, también está incluyendo app.css, que es lo que nos da ese fondo azul.
| body { | |
| background-color: skyblue; | |
| } |
Más adelante hablaremos más sobre cómo se cargan estos archivos y cómo funciona todo esto. Pero por ahora, basta con saber que app.js y app.css están incluidos en la página.
El segundo gran superpoder de Asset Mapper es un poco más sencillo. La receta ha creado un archivo config/packages/asset_mapper.yaml. No hay mucho aquí:
| framework: | |
| asset_mapper: | |
| # The paths to make available to the asset mapper. | |
| paths: | |
| - assets/ |
sólo paths apuntando a nuestro directorio assets/. Pero gracias a esta línea, cualquier archivo que pongamos en el directorio assets/ estará disponible públicamente. Es como si el directorio assets/ viviera físicamente dentro de public/. Esto es útil porque, sobre la marcha, Asset Mapper añade el versionado de activos: un importante concepto de frontend que veremos dentro de un minuto.
Listado de activos y ruta lógica
Pero antes, dirígete a tu terminal y ejecuta otro nuevo comando debug:
php bin/console debug:asset
Esto muestra todos los activos expuestos públicamente a través del Mapeador de Activos. Ahora mismo son sólo dos: app.css y app.js.
Si descargas el código del curso de esta página y lo descomprimes, encontrarás un directorio tutorial/con un subdirectorio images/. Cortaré esto... y luego lo pegaré enassets/.
Así que ahora tenemos un directorio assets/images/ con 5 archivos dentro. Y, por cierto, puedes organizar el directorio assets/ como quieras.
Pero ahora, vuelve atrás y ejecuta de nuevo debug:asset:
php bin/console debug:asset
¡Los nuevos archivos están ahí!
Representación de una imagen
A la izquierda, ¿ves esta "ruta lógica"? Es la ruta que utilizaremos para hacer referencia a ese archivo en Asset Mapper.
Te lo mostraré: vamos a renderizar una etiqueta img en el logotipo. Copia la ruta lógica starshop-logo.png. Luego dirígete a templates/base.html.twig. Justo encima del bloque del cuerpo -para que no quede anulado por el contenido de nuestra página- añade una etiqueta <img> consrc="". En lugar de intentar codificar una ruta, di {{ y utiliza una nueva función Twig llamada asset(). Pásale la ruta lógica.
Ya está Vale, añadiré un atributo alt... para ser un buen ciudadano de la web.
| // ... line 1 | |
| <html> | |
| // ... lines 3 - 13 | |
| <body> | |
| <img src="{{ asset('images/starshop-logo.png') }}" alt="Starshop Logo"> | |
| {% block body %}{% endblock %} | |
| </body> | |
| </html> |
Probemos esto. Actualiza y... ¡estalla!
¿Has olvidado ejecutar
composer require symfony/asset. Función desconocida "activo".
Recuerda: nuestra aplicación empieza siendo pequeña. Y luego, a medida que necesitamos más funciones, instalamos más componentes Symfony. Y a menudo, si intentas utilizar una función de un componente que no está instalado, te lo dirá. La función Twigasset() proviene de otro componente diminuto llamado symfony/asset. Todo lo que tenemos que hacer es seguir el consejo. Copia el comando composer require, pasa a tu terminal y ejecútalo:
composer require symfony/asset
Cuando termine, muévete y actualiza. ¡Ahí está nuestro logotipo!
Versionado automático de activos
¿La parte más interesante? Ver el código fuente de la página y comprobar la URL:/assets/images/starshop-logo- y luego una larga cadena de letras y números, .png. Esta cadena se llama hash de la versión y se genera en función del contenido del archivo. Eso significa que si más adelante actualizamos nuestro logotipo, este hash cambiará automáticamente.
Esto es superimportante. A los navegadores les gusta almacenar en caché las imágenes, el JavaScript y los archivos CSS, lo que está muy bien: ayuda al rendimiento. Pero cuando cambiamos esos archivos, queremos que nuestros usuarios descarguen la nueva versión: no que sigan utilizando la versión obsoleta, almacenada en caché.
Pero como el nombre del archivo cambiará cuando actualicemos la imagen, ¡el navegador va a utilizar automáticamente el nuevo! Esto es así:
- El usuario va a nuestro sitio y descarga
logo-abc123.png. Su navegador lo almacena en caché. - En la siguiente visita, su navegador ve la etiqueta
imgparalogo-abc123.png, encuentra el archivo en su caché y lo utiliza. - Entonces llegamos nosotros, actualizamos ese archivo y lo desplegamos.
- La próxima vez que el usuario visite nuestro sitio, la etiqueta
imgapuntará a un nombre de archivo diferente:logo-def456.png. Y como el navegador no tiene ese archivo en su caché, lo descarga nuevo.
Se trata de un pequeño detalle, pero también es increíblemente importante para asegurarnos de que nuestros usuarios utilizan siempre los archivos más recientes. ¿Y lo mejor? Simplemente funciona. Ahora que te lo he explicado, no tendrás que volver a pensar en esto.
Ok equipo, vamos a instalar y empezar a usar Tailwind CSS a continuación.
15 Comments
Hi, I'm on Debian12 with Symfony7.1 I dont kow if that make any difference but
when I execute this command in terminal:
I recieve this error at the end of the recipe installer:
BUT, when I run:
everything goes well with this extra recipe (symfony/asset) as specified in:
https://symfonycasts.com/screencast/asset-mapper/install?playAt=28.188311
I hope this helps if sombody have the same problem
Hey Martin,
Thanks for this tip! Did you download the course code from this page and start from the start/ directory? I see we're using Symfony v7.0 in this course while you mentioned you're on 7.1 which means you may start a new project from scratch on the latest Symfony version. If so, yes, you need to bring that package as well as you did in your last command. That package was already pre-installed in the course project code, that's why it works out of the box. Though following our courses on a newer Symfony is OK and it's up to users, we do recommend to follow them by downloading the course code and start from the start/ dir.
Cheers!
I had not realized that I was using Symfony 7.1, I like to do the project from scratch, so I will understand it better, I am very new to this, also finding problems and solving them makes me learn :). I'm already on unit 18 and everything works fine. Thank you :) .
Hey Martin,
No problem :) Yeah, sure, it's up to you! You indeed can follow the course on a newer Symfony version. We usually add notes to the video and scripts when something is changed in a newer version that should help to users. But if you ever get stuck following our courses on a newer version - feel free to ask for help in the comments below the video and our support team will help you. You will miss some reconfiguration content this way that we prepared to for the tutorial start, we usually add some files to the empty Symfony project to make it nicer and save some times during the course, but with some little copy/paste I think you can easily bring that code into your empty project.
Cheers!
hello,
I have 2 questions about asset.
Hello,
assets/folder and then Symfony can process them and add versioning and so onCheers!
First of all - thank you very much for the great tutorial. It definitely makes me want to do more.
However, there is a problem with Twig and the asset maker. You can see this in the video at 03:54 (base.html.twig, line 15): asset() marks the file 'images/starshop-logo.png' as “Missing asset”, recognizable by the yellow background. Autocompletion does not work either, only “index.php” is suggested here. This can also be seen again and again in the following videos of the course.
I have already tried a few things, for example deleting the .idea folder and creating a new one, but the problem persists.
BUT! When I download your finished project and open it in PhpStorm, everything works perfectly (then it is base.html.twig, line 19), here I also have autocomplete available. What is different here?
Many thanks in advance!
Hey Thomas,
Hm, difficult to say, you would probably need to compare both projects locally to see the difference. It might be so that PhpStorm just didn't finish the indexing of your project yet? Follow that path in the public/ dir, i.e. make sure you have that public/images/starshop-logo.png file there. Also, you might need to compile your assets with
bin/console asset-map:compileto physically moved those files to the public/ dir. Also, make sure you have the Symfony PhpStorm plugin installed, enabled, and configured properly. But if those files are already in the public/ dir and it still does not autocomplete - try to restart your PhpStorm IDE maybe, not sure what else might be wrong.Cheers!
Hello Victor,
Thank you for your quick and detailed reply. I will probably invest a little more time and try to find out what the problem is. If I have any news, I'll let you know.
Cheers!
I also had the same error that was mentioned by user martinE.
Question about git reset:
Nevertheless I ran into another problem. Let say I only installed symfony/asset-mapper(without symfony/asset).
At this point my whole script with all the routes is completely broken and I can't even run php/bin console commands. I get cmd error:
and browser error:
I ran
git reset --hard HEADand
git clean -fdI also tried:
git reset --hard 14546d1(my previous safe save)It deleted all the 'asset mapper' files from staging area and project folder. My git head is at my previous commit before installing asset -mapper. Nevertheless my script is still broken. If I haven't googled the solution that i need to install symfony/asset i would be completely stuck at this point(with the previous 2 errors mentioned). It's a big problem in the sense that If I ran into the same problem in the future and can't google the solution my whole work will be broken.
Why didn't my git reset worked ?
Hey John-S,
If you rollback some files with Git, you still may need to clear the cache... also, you may need to rerun "composer install" and "yarn install --force" commands as well if you rollback some changes related to a new package installation. The reason is that some folders like Composer's vendor/ and NodeJS's node_modules/ are git-ignored, and so Git do not roll back files in there that were added/changed, so to keep them, in sync with the rollback-ed composer.lock and yarn.lock files you need to rerun those commands.
I hope that helps!
Cheers!
Hi there! Unfortunately the video cuts right after the Exception shows up at 6:17, I'm pretty sure we're missing 1 or 2 minutes of explanations according to the script.
Thank you again for this tutorial!
Hey @Adam-E
Are you talking about this chapter? I see it finishes where it should be and the next video continues exactly where this one ends.
Did I miss anything?
Hello @MolloKhan
I'm sorry, I don't know why yesterday my video ended right after the Exception "Did you forget to run composer require symfony/asset. Unknown function "asset"."
Everything seems to work perfectly now !
Thank you for reactivity
It could have been a Vimeo outage. That's where we store our videos :)
"Houston: no signs of life"
Start the conversation!