<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Chris López</title>
    <description>The latest articles on Forem by Chris López (@krsrk).</description>
    <link>https://forem.com/krsrk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F737662%2F85e16234-2c57-4855-b3d9-e1d4d39a32eb.png</url>
      <title>Forem: Chris López</title>
      <link>https://forem.com/krsrk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/krsrk"/>
    <language>en</language>
    <item>
      <title>Actualizando la versión de PHP al proyecto Pokedex.</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Fri, 26 May 2023 06:05:58 +0000</pubDate>
      <link>https://forem.com/krsrk/actualizando-la-version-de-php-al-proyecto-pokedex-3c0a</link>
      <guid>https://forem.com/krsrk/actualizando-la-version-de-php-al-proyecto-pokedex-3c0a</guid>
      <description>&lt;p&gt;Hace ya tiempo, hice una publicación en la cual desarrolle un Pokedex con simple y llano PHP, solo usando ciertas librerías que sirvieron como herramientas para agregar funcionalidad al proyecto. &lt;/p&gt;

&lt;p&gt;Como contexto general, es como un mini framework donde solo tiene funcionalidad de crear rutas, hacer requests y responses y crear controllers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;El repositorio del proyecto lo puedes consultar aquí:&lt;br&gt;
&lt;a href="https://github.com/krsrk/pokedex-vanilla-php" rel="noopener noreferrer"&gt;https://github.com/krsrk/pokedex-vanilla-php&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nos vamos a dar a la tarea de actualizar la versión de PHP a la mas actual, que es la 8.2(actualmente la versión que maneja el pokedex es la 7.2). &lt;/p&gt;

&lt;p&gt;Después de actualizar las librerías y la versión de PHP, refactorizaremos código basados en las nuevas características de la versión 8.2 de PHP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre requisitos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tener &lt;strong&gt;PHP 8.2&lt;/strong&gt; instalado en CLI&lt;/li&gt;
&lt;li&gt;Tener &lt;strong&gt;GIT&lt;/strong&gt; instalado en CLI&lt;/li&gt;
&lt;li&gt;Tener la versión mas actual de &lt;strong&gt;composer&lt;/strong&gt; instalado en CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Manos a la obra
&lt;/h2&gt;

&lt;p&gt;Los primeros pasos que debemos hacer, es actualizar el &lt;strong&gt;composer.json&lt;/strong&gt; con las versiones de las librerías mas actuales y la versión o versiones de PHP que vamos a manejar.&lt;/p&gt;

&lt;p&gt;Entonces actualizamos nuestro &lt;strong&gt;composer.json&lt;/strong&gt; con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"require": {
        "php": "^8.1||^8.2",
        "twig/twig": "^v3.6.0",
        "illuminate/database": "^v10.10.1",
        "vlucas/phpdotenv": "^v5.5.0"
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con estos pasos ya tendríamos actualizadas las librerías que se usaron, así como también la versión de PHP requerida para el proyecto.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si quieres revisar estos cambios puedes ver el Pull Request en el siguiente link:&lt;br&gt;
&lt;a href="https://github.com/krsrk/pokedex-vanilla-php/pull/2" rel="noopener noreferrer"&gt;https://github.com/krsrk/pokedex-vanilla-php/pull/2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Actualizando código
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Instalando nuestra suite de pruebas
&lt;/h3&gt;

&lt;p&gt;Para este paso necesitaremos la librería de &lt;strong&gt;PEST&lt;/strong&gt;, que es una librería o super set de &lt;strong&gt;PHPUnit&lt;/strong&gt; que nos ayuda hacer pruebas unitarias y pruebas de integración. Con esto crearemos las pruebas unitarias del actual código(src/Utils) para poder validar y probar los cambios el código actual.&lt;/p&gt;

&lt;p&gt;Instalamos la librería:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require pestphp/pest --dev --with-all-dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despues ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./vendor/bin/pest --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;El comando anterior nos inicializa la configuración de PEST para empezar a crear nuestros tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora, probamos la instalación de PEST con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./vendor/bin/pest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creando nuestra primer prueba
&lt;/h3&gt;

&lt;p&gt;Ya teniendo PEST instalado, vamos a hacer cambios en la clase Response. Estos cambios aplicarían lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementar el contrato de la clase(crear la interface de la clase Response)&lt;/li&gt;
&lt;li&gt;Agregar tipado de datos en métodos, propiedades y parámetros(esto se puede hacer desde la versión 8.1).&lt;/li&gt;
&lt;li&gt;Refactorización de procesos internos de la clase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con estos requerimientos definidos, creamos nuestra prueba:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
//tests/Unit/ResponseTest

test('it can create a response object', function (){
    $response = new \Utils\Response();

    expect($response)-&amp;gt;toBeObject();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Actualizando nuestra clase Response
&lt;/h3&gt;

&lt;p&gt;Como anteriormente mencionamos, el primer requerimiento es hacer el contrato de la clase o interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Utils;

interface ResponseInterface
{
    public function setClosure(): void;

    public function send(Request $request): void;

    public function getClosure(): mixed;

    public function json(mixed $dataResponse, int $codeResponse = 200): void;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementamos la interface en nuestra clase Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Response implements ResponseInterface
{
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cambiamos la definición de nuestros métodos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Antes
public function send($request)
{

// Después
public function send(Request $request): void
{
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cambiamos también el constructor de la clase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Antes
protected $closure;

public function __construct($closure = null)
{
        if(!is_null($closure)) {
            $this-&amp;gt;setClosure($closure);
        }
}

// Después
public function __construct(protected mixed $closure = null)
{
        if(!is_null($this-&amp;gt;closure)) {
            $this-&amp;gt;setClosure();
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando inicializamos la propiedad "closure" en el método "setClosure", se le asignan varios valores de "closure types" que son de tipo string; actualmente están escritos sin ninguna asignación directo en el código, o lo que se conoce en el ambiente dev como valores &lt;strong&gt;"hardcodeados"&lt;/strong&gt;, para arreglar esto usaremos Enums con los valores de los closure types:&lt;/p&gt;

&lt;p&gt;Creamos la clase Enum para implementar los valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Utils\ValueObjects;

enum ClosureTypes: string
{
    case CLOSURE_STRING = 'string';

    case CLOSURE_ARRAY = 'array';

    case CLOSURE_CONTROLLER = 'controller';

    case CLOSURE_FUNCTION = 'function';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En nuestro metodo "setClosure" cambiamos esos valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

if (is_array($closure)) {
    // Antes: $closureType = 'array'

    // Después
    $closureType = ClosureTypes::CLOSURE_ARRAY-&amp;gt;value;
}

if (is_callable($closure)) {
    // Antes: $closureType = 'closure'

    // Después
    $closureType = ClosureTypes::CLOSURE_FUNCTION-&amp;gt;value;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modificamos nuestro archivo de test con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test('it can create a response object with closure', function (){
    $response = new \Utils\Response('Hello World');

    expect($response)-&amp;gt;toBeObject();
});

test('it can create a response object with string closure', function (){
    $response = new \Utils\Response('Hello World');
    $closure = $response-&amp;gt;getClosure();

    expect($closure['closure_type'])-&amp;gt;toBe(\Utils\ValueObjects\ClosureTypes::CLOSURE_STRING-&amp;gt;value);
});

test('it can create a response object with array closure', function (){
    $response = new \Utils\Response(['pokemon' =&amp;gt; 'Bulbasaur']);
    $closure = $response-&amp;gt;getClosure();

    expect($closure['closure_type'])-&amp;gt;toBe(\Utils\ValueObjects\ClosureTypes::CLOSURE_ARRAY-&amp;gt;value);
});

test('it can create a response object with function closure', function (){
    $response = new \Utils\Response(fn() =&amp;gt; 'Hello World');
    $closure = $response-&amp;gt;getClosure();

    expect($closure['closure_type'])-&amp;gt;toBe(\Utils\ValueObjects\ClosureTypes::CLOSURE_FUNCTION-&amp;gt;value);
});

test('it can create a response object with controller closure', function (){
    $response = new \Utils\Response('PokemonController@index');
    $closure = $response-&amp;gt;getClosure();

    expect($closure['closure_type'])-&amp;gt;toBe(\Utils\ValueObjects\ClosureTypes::CLOSURE_CONTROLLER-&amp;gt;value);
});

test('it expects "unknown" if there is an unknown closure', function (){
    $response = new \Utils\Response(1);
    $closure = $response-&amp;gt;getClosure();

    expect($closure['closure_type'])-&amp;gt;toBe('unknown');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejecutamos nuestro test y deberíamos ver algo como lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k1i9u7ru5peyw9a9not.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k1i9u7ru5peyw9a9not.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactorizando el método send()
&lt;/h3&gt;

&lt;p&gt;Una vez que tengamos nuestros test validados, debemos refactorizar el código de nuestra clase.&lt;/p&gt;

&lt;p&gt;Para efectos prácticos lo vamos hacer con el método send(), que es el que se encargará de ejecutar el response dependiendo su tipo de closure(string, array, json, function, controller).&lt;/p&gt;

&lt;p&gt;El código original del método es el siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function send($request)
{
        if ($this-&amp;gt;closure['closure_type'] == 'string') {
            echo $this-&amp;gt;closure['closure'];
        } elseif ($this-&amp;gt;closure['closure_type'] == 'array') {
            echo json_encode($this-&amp;gt;closure['closure']);
        } elseif ($this-&amp;gt;closure['closure_type'] == 'closure' || $this-&amp;gt;closure['closure_type'] == 'controller') {
            $this-&amp;gt;_executeClosure($request);
        } else {
            header("HTTP/1.0 404 Not Found");
            exit('&amp;lt;h3&amp;gt;404 - Not Found&amp;lt;/h3&amp;gt;');
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para refactorizar las sentencias &lt;strong&gt;"if"&lt;/strong&gt; implementaremos un tipo factory para poder instanciar una clase dependiendo algún parámetro de funcionalidad o comportamiento.&lt;/p&gt;

&lt;p&gt;Entonces, si por ejemplo tengo un &lt;strong&gt;closure_type = 'string'&lt;/strong&gt; el Factory va instanciar la clase ClosureTypeString y va a ejecutar su método execute().&lt;/p&gt;

&lt;p&gt;De esta forma quedaría el código refactorizado del método send():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (is_null(ClosureTypes::tryFrom($this-&amp;gt;closure['closure_type']))) {
    header("HTTP/1.0 404 Not Found");
    exit('&amp;lt;h3&amp;gt;404 - Not Found&amp;lt;/h3&amp;gt;');
}

ClosureType::from($this-&amp;gt;closure['closure_type'], $this-&amp;gt;closure['closure'])-&amp;gt;execute($request-&amp;gt;getParams());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agregamos el test de este método ya refactorizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test('it can send a string response', function (){
    $_SERVER['REQUEST_URI'] = '/orders/products/1';
    $response = new \Utils\Response('Hello World');
    $response-&amp;gt;send(request());
})-&amp;gt;expectNotToPerformAssertions();

test('it can send an array response', function (){
    $_SERVER['REQUEST_URI'] = '/orders/products/1';
    $response = new \Utils\Response(['message' =&amp;gt; 'Hello World']);
    $response-&amp;gt;send(request());
})-&amp;gt;expectNotToPerformAssertions();

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejecutamos las pruebas y vemos que todas pasaron:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc1g8fu98kxb8s5y9vv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc1g8fu98kxb8s5y9vv5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora, iniciamos el servidor y ejecutamos nuestro proyecto con alguna ruta que venga registrada en el &lt;strong&gt;routes/web.php&lt;/strong&gt;, deberíamos de ver lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftp47hb20iplkva91p1ig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftp47hb20iplkva91p1ig.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ejecutamos todas nuestras pruebas con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ./vendor/bin/pest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y deberíamos de ver algo como esto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo04sdfjh4uy4ey37ssbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo04sdfjh4uy4ey37ssbm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con estos pasos, podríamos decir, que tenemos cubiertos los cambios al integrar las pruebas al código. Es muy importante, que en cambios mayores al código se tengan integradas este tipo de pruebas, ya que estas son las que nos pueden salvar de varios dolores de cabeza y ahorrar tiempo a la hora de hacer algún deploy.&lt;/p&gt;

&lt;p&gt;Los cambios los puedes consultar en el siguiente PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/krsrk/pokedex-vanilla-php/pull/5" rel="noopener noreferrer"&gt;https://github.com/krsrk/pokedex-vanilla-php/pull/5&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>development</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>PHP 8.2 Liberación Nov. 2022</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Mon, 19 Sep 2022 22:07:38 +0000</pubDate>
      <link>https://forem.com/krsrk/php-82-liberacion-nov-2022-3b4h</link>
      <guid>https://forem.com/krsrk/php-82-liberacion-nov-2022-3b4h</guid>
      <description>&lt;p&gt;Para noviembre 24, se libera la nueva versión de PHP 8.2, la cual traerá nuevas características que mejoran mucho el lenguaje y lo harán mas robusto. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Puedes ver el estatus de este release en este link: &lt;a href="https://wiki.php.net/todo/php82"&gt;https://wiki.php.net/todo/php82&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;También puedes revisar el timelapse de las versiones de PHP en este link: &lt;a href="https://www.php.net/supported-versions.php"&gt;https://www.php.net/supported-versions.php&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A continuación, se describen algunas de las características mas importantes de la versión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Readonly classes
&lt;/h2&gt;

&lt;p&gt;Esta característica introducida en la versión 8.1, hace que las propiedades de nuestra clase sean de solo lectura, evitando la sobreescritura de los valores asignados a nuestras propiedades, eso se usa con bastante frecuencia en las clases DTO.&lt;/p&gt;

&lt;p&gt;Esta característica en la versión 8.1 se define de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User
{
    public function __construct(
        public readonly string $name, 
        public readonly string $email,
    ) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la versión 8.2 se refactoriza de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;readonly class User
{
    public function __construct(
        public string $name, 
        public string $email,
    ) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Propiedades dinámicas de las clases deprecadas
&lt;/h2&gt;

&lt;p&gt;Otra característica importante de la versión 8.2, es que ya no podríamos crear propiedades dinámicas, al menos te generaría un "Warning Deprecated".&lt;/p&gt;

&lt;p&gt;En versiones futuras este "Warning Deprecated", se convertiría en error. Hasta el momento podemos realizar lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User 
{
   public string $name;
}


$user = new User();
$user-&amp;gt;last_name = 'Jhon Snow';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con la versión 8.2, si hacemos lo anterior arrojaría un warning, salvo que en nuestra clase usemos los "Magic Methods" "&lt;strong&gt;get" y "&lt;/strong&gt;set", ejemplo;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User
{
    private array $properties = [];

    public function __set(string $name, mixed $value): void
    {
        $this-&amp;gt;properties[$name] = $value;
    }
}

// …

$user-&amp;gt;last_name = 'Bruce Wayne';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Probando la versión 8.2 en Docker
&lt;/h2&gt;

&lt;p&gt;Si quieres probar las características de la nueva versión, el contenedor de PHP 8.2 se encuentra ya disponible en el Docker Hub, con esto ya no tendrás que instalar esta versión en tu equipo para hacer pruebas, puedes consultarlo en el siguiente link:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://hub.docker.com/_/php/tags"&gt;https://hub.docker.com/_/php/tags&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probamos nuestros ejemplos de esta publicación en el contenedor de Docker y este fue el resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aUPR7vd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igzxfi73q11s01v8k0nz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aUPR7vd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igzxfi73q11s01v8k0nz.png" alt="Read Only Classes" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QP8BXCnI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9adbdy34iaz6c3oqlaey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QP8BXCnI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9adbdy34iaz6c3oqlaey.png" alt="Deprecated Dynamic Properties 1" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4XJlkZRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2w5geard8eeso150k2am.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4XJlkZRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2w5geard8eeso150k2am.png" alt="Deprecated Dynamic Properties 1" width="721" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Y tu proyecto ya esta preparado para este cambio?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Pokedex: Utilizando Livewire para el front.</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Tue, 13 Sep 2022 00:09:48 +0000</pubDate>
      <link>https://forem.com/krsrk/pokedex-utilizando-livewire-para-el-front-4fjn</link>
      <guid>https://forem.com/krsrk/pokedex-utilizando-livewire-para-el-front-4fjn</guid>
      <description>&lt;p&gt;Ya que en previas publicaciones actualizamos el Pokedex a versiones mas actuales del stack de tecnologías de Laravel, ahora probaremos una herramienta que nos ayudará bastante a crear nuestras aplicaciones en el lado del front-end, en el caso, que no se desee aprender o no sabemos Javascript, pero si PHP.&lt;/p&gt;

&lt;p&gt;Esta herramienta es del mismo ecosistema de Laravel y se llama &lt;strong&gt;Livewire&lt;/strong&gt;. Su funcionalidad es controlar el front-end por medio de Blade y de PHP.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Puedes revisar la anterior publicación aquí: &lt;a href="https://dev.to/krsrk/pokedex-migracion-de-mix-a-vite-40ab"&gt;https://dev.to/krsrk/pokedex-migracion-de-mix-a-vite-40ab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Puedes saber más sobre Livewire aquí: &lt;a href="https://laravel-livewire.com/docs/2.x/quickstart"&gt;https://laravel-livewire.com/docs/2.x/quickstart&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuración e Instalación
&lt;/h2&gt;

&lt;p&gt;Para tener Livewire en nuestro proyecto, tenemos que instalar la librería de Livewire:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require livewire/livewire
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y en el caso que queramos configurar Livewire, ejecutamos este comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan livewire:publish --config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, modificaremos el archivo layout.blade, ya que debemos de agregar los recursos de Livewire y quitar los de Vite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  ...
  &amp;lt;!-- Styles --&amp;gt;
  &amp;lt;link rel="stylesheet" href="{{ asset('css/app.css') }}"&amp;gt;
  @livewireStyles
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt; 
  ...
  &amp;lt;div id="app"&amp;gt;
    ...
  &amp;lt;/div&amp;gt;
  @livewireScripts
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya con Livewire instalado y configurado en nuestro proyecto, el paso siguiente es la creación de componentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creación de componentes
&lt;/h2&gt;

&lt;p&gt;Los componentes como mencionamos anteriormente, están tratados por Blade y PHP. Cuando se crea un componente, se genera una clase en PHP con sus respectivos eventos y la vista del componente en Blade.&lt;/p&gt;

&lt;p&gt;Para crear un componente ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:livewire PokedexNav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto, nos generaría los siguientes archivos:&lt;/p&gt;

&lt;p&gt;Vista del componente livewire/pokedex-nav.blade.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="relative bg-red-600"&amp;gt;
    &amp;lt;div class="max-w-7xl mx-auto px-4 sm:px-6"&amp;gt;
        &amp;lt;div class="flex justify-between items-center border-b-1 border-gray-100 py-6 md:justify-start md:space-x-10"&amp;gt;
            &amp;lt;div class="lg:w-0 lg:flex-1 rounded-full text-white shadow-solid"&amp;gt;
                &amp;lt;a href="#" class="flex"&amp;gt;
                    &amp;lt;img class="h-12 w-12" src="https://upload.wikimedia.org/wikipedia/commons/5/53/Pok%C3%A9_Ball_icon.svg" alt="Workflow"&amp;gt;
                &amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="md:flex items-center justify-center space-x-8 md:flex-1 lg:w-0"&amp;gt;
                &amp;lt;h1 class="text-white text-3xl"&amp;gt;The Pokedex&amp;lt;/h1&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="md:flex items-center justify-center space-x-8 md:flex-1 lg:w-0"&amp;gt;
                &amp;amp;nbsp;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clase para programar eventos del componente, se encuentra en app/Http/Livewire/PokedexNav.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Livewire;

use Livewire\Component;

class PokedexNav extends Component
{
    public function render()
    {
        return view('livewire.pokedex-nav');
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no se requiere crear un archivo Blade por componente, simplemente creamos un &lt;strong&gt;Inline Component&lt;/strong&gt; de la siguiente manera:&lt;/p&gt;

&lt;p&gt;Se ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:livewire PokedexNav --inline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos generaría el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PokedexNav extends Component
{
    public function render()
    {
        return &amp;lt;&amp;lt;&amp;lt;'blade'
            &amp;lt;nav&amp;gt;...&amp;lt;/nav&amp;gt;
        blade;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como vemos, inyectaremos el código Html en el return del método render, esto sería algo similar a como lo hace React o Vue con JSX.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programando los componentes
&lt;/h2&gt;

&lt;p&gt;Así como en Vue se programan las propiedades, métodos, computed, etc, con Livewire se hace con clases en PHP, y la estructura es algo similar que con las tecnologías de Front antes mencionadas.&lt;/p&gt;

&lt;p&gt;Las propiedades del componente se definirán de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PokedexContent extends Component
{
    public $pokemons;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y esta propiedad la podemos usar en el componente Blade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="m-5 grid grid-cols-3 gap-4"&amp;gt;
        @foreach ($pokemons as $pokemon)
            ...
        @endforeach
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tiene la misma metodología como cuando pasamos variables a Blade desde el controller.&lt;/p&gt;

&lt;p&gt;Para definir un componente en la vista es con el tag "livewire:nombre-del-componente":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;livewire:the-items-data /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al igual que hacemos en Vue, podemos definir sus propiedades y pasarle valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;livewire:the-items-data :pokemon="$pokemon"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para hacer un propiedad reactiva como lo hacemos en Vue, tenemos que definirla de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
   wire:model="search"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, lo que escribamos en el "input" actualizará el valor de la propiedad "search".&lt;/p&gt;

&lt;p&gt;El wire:model tiene la propiedad de debounce, por defecto, lo hace cada 150 ms. Esto ocasiona un re render de la vista cada vez que se ejecuta algún evento relacionado con la propiedad reactiva. &lt;/p&gt;

&lt;p&gt;Para configurarlo hacemos lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
   wire:model.debounce.250ms="search"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Livewire, es una herramienta que trata de abarcar el "Full-Stack" en el ecosistema de Laravel. Como podrás observar, no necesitas ningún lenguaje extra (como Javascript para el front), ni mucho menos un compilador de assets (Como Laravel Mix o Vite). En si, el render de la vista es rápido ya que cuenta con la información al momento que se hace el request.&lt;/p&gt;

&lt;p&gt;Hasta el momento, hay muchos proyectos interesantes que se realizaron con esta herramienta; como paneles de administración, stacks de tecnología y componentes. &lt;br&gt;
Ha ido creciendo desde su lanzamiento, quizá en un futuro, ya se podrá adoptar esta tecnología como default en el stack de Laravel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pueden ver el crecimiento de Livewire y los proyectos en estos links: &lt;a href="https://trends.builtwith.com/framework/Laravel-Livewire"&gt;https://trends.builtwith.com/framework/Laravel-Livewire&lt;/a&gt; &lt;a href="https://www.libhunt.com/topic/livewire"&gt;https://www.libhunt.com/topic/livewire&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sin embargo, por el momento carece de características que otros frameworks en el front tienen, por ejemplo; en Vue o React, sería la reactividad, ya que en Livewire si la tiene pero no funciona como estamos acostumbrados en estos frameworks, y cada que se aplica se hace una llamada Ajax para re renderizar la vista en cualquier cambio de algún evento.&lt;/p&gt;

&lt;p&gt;un dato mas sobre la reactividad, es que no se puede aplicar de un componente hijo a un componente padre por medio de Props, y tampoco permite tener demasiada abstracción de niveles de componentes anidados.&lt;br&gt;
Por ende, tampoco tiene manejo de estados entre componentes como lo tiene Vue con Vuex y con Pinia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estas condiciones las podrás encontrar al inicio de su documentación de la sección "Nesting Components": &lt;a href="https://laravel-livewire.com/docs/2.x/nesting-components"&gt;https://laravel-livewire.com/docs/2.x/nesting-components&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora la mayor de las dudas, ¿Cómo puedo hacer que funcione Livewire en un entorno que este separado el Front del Back?, ¿Se tendría que usar el paquete Http de Laravel directo en algún método del componente, y hacer la llamada al api?, ¿Cómo afectaría el rendimiento el "re render" que hace cuando se actualiza el componente?.&lt;/p&gt;

&lt;p&gt;Todo esto, desde mi punto de vista, hace dudar si es bueno escoger a Livewire como herramienta por default para un proyecto real. Desconozco si en versiones posteriores lo vayan a mejorar,ahora ya es cuestión de un análisis "costo-beneficio" a la hora de usar esta herramienta en cualquier proyecto.&lt;/p&gt;

&lt;p&gt;Puedes revisar los cambios del código de este artículo en el siguiente enlace: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/krsrk/pokedex-laravel/tree/pokedex-livewire-version"&gt;https://github.com/krsrk/pokedex-laravel/tree/pokedex-livewire-version&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Pokedex: Migración de Mix a Vite</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Thu, 08 Sep 2022 17:48:27 +0000</pubDate>
      <link>https://forem.com/krsrk/pokedex-migracion-de-mix-a-vite-40ab</link>
      <guid>https://forem.com/krsrk/pokedex-migracion-de-mix-a-vite-40ab</guid>
      <description>&lt;p&gt;En la anterior publicación nos dimos a la tarea de actualizar la versión de &lt;strong&gt;"Vue"&lt;/strong&gt;(de Vue 2 a Vue 3).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Puedes ver la publicación aquí: &lt;a href="https://dev.to/krsrk/pokedex-actualizar-vue-de-la-version-2-a-la-3-58gj"&gt;https://dev.to/krsrk/pokedex-actualizar-vue-de-la-version-2-a-la-3-58gj&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora, requerimos actualizar la herramienta de compilación de los recursos de &lt;strong&gt;"Javascript"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Desde la versión 9.19 de Laravel cambio la herramienta para compilar los recursos de Javascript, dejando &lt;strong&gt;"Laravel Mix"&lt;/strong&gt; a un lado, e integrando &lt;strong&gt;"Vite"&lt;/strong&gt; como la herramienta oficial para esta tarea en Laravel. &lt;/p&gt;

&lt;p&gt;Las diferencias entre estas es que &lt;strong&gt;"Vite"&lt;/strong&gt; te da un entorno de desarrollo y compilación mas rápido que &lt;strong&gt;"Laravel Mix"&lt;/strong&gt; y &lt;strong&gt;"Webpack"&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aquí puedes obtener información sobre Vite:&lt;br&gt;
&lt;a href="https://vitejs.dev/guide/why.html"&gt;https://vitejs.dev/guide/why.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://laravel.com/docs/9.x/vite"&gt;https://laravel.com/docs/9.x/vite&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuración
&lt;/h2&gt;

&lt;p&gt;Para integrar Vite a un proyecto ya existente, solamente necesitamos instalar dos paquetes; para lograr esto debemos ejecutar lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev vite laravel-vite-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;También necesitaremos instalar el plugin de Vite para Vue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev @vitejs/plugin-vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creamos el archivo &lt;strong&gt;"vite.config.js"&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch vite.config.js &amp;amp;&amp;amp; nano vite.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo editamos con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
        vue()
    ],
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actualizamos el archivo &lt;strong&gt;"package.json"&lt;/strong&gt; en su sección de &lt;strong&gt;"scripts"&lt;/strong&gt; con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
        "dev": "vite",
        "build": "vite build"
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuración en código
&lt;/h2&gt;

&lt;p&gt;Otro requerimiento para que funcione correctamente &lt;strong&gt;"Vite"&lt;/strong&gt;, es quitar en el proyecto los "require y sustituirlos por "import". Además los archivos de los componentes en los "import" deben terminar con ".vue", Ejemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//bootstrap.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//app.js
import './bootstrap';

import PokedexNav from "./components/PokedexNav.vue";
import PokedexContent from "./components/PokedexContent.vue";
import PokedexFooter from "./components/PokedexFooter.vue";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, reemplazaremos &lt;strong&gt;"mix()"&lt;/strong&gt; o &lt;strong&gt;"asset()"&lt;/strong&gt; por &lt;strong&gt;"@vite"&lt;/strong&gt; en el &lt;strong&gt;"layout.blade"&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;

    &amp;lt;title&amp;gt;Pokedex&amp;lt;/title&amp;gt;

    &amp;lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" integrity="sha256-h20CPZ0QyXlBuAw7A+KluUYx/3pK+c7lYEpqLTlxjYQ=" crossorigin="anonymous" /&amp;gt;

    @vite(['resources/css/app.css', 'resources/js/app.js'])
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eliminamos Laravel Mix y su configuración:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm remove laravel-mix &amp;amp;&amp;amp; rm webpack.mix.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuramos Tailwind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss init -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configurar Sail
&lt;/h2&gt;

&lt;p&gt;Para que Vite se ejecute en el contenedor de Sail, necesitamos realizar unas configuraciones para que funcione la integración.&lt;/p&gt;

&lt;p&gt;Nos aseguramos que en el archivo &lt;strong&gt;"docker-compose.yml"&lt;/strong&gt; tenga esta línea en el servicio &lt;strong&gt;"laravel.test"&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abrimos el &lt;strong&gt;"vite.config.js"&lt;/strong&gt; y agregamos lo siguiente en la sección de &lt;strong&gt;"defineConfig"&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server: {
        host: '0.0.0.0',
        hmr: {
            host: 'localhost',
        },
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite por default tiene configurado un host, y asignándole dicha configuración va a convivir con el contenedor de Sail. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: La configuración &lt;strong&gt;"hmr"&lt;/strong&gt; sirve para cuando se usa WSL2 en Windows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Borramos caché y ejecutamos Vite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sailartisan optimize:clear &amp;amp;&amp;amp; sail npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y Voila!, ya tenemos corriendo el Pokedex con Vite y nuestros recursos de Javascript se compilan casi al instante. &lt;/p&gt;

&lt;p&gt;Otra de las ventaja de tener Vite en nuestro proyecto, es que el &lt;strong&gt;"hot reload"&lt;/strong&gt; lo hace casi instantáneo en cuanto guardas los cambios de algún archivo.&lt;/p&gt;

&lt;p&gt;Si quieres ver la diferencia de archivos para esta configuración lo puedes consultar aquí:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/krsrk/pokedex-laravel/pull/8"&gt;https://github.com/krsrk/pokedex-laravel/pull/8&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vite</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Pokedex: Actualizar Vue de la versión 2 a la 3</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Wed, 07 Sep 2022 01:07:35 +0000</pubDate>
      <link>https://forem.com/krsrk/pokedex-actualizar-vue-de-la-version-2-a-la-3-58gj</link>
      <guid>https://forem.com/krsrk/pokedex-actualizar-vue-de-la-version-2-a-la-3-58gj</guid>
      <description>&lt;p&gt;Anteriormente actualizamos la versión de Laravel de la 8.x a la 9.27, ahora toca el turno para actualizar la versión de Vue.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La publicación anterior la puedes consultar aquí:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/krsrk/pokedex-update-laravel-from-8x-to-9x-4018"&gt;https://dev.to/krsrk/pokedex-update-laravel-from-8x-to-9x-4018&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actualmente la versión 3 de Vue, viene con &lt;strong&gt;"composition API"&lt;/strong&gt;, la cual en términos generales, es una funcionalidad que hace que tu app de Vue2 no se rompa con lo nuevo del Vue3.&lt;/p&gt;

&lt;p&gt;Uno de los primeros cambios que podremos notar, será como se define la instancia de Vue.&lt;/p&gt;

&lt;p&gt;A continuación, actualizaremos a la versión 3, configurando lo básico.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración
&lt;/h2&gt;

&lt;p&gt;Inicialmente, debemos modificar el archivo &lt;strong&gt;"package.json"&lt;/strong&gt; con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"devDependencies": {
     "@vue/compiler-sfc": "^3.2.38",
     "axios": "^0.21.4",
     "css-loader": "^6.7.1",
     "laravel-mix": "^6.0.0-beta.17",
     "postcss": "^8.1.14",
     "resolve-url-loader": "^3.1.2",
     "sass": "^1.32.11",
     "sass-loader": "^11.0.1",
     "vue": "^3.2.36",
     "vue-loader": "^17.0.0"
},
"dependencies": {
     "tailwindcss": "^2.2.4",
     "vuex": "^4.0.0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos observar, actualizamos varias versiones de paquetes existentes, y agregamos otros paquetes que nos sirven para usar Vue 3. &lt;br&gt;
En el caso de Vue, actualizamos los paquetes de &lt;strong&gt;"vue"&lt;/strong&gt; y &lt;strong&gt;"vue-loader"&lt;/strong&gt;, quitamos &lt;strong&gt;"vue-template-compiler"&lt;/strong&gt;, agregamos &lt;strong&gt;"@vue/compiler-sfc"&lt;/strong&gt; y actualizamos &lt;strong&gt;"vuex"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Una vez que hemos realizado lo anteriormente descrito, borraremos los siguientes archivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;node_modules&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;public/css/app.css&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;public/js/app.js(todo lo que contenga esta carpeta)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez borrados los archivos tendremos que ejecutar lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si todo se realizó de forma correcta, ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuración de punto de entrada de Javascript
&lt;/h2&gt;

&lt;p&gt;Como se mencionó anteriromente, la creación de la instancia de Vue3 es un poco diferente a la versión anterior, por tal motivo tendremos que modificar el punto de entrada de la app.&lt;/p&gt;

&lt;p&gt;Para lograrlo, modificaremos el archivo &lt;strong&gt;resources/js/app.js&lt;/strong&gt; con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('./bootstrap');
import { createApp } from 'vue';
import store from './store/store';

import PokedexNav from "./components/PokedexNav.vue";
import PokedexContent from "./components/PokedexContent.vue";
import PokedexFooter from "./components/PokedexFooter.vue";

createApp({
    components: {
        'pokedex-nav': PokedexNav,
        'pokedex-content': PokedexContent,
        'pokedex-footer': PokedexFooter,
    }
}).use(store).mount('#app')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La diferencia consiste que antes usábamos &lt;strong&gt;"new Vue"&lt;/strong&gt; para crear nuestra app, en esta versión tenemos que usar el método &lt;strong&gt;"createApp"&lt;/strong&gt; de la versión 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modificación de los componentes
&lt;/h2&gt;

&lt;p&gt;Otro de los cambios en la versión 3 de Vue, es la definición de componentes, aunque en teoría no debe afectar si los dejamos así, vamos a modificar uno de ellos, para ver la diferencia.&lt;/p&gt;

&lt;p&gt;Modificamos el componente &lt;strong&gt;"PokedexNav"&lt;/strong&gt; con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
import { defineComponent } from 'vue';

export default defineComponent({
    name: "PokedexNav"
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usamos la función &lt;strong&gt;"defineComponent"&lt;/strong&gt; para configurar y programar nuestro componente, anteriormente simplemente lo exportábamos como un objeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modificación del Store
&lt;/h2&gt;

&lt;p&gt;La llamada al "store" definida por &lt;strong&gt;"Vuex"&lt;/strong&gt; también cambio, aquí antes inyectábamos la store definida global en el objeto del componente, ahora tendremos que usarla en el &lt;strong&gt;"setup"&lt;/strong&gt; del componente.&lt;/p&gt;

&lt;p&gt;Definimos nuestra store modificando el archivo "store.js"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createStore } from 'vuex';
import state from "./state"
import getters from "./getters"
import mutations from "./mutations"
import actions from "./actions"

const store = createStore({
    state,
    getters,
    mutations,
    actions,
})

export default store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usamos la función &lt;strong&gt;"createStore"&lt;/strong&gt; para definir y configurar nuestra "store". Previamente en "app.js" la habíamos configurado en la función de &lt;strong&gt;"createApp"&lt;/strong&gt; de nuestro punto de entrada.&lt;/p&gt;

&lt;p&gt;Ahora modificamos el componente "PokedexContent" con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
import { defineComponent, computed } from 'vue';
import { useStore } from 'vuex';

import TheItemData from "./TheItemData";
import TheSearchBox from "./TheSearchBox";

export default defineComponent({
    name: "PokedexContent",
    components: {
        'the-item-data': TheItemData,
        'the-search-box': TheSearchBox,
    },
    created() {
        this.$store.dispatch('getPokemonsData')
    },
    setup() {
        const store = useStore();
        let items = computed(function () {
            return store.state.pokemonsWithSearchFilter;
        });

        return {
            store,
            items,
        }
    }
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La "store" la definimos con la función "useStore" en "setup()", toda la configuración de la misma, fue definida en el archivo "app.js". Después definimos nuestra propiedad "computed"(otra función de "vue") y le pasamos el "state" del store a esta propiedad. &lt;/p&gt;

&lt;p&gt;Cabe destacar que aunque tenemos definido el store en el setup, todavía funciona la llamada al store de la versión 2 con "this.$store".&lt;/p&gt;

&lt;p&gt;Al terminar de realizar todo lo anteriormente descrito, ya podremos ejecutar nuestro Pokedex con Vue actualizado a la versión 3.&lt;/p&gt;

&lt;p&gt;Si deseas visualizar la diferencia de los archivos cuando se actualizó la versión de Vue, la puedes consultar en el siguiente PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/krsrk/pokedex-laravel/pull/7"&gt;https://github.com/krsrk/pokedex-laravel/pull/7&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pokedex: Actualizar Laravel de la versión 8.x a la 9.x</title>
      <dc:creator>Chris López</dc:creator>
      <pubDate>Mon, 05 Sep 2022 21:21:03 +0000</pubDate>
      <link>https://forem.com/krsrk/pokedex-update-laravel-from-8x-to-9x-4018</link>
      <guid>https://forem.com/krsrk/pokedex-update-laravel-from-8x-to-9x-4018</guid>
      <description>&lt;p&gt;Hace un año estuve realizando algunas publicaciones, las cuales hacen referencia a Laravel, en dichas publicaciones construimos un "Pokedex" desde 0.&lt;/p&gt;

&lt;p&gt;Estas publicaciones se pueden consultar en el siguiente enlace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chris-lopez.medium.com/the-pokedex-project-creando-un-pokedex-con-laravel-1-481a1df3b92a" rel="noopener noreferrer"&gt;Pokedex con Laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora que ha pasado este periodo de tiempo, me propuse a actualizar el proyecto, el cual contaba con la versión de &lt;strong&gt;Laravel 8.x&lt;/strong&gt;, por tal motivo, el requerimiento principal, será actualizar a la versión mas reciente. &lt;br&gt;
De igual forma, estarémos actualizando a la versión 8.1 de PHP. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cuando se escribió este articulo, la versión mas actual de Laravel es la 9.27 con versión mínima de PHP, que es la 8.0.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Prerrequisitos
&lt;/h2&gt;

&lt;p&gt;Para poder hacer esta actualización se debe tener instalado lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP 8.1&lt;/li&gt;
&lt;li&gt;Ubuntu 20.04 o WSL2 en Windows&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Primeros pasos
&lt;/h2&gt;

&lt;p&gt;Antes de continuar, les recomiendo que sigan la guía de instalación que tiene Laravel para cuando liberan las versiones, en este caso fue de 8 a 9, les dejo el link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://laravel.com/docs/9.x/upgrade" rel="noopener noreferrer"&gt;Upgrade Guide Laravel From 8.x to 9.x&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si actualmente no usas tantos paquetes, en esa guía simplemente van a llegar al paso que dice &lt;strong&gt;"Upgrade Dependencies"&lt;/strong&gt;, en caso contrario, les recomiendo una auditoría exhaustiva con los paquetes que usan y revisar los repositorios de los mismos, para ver si tienen versiones para Laravel 9 en este caso.&lt;/p&gt;
&lt;h2&gt;
  
  
  Instalación
&lt;/h2&gt;

&lt;p&gt;Siguiendo estas recomendaciones; el &lt;strong&gt;"Pokedex"&lt;/strong&gt; no usa paquetes externos, es un proyecto sencillo que nos da una inducción a Laravel, por lo cual vamos a codificar, y lo primero que vamos realizar es la modificación del archivo &lt;strong&gt;"composer.json"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sustituimos con lo siguiente en la sección de &lt;strong&gt;"require"&lt;/strong&gt; del archivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"require": {
        "php": "^8.0||^8.1",
        "fruitcake/laravel-cors": "^v2.0.5",
        "guzzlehttp/guzzle": "^7.5.0",
        "laravel/framework": "^v9.27.0",
        "laravel/tinker": "^v2.7.2",
        "laravel/ui": "^3.3"
    },

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si ponemos atención a la diferencia, solamente actualizamos versiones y quitamos un paquete llamado &lt;strong&gt;"fideloper/proxy"&lt;/strong&gt;, mas adelante sabremos porqué eliminamos esta librería.&lt;/p&gt;

&lt;p&gt;Ahora modificamos la sección de "require-dev":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"require-dev": {
        "spatie/laravel-ignition": "^1.4.0",
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^v6.2.1",
        "phpunit/phpunit": "^9.5.24"
    },

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En esta parte, actualizamos versiones y sustituimos el paquete &lt;strong&gt;"facade/ignition"&lt;/strong&gt; por &lt;strong&gt;"spatie/laravel-ignition"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Una vez modificado el archivo &lt;strong&gt;"composer.json"&lt;/strong&gt; borramos el archivo &lt;strong&gt;"composer.lock"&lt;/strong&gt;, ya que está ligado a la versión 8 y nos puede arrojar errores en la instalación si lo dejamos así.&lt;/p&gt;

&lt;p&gt;Después de borrar el archivo "composer.lock" ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instalamos las dependencias de Javascript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copiamos el archivo de configuración de Laravel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Probamos que sirva la configuración:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan key:generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test en browser de la instalación
&lt;/h2&gt;

&lt;p&gt;Aunque de cierta manera nos sirva el comando "artisan" después de configurar la versión de Laravel, tendremos que probar que todo nuestro Pokedex se ejecute sin errores en el browser.&lt;/p&gt;

&lt;p&gt;Para esto utilizaremos "Laravel Sail", la configuración como tal no la mencionaré aquí, ya que previamente en las publicaciones del "Pokedex" se mostro como se configura; solamente configuraremos el servicio de MariaDb.&lt;/p&gt;

&lt;p&gt;Pueden encontrar la publicación de Pokedex con Sail aquí:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chris-lopez.medium.com/the-pokedex-project-desplegando-nuestro-ambiente-de-desarrollo-con-laravel-sail-2-11d5445a8c23" rel="noopener noreferrer"&gt;The Pokedex Project — Desplegando nuestro ambiente de desarrollo con Laravel Sail(2)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez configurado, levantamos los servicios de Sail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sail up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;En este caso, se uso un alias para ejecutar el comando de Sail, recordemos que se encuentra en vendor/bin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probamos que los servicios se hayan levantado correctamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sail ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya con los servicios levantados, abrimos nuestro browser y ponemos el localhost que nos indica el comando anterior y nos arrojará un error:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibqatw8ojfwkpn6st459.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibqatw8ojfwkpn6st459.png" alt="Error: Paquete Fideloper Proxy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para la versión 9, dejaron de usar &lt;strong&gt;"fideloper/proxy"&lt;/strong&gt; y usaron una librería que ya viene en el core de Laravel, la cual se encuentra en &lt;strong&gt;"Illuminate/Http/Middleware/TrustProxies"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Entonces, para que ya no arroje dicho error, modificaremos el archivo &lt;strong&gt;TrustProxies.php&lt;/strong&gt;, el cual se encuentra en la carpeta de Middleware con lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Middleware;

use Illuminate\Http\Middleware\TrustProxies as Middleware;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Realizando estos cambios, probamos de nuevo en nuestro browser y tendremos el &lt;strong&gt;"Pokedex"&lt;/strong&gt; con la versión mas reciente de Laravel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr32bfpig6uj7nswry7dy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr32bfpig6uj7nswry7dy.png" alt="Pokedex con Laravel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los cambios que se realizaron en esta publicación, los puedes encontrar en el siguiente PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/krsrk/pokedex-laravel/pull/3" rel="noopener noreferrer"&gt;https://github.com/krsrk/pokedex-laravel/pull/3&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
