Cómo crear una extensión Magento PWA Studio

Publicado: 2021-01-06

Tabla de contenido

Normalmente, desearía realizar cambios directamente en el proyecto pwa-studio , pero este enfoque, sin embargo, está lejos de ser ideal si desea crear extensiones. Para las extensiones, desea poder deshabilitarlas fácilmente o poder importar múltiples extensiones en un proyecto con facilidad.

Para hacerlo, podemos crear un paquete dentro del proyecto creado e importarlo desde el archivo JSON . Afortunadamente, este proceso se simplificó para nosotros con la ayuda de un paquete npm lanzado por Lars Roettig, un mantenedor de Magento: https://www.npmjs.com/package/@larsroettig/create-pwa-extension

En este tutorial, intentaremos usar este paquete para crear una extensión de PWA Studio.

1. Instale Magento PWA Studio

Primero necesitamos instalar un proyecto de PWA Studio. Esto es bastante fácil si sigue nuestra guía aquí: Cómo configurar Magento 2 PWA Studio

* Nota : en el paso de preguntas, para esta pregunta " Instalar dependencias de paquetes con hilo después de crear el proyecto " debe seleccionar No en lugar de Sí como en nuestro tutorial de configuración.

2. Crea una nueva ruta

cd en el directorio de su proyecto.

Ejecute este comando:

 hilo crear @larsroettig/pwa-extension

Te pedirá más información sobre la extensión:

Nuevamente, recuerde seleccionar No en la pregunta " Instalar dependencias de paquetes con hilo después de crear el proyecto ".

Abra el directorio creado.

Abre el directorio creado.

Ahora podemos ver que se ha creado el archivo intercept.js y que ya incluye overridemapping .

Ahora intentemos crear una nueva ruta en testextension/src/intercept.js

 /**
 * Archivo de intercepción personalizado para la extensión
 * De forma predeterminada, solo puede usar el destino de @magento/pwa-buildpack.
 *
 * Si desea extender @magento/peregrine o @magento/venia-ui
 * debe agregarlos a peerDependencies a su paquete.json
 *
 * Si desea agregar sobrescrituras para los componentes @magento/venia-ui, puede usar
 * móduloOverrideWebpackPlugin y componenteOverrideMapping
 **/
módulo.exportaciones = objetivos => {
    objetivos.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Necesitamos activar esModules y cssModules para permitir que el paquete de compilación cargue nuestra extensión
         * {@enlace https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules: true, cssModules: true };
    });
    objetivos.of('@magento/venia-ui').routes.tap(
        rutasArray => {
            rutasArray.push({
                nombre: 'Página de SimiCart',
                patrón: '/simicart',
                ruta: '@simicart/testextension/src/components/page1'
            });

            volver rutasArray;
        });
};

Cree un componente para la nueva ruta en testextension/src/components/page1/index.js :

 importar React desde 'react';
importar {mergeClasses} desde '@magento/venia-ui/lib/classify';
importar {forma, cadena} de 'prop-types';
 
importar clases predeterminadas desde './index.css';
 
const Página1 = apoyos => {
    const clases = mergeClasses(defaultClasses, props.classes);
    return (<div className={classes.root}>SimiCart</div>);
}

Página1.propTypes = {
    clases: forma ({raíz: cadena})
};
Página1.propiedades predeterminadas = {};
exportar página predeterminada 1;

Modifique package.json para importar el paquete:

Modificar package.json para importar paquete
 "dependencias": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "enlace:./@simicart/testextension"
  },

Después de lo cual, instale y observe para verificar si la nueva ruta funciona.

 instalación de hilo
reloj de hilo

3. Componentes anulados

Siguiendo la parte anterior, esta parte tratará de anular las vistas existentes de su proyecto.

Desde el proyecto creado en el paso anterior, agregamos nuestra anulación en testextension/src/componentOverrideMapping.js :

 /**
 * Asignaciones para sobrescrituras
 * ejemplo: [`@magento/venia-ui/lib/components/Main/main.js`]: './lib/components/Main/main.js'
 */
módulo.exportaciones = componenteOverride = {
    [`@magento/venia-ui/lib/components/Header/header.js`]: '@simicart/testextension/src/override/header.js'
};

Luego require este código de anulación en testextension/src/intercept.js :

 /**
 * Archivo de intercepción personalizado para la extensión
 * De forma predeterminada, solo puede usar el destino de @magento/pwa-buildpack.
 *
 * Si desea extender @magento/peregrine o @magento/venia-ui
 * debe agregarlos a peerDependencies a su paquete.json
 *
 * Si desea agregar sobrescrituras para los componentes @magento/venia-ui, puede usar
 * móduloOverrideWebpackPlugin y componenteOverrideMapping
 */
const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin');
const componenteOverrideMapping = require('./componentOverrideMapping')

módulo.exportaciones = objetivos => {
    objetivos.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Necesitamos activar esModules y cssModules para permitir que el paquete de compilación cargue nuestra extensión
         * {@enlace https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules: true, cssModules: true };
    });

    console.log(objetivos.of('@magento/pwa-buildpack'));
    objetivos.of('@magento/venia-ui').routes.tap(
        rutasArray => {
            rutasArray.push({
                nombre: 'SimiCartPage',
                patrón: '/simicart',
                ruta: '@simicart/testextension/src/components/page1'
            });

            volver rutasArray;
        });
    objetivos.of('@magento/pwa-buildpack').webpackCompiler.tap(compilador => {
        nuevo moduleOverrideWebpackPlugin(componentOverrideMapping).apply(compilador);
    })
};

Luego, desde la carpeta venia-ui , copie el componente de encabezado en el nuevo componente que anularemos. Luego agregue una vista más en el encabezado que acabamos de copiar:

 importar SimiCartIcon desde './simicartIcon';
.
.
.
<Icono de SimiCart />

Código completo en testextension/src/override/header.js :

 importar Reaccionar, { Suspenso } de 'reaccionar';
importar {forma, cadena} de 'prop-types';

importar logotipo desde '@magento/venia-ui/lib/components/Logo';
importar resourceUrl desde '@magento/peregrine/lib/util/makeUrl';
importar {Enlace, Ruta} desde 'react-router-dom';

importar AccountTrigger desde '@magento/venia-ui/lib/components/Header/accountTrigger';
importar CartTrigger desde '@magento/venia-ui/lib/components/Header/cartTrigger';
importar NavTrigger desde '@magento/venia-ui/lib/components/Header/navTrigger';
importar SearchTrigger desde '@magento/venia-ui/lib/components/Header/searchTrigger';
importar OnlineIndicator desde '@magento/venia-ui/lib/components/Header/onlineIndicator';
importar { useHeader } desde '@magento/peregrine/lib/talons/Header/useHeader';

importar {mergeClasses} desde '@magento/venia-ui/lib/classify';
importar clases predeterminadas desde '@magento/venia-ui/lib/components/Header/header.css';
importar PageLoadingIndicator desde '@magento/venia-ui/lib/components/PageLoadingIndicator';
importar SimiCartIcon desde './simicartIcon';

const SearchBar = React.lazy(() => import('@magento/venia-ui/lib/components/SearchBar'));

const Encabezado = accesorios => {
    constante {
        manejarSearchTriggerClick,
        ha estado fuera de línea,
        está en linea,
        buscarAbrir,
        esPageLoading
    } = usarEncabezado();

    const clases = mergeClasses(defaultClasses, props.classes);
    const rootClass = searchOpen ? clases.abiertas : clases.cerradas;
     const searchBarFallback = (
        <div className={classes.searchFallback}>
            <div className={clases.input}>
                <div className={clases.loader} />
            </div>
        </div>
    );
    const searchBar = searchOpen ? (
        <Suspense fallback={searchBarFallback}>
            <Ruta>
                <La barra de búsqueda está abierta={búsqueda abierta} />
            </Ruta>
        </suspenso>
    ) : nulo;
    const pageLoadingIndicator = isPageLoading ? (
        <Indicador de carga de página />
    ) : nulo;
 
    devolver (
        <nombre de clase de encabezado = {clase raíz}>
            <div className={clases.barra de herramientas}>
                <div className={classes.primaryActions}>
                    <Disparador de navegación />
                </div>
                {indicador de carga de página}
                <Indicador en línea
                    hasBeenOffline={hasBeenOffline}
                    está en línea = {está en línea}
                />
                <Enlace a={resourceUrl('/')}>
                    <Clases de logotipo={{ logotipo: clases.logo }} />
                </enlace>
                <div className={clases.secundariasAcciones}>
                    <Desencadenador de búsqueda
                        active={buscarAbrir}
                        onClick={handleSearchTriggerClick}
                    />
                    <Disparador de cuenta />
                    <Icono de SimiCart />
                    <Activador de carro />
                </div>
            </div>
            {barra de búsqueda}
        </encabezado>
    );
};

Encabezado.propTypes = {
    clases: forma ({
        cerrado: cadena,
        logotipo: cadena,
        abierto: cadena,
        Acciones primarias: cadena,
        acciones secundarias: cadena,
        barra de herramientas: cadena
    })
};
 
exportar encabezado predeterminado;

Vamos a crear esta vista en testextension/src/override/SimiCartIcon.js :

 importar React desde 'react';
importar icono desde '@magento/venia-ui/lib/components/Icon';
importar { FastForward } desde 'react-feather';
importar resourceUrl desde '@magento/peregrine/lib/util/makeUrl';
importar { useHistory } desde 'react-router-dom';
importar {forma, cadena} de 'prop-types';

importar clases predeterminadas desde './SimiCartIcon.css';
import { FormattedMessage, useIntl } from 'react-intl';

const SimiCartIcon = props => {
    const clases = clases por defecto;
    const {formatoMensaje} = useIntl();
    const historial = useHistory();

    devolver (
        <botón
            aria-label={formatoMensaje({
                id: `blog.bloglabel`,
                mensaje predeterminado: 'Blog'
            })}
            className={clases.raíz}
            onClick={() => historial.push(resourceUrl('/simicart'))}
        >
            <Icono src={Avance rápido} />
            <span className={clases.etiqueta}>
                <Id. de mensaje formateado={`Blog`} />
            </span>
        </botón>
    );
}
 
SimiCartIcon.propTypes = {
    clases: forma ({raíz: cadena})
};
SimiCartIcon.defaultProps = {};
exportar SimiCartIcon predeterminado;

Luego dale estilo:

 .raíz {
    alinear elementos: centro;
    cursor: puntero;
    pantalla: en línea-flexible;
    justificar-contenido: centro;
    altura de línea: 1;
    puntero-eventos: auto;
    alineación de texto: centro;
    espacios en blanco: nowrap;
    propiedad de transición: color;
    transición-duración: 224ms;
    función de temporización de transición: cubic-bezier (0, 0, 0.2, 1);
    altura: 3 rem;
    ancho: 3 rem;
}

.etiqueta {
    pantalla: ninguna;;
}

@media (ancho mínimo: 641 px) {
    .raíz {
        ancho: automático;
    }
    .etiqueta {
        pantalla: inicial;
        margen-inicio-inicio: 0,25 rem;
    }
}

El resultado:

Demostración de extensión personalizada de PWA Studio

Y eso concluye nuestro tutorial. No dude en enviarnos cualquier pregunta si hay alguna parte confusa, y si cree que este tutorial es útil, ¡no olvide calificarlo como útil!

Además, si tiene ganas de probar una extensión de Magento PWA Studio, tenemos módulos complementarios gratuitos y de código abierto que puede instalar en la parte superior de su sitio web de Magento PWA Studio.

Generador de páginas Magento PWA Studio

Lee mas:

Magento PWA Studio: enlaces y recursos útiles