Aprende a incluir jQuery correctamente en tu proyecto Symfony para evitar la conocida excepción '$ is not a function'

Symfony es una de las mejores opciones para trabajar en el backend de tu proyecto web y jQuery es uno de los frameworks más fáciles disponibles para manipular el DOM en el frontend. Sin duda, para sitios web y blogs simples esta es una buena combinación, sin embargo, los desarrolladores novatos de Symfony se enfrentarán al problema de que, cuando incluyen jQuery en el base.html.twigarchivo y escriben scripts en las vistas secundarias (en el bloque del cuerpo) que extienden este vista, la excepción conocida $ is not definedaparecerá en la consola.

Nota

En este artículo no mostraremos cuál es la mejor manera de incluir (o ubicar) el archivo jQuery en su proyecto, eso depende de usted. Puede obtener más información sobre esta pregunta leyendo esta publicación en Stack Overflow .

¿Por qué pasó esto?

Seguramente ha incluido jQuery al final de la <body>etiqueta del documento base como una buena práctica para optimizar el tiempo de renderizado de su página, ¡ bien hecho ! Sin embargo, ¿por qué entonces no funciona correctamente en Symfony? Para que este error sea más fácil de entender, trabajaremos con ejemplos. Tenemos el siguiente marcado como nuestro archivo base.html.twig en el proyecto:

{# file: base.html.twig #}
<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/style.css" rel="stylesheet">
    </head>
    <body>
        {# Bloque de cuerpo donde aparecerán las vistas de los niños #}
        {% block body %}{% endblock %}

        {# 
             Ignorando la forma en que cargas jQuery, si cuidas las buenas prácticas
             cargado al final como una buena práctica
        #}
        <script src="jquery.js"></script>
    </body>
</html>

El archivo tiene solo 1 bloque, el bloque del cuerpo. Ahora, si está accediendo a otra acción en su proyecto que devuelve alguna respuesta HTML y usa este archivo base, la vista se verá, por ejemplo, como:

{% extends base.html.twig %}

{% block body %}
    <h1>Example Child View 1</h1>

    <p>Some text 1</p>
    
    <script>
        $(document).ready(function(){
            console.log("Script working properly");
        });
    </script>
{% endblock %}

La vista secundaria usa JavaScript como puede ver y es muy simple. Una vez que acceda a su ruta en el navegador, la respuesta HTML será:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/style.css" rel="stylesheet">
    </head>
    <body>
        <h1>Example Child View 1</h1>

        <p>Some text 1</p>
        
        <script>
            $(document).ready(function(){
                console.log("Script working properly");
            });
        </script>

        <script src="jquery.js"></script>
    </body>
</html>

De hecho, jQuery se está ejecutando cuando ni siquiera está disponible .

Solución

El problema se debe a la falta de comprensión de cómo funcionan los bloques Twig. De forma predeterminada, no necesita cargar jQuery en la etiqueta de encabezado del documento porque eso disminuirá la velocidad de carga de su documento. Solo necesita crear un nuevo bloque, a saber javascripts (el nombre se puede cambiar si lo desea) en su archivo base:

{# file: base.html.twig #}
<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/style.css" rel="stylesheet">
    </head>
    <body>
        {# Bloque de cuerpo donde aparecerán las vistas de los niños #}
        {% block body %}{% endblock %}

        {# 
            Ignorando la forma en que cargas jQuery, si cuidas las buenas prácticas
            cargado al final como una buena práctica
        #}
        <script src="jquery.js"></script>

        {# 
            Cree los bloques de javascripts donde se ven todos los scripts escritos en el niño.
            debería aparecer realmente
        #}
        {% block javascripts %}{% endblock %}
    </body>
</html>

Y si deseas escribir JavaScript (o cargar archivos) en sus vistas secundarias, simplemente escríbalo dentro del javascriptsbloque en lugar del cuerpo:

{% extends base.html.twig %}

{% block body %}
    <h1>Example Child View 2</h1>

    <p>Some text 2</p>
{% endblock %}

{% block javascripts %}
    <script>
        $(document).ready(function(){
            console.log("Script working properly");
        });
    </script>
{% endblock %}

Eso generaría el siguiente HTML en su lugar:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/style.css" rel="stylesheet">
    </head>
    <body>
        <h1>Example Child View 2</h1>

        <p>Some text 2</p>
    

        <script src="jquery.js"></script>
        <script>
            $(document).ready(function(){
                console.log("Script working properly");
            });
        </script>
    </body>
</html>

Lo que ya no debería arrojar un error porque jQuery ahora existe.

Que te diviertas ❤️!


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores