Come creare un'estensione Magento PWA Studio

Pubblicato: 2021-01-06

Sommario

Normalmente, vorresti apportare modifiche direttamente al progetto pwa-studio , ma questo approccio è, tuttavia, tutt'altro che ideale se vuoi creare estensioni. Per le estensioni, vuoi essere in grado di disattivarle facilmente o essere in grado di importare più estensioni in un progetto con facilità.

Per fare ciò, possiamo creare un pacchetto all'interno del progetto creato e importarlo dal file JSON . Questo processo è stato, fortunatamente, semplificato per noi con l'aiuto di un pacchetto npm rilasciato da Lars Roettig, un manutentore di Magento: https://www.npmjs.com/package/@larsroettig/create-pwa-extension

In questo tutorial, proveremo a utilizzare questo pacchetto per creare un'estensione PWA Studio.

1. Installa Magento PWA Studio

Per prima cosa dobbiamo installare un progetto PWA Studio. Questo è abbastanza facile se segui la nostra guida qui: Come configurare Magento 2 PWA Studio

*Nota : al passaggio delle domande, per questa domanda " Installa le dipendenze del pacchetto con il filato dopo aver creato il progetto " devi selezionare No invece di Sì come nel nostro tutorial di installazione.

2. Crea un nuovo percorso

cd nella directory del tuo progetto.

Esegui questo comando:

 filato create @larsroettig/pwa-extension

Richiederà ulteriori informazioni sull'estensione:

Ancora una volta, ricorda di selezionare No alla domanda " Installa le dipendenze del pacchetto con il filato dopo aver creato il progetto ".

Apri la directory creata.

Apri la directory creata

Ora possiamo vedere che il file intercept.js è stato creato e include già overridemapping .

Ora proviamo a creare un nuovo percorso in testextension/src/intercept.js

 /**
 * File di intercettazione personalizzato per l'estensione
 * Per impostazione predefinita puoi utilizzare solo target di @magento/pwa-buildpack.
 *
 * Se vuoi estendere @magento/peregrine o @magento/venia-ui
 * dovresti aggiungerli a peerDependencies al tuo package.json
 *
 * Se vuoi aggiungere sovrascritture per i componenti @magento/venia-ui puoi usare
 * moduleOverrideWebpackPlugin e componentOverrideMapping
 **/
module.exports = destinazioni => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Abbiamo bisogno di attivare esModules e cssModules per consentire al build pack di caricare la nostra estensione
         * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules: true, cssModules: true };
    });
    target.of('@magento/venia-ui').routes.tap(
        rotteArray => {
            rotteArray.push({
                nome: 'Pagina SimiCart',
                modello: '/simicart',
                percorso: '@simicart/testextension/src/components/page1'
            });

            rotte di ritornoArray;
        });
};

Crea un componente per il nuovo percorso in testextension/src/components/page1/index.js :

 import React da 'react';
importa {mergeClasses} da '@magento/venia-ui/lib/classify';
import {shape, string} da 'prop-types';
 
importare defaultClasses da './index.css';
 
const Pagina1 = oggetti di scena => {
    classi const = mergeClasses(defaultClasses, props.classes);
    ritorno (<div className={classes.root}>SimiCart</div>);
}

Page1.propTypes = {
    classi: forma({radice: stringa})
};
Pagina1.defaultProps = {};
esportazione predefinita Pagina1;

Modifica package.json per importare il pacchetto:

Modifica package.json per importare il pacchetto
 "dipendenze": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "link:./@simicart/testextension"
  },

Dopodiché, installa e guarda per verificare se il nuovo percorso funziona.

 installazione del filato
orologio di filato

3. Componenti sostitutivi

Dopo la parte precedente, questa parte riguarderà l'override delle viste esistenti del tuo progetto.

Dal progetto creato nel passaggio precedente, aggiungiamo il nostro override in testextension/src/componentOverrideMapping.js :

 /**
 * Mappature per sovrascritture
 * esempio: [`@magento/venia-ui/lib/components/Main/main.js`]: './lib/components/Main/main.js'
 */
module.exports = componenteOverride = {
    [`@magento/venia-ui/lib/components/Header/header.js`]: '@simicart/testextension/src/override/header.js'
};

Quindi require questo codice di override in testextension/src/intercept.js :

 /**
 * File di intercettazione personalizzato per l'estensione
 * Per impostazione predefinita puoi utilizzare solo target di @magento/pwa-buildpack.
 *
 * Se vuoi estendere @magento/peregrine o @magento/venia-ui
 * dovresti aggiungerli a peerDependencies al tuo package.json
 *
 * Se vuoi aggiungere sovrascritture per i componenti @magento/venia-ui puoi usare
 * moduleOverrideWebpackPlugin e componentOverrideMapping
 */
const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin');
const componenteOverrideMapping = require('./componentOverrideMapping')

module.exports = destinazioni => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Abbiamo bisogno di attivare esModules e cssModules per consentire al build pack di caricare la nostra estensione
         * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules: true, cssModules: true };
    });

    console.log(targets.of('@magento/pwa-buildpack'));
    target.of('@magento/venia-ui').routes.tap(
        rotteArray => {
            rotteArray.push({
                nome: 'SimiCartPage',
                modello: '/simicart',
                percorso: '@simicart/testextension/src/components/page1'
            });

            rotte di ritornoArray;
        });
    target.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
        nuovo moduloOverrideWebpackPlugin(componentOverrideMapping).apply(compilatore);
    })
};

Quindi, dalla cartella venia-ui , copia il componente di intestazione nel nuovo componente che sovrascriveremo. Quindi aggiungi un'altra vista nell'intestazione che abbiamo appena copiato:

 importa SimiCartIcon da './simicartIcon';
.
.
.
<IconaSimiCart/>

Codice completo in testextension/src/override/header.js :

 import React, {Suspense} da 'react';
import { shape, string } da 'prop-types';

import Logo da '@magento/venia-ui/lib/components/Logo';
import ResourceUrl da '@magento/peregrine/lib/util/makeUrl';
import {Link, Route } da 'react-router-dom';

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

import {mergeClasses} da '@magento/venia-ui/lib/classify';
import defaultClasses da '@magento/venia-ui/lib/components/Header/header.css';
import PageLoadingIndicator da '@magento/venia-ui/lib/components/PageLoadingIndicator';
importa SimiCartIcon da './simicartIcon';

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

const Header = props => {
    cost {
        handleSearchTriggerClick,
        è stato offline,
        è in linea,
        cercaApri,
        isPageLoading
    } = useHeader();

    classi const = mergeClasses(defaultClasses, props.classes);
    const rootClass = searchOpen ? classi.aperte : classi.chiuse;
     const searchBarFallback = (
        <div className={classes.searchFallback}>
            <div nomeclasse={classi.input}>
                <div className={classes.loader} />
            </div>
        </div>
    );
    const searchBar = searchOpen ? (
        <Suspense fallback={searchBarFallback}>
            <Percorso>
                <SearchBar isOpen={searchOpen} />
            </Rotta>
        </Suspense>
    ) : nullo;
    const pageLoadingIndicator = isPageLoading ? (
        <PageLoadingIndicator />
    ) : nullo;
 
    Restituzione (
        <header className={rootClass}>
            <div className={classes.toolbar}>
                <div className={classes.primaryActions}>
                    <NavTrigger />
                </div>
                {pageLoadingIndicator}
                <Indicatore in linea
                    hasBeenOffline={hasBeenOffline}
                    isOnline={isOnline}
                />
                <Link a={resourceUrl('/')}>
                    <Logo classi={{ logo: classi.logo }} />
                </Link>
                <div className={classes.secondaryActions}>
                    <SearchTrigger
                        attivo={cercaOpen}
                        onClick={handleSearchTriggerClick}
                    />
                    <AccountTrigger />
                    <IconaSimiCart/>
                    <CartTrigger />
                </div>
            </div>
            {barra di ricerca}
        </intestazione>
    );
};

Header.propTypes = {
    classi: forma({
        chiuso: stringa,
        logo: stringa,
        aperto: stringa,
        primaryActions: stringa,
        secondaryActions: stringa,
        barra degli strumenti: stringa
    })
};
 
esporta intestazione predefinita;

Creiamo questa vista in testextension/src/override/SimiCartIcon.js :

 import React da 'react';
import Icon da '@magento/venia-ui/lib/components/Icon';
import { FastForward } da 'react-feather';
import ResourceUrl da '@magento/peregrine/lib/util/makeUrl';
import {useHistory} da 'react-router-dom';
import { shape, string } da 'prop-types';

import defaultClasses da './SimiCartIcon.css';
import { FormattedMessage, useIntl } da 'react-intl';

const SimiCartIcon = oggetti di scena => {
    const classi = defaultClasses;
    const { formatMessage } = useIntl();
    const history = useHistory();

    Restituzione (
        <pulsante
            etichetta-aria={formatMessage({
                id: `blog.bloglabel`,
                messaggio predefinito: 'Blog'
            })}
            nomeclasse={classi.root}
            onClick={() => history.push(resourceUrl('/simicart'))}
        >
            <Icon src={FastForward} />
            <span className={classes.label}>
                <FormattedMessage id={`Blog`} />
            </span>
        </pulsante>
    );
}
 
SimiCartIcon.propTypes = {
    classi: forma ({ radice: stringa })
};
SimiCartIcon.defaultProps = {};
esportazione SimiCartIcon predefinita;

Quindi modellalo:

 .radice {
    allineare-elementi: centro;
    cursore: puntatore;
    display: inline-flex;
    giustificare-contenuto: centro;
    altezza della linea: 1;
    eventi-puntatore: auto;
    allineamento testo: centro;
    spazio bianco: nowrap;
    proprietà di transizione: colore;
    durata della transizione: 224 ms;
    funzione di temporizzazione di transizione: cubic-bezier(0, 0, 0.2, 1);
    altezza: 3rem;
    larghezza: 3 rem;
}

.etichetta {
    display: nessuno;;
}

@media (larghezza minima: 641px) {
    .radice {
        larghezza: automatica;
    }
    .etichetta {
        display: iniziale;
        margin-inline-start: 0.25rem;
    }
}

Il risultato:

Demo dell'estensione personalizzata di PWA Studio

E questo conclude il nostro tutorial. Sentiti libero di farci qualsiasi domanda se c'è qualche parte confusa e se pensi che questo tutorial sia utile, non dimenticare di valutarlo come utile!

Inoltre, se hai voglia di provare un'estensione Magento PWA Studio, abbiamo moduli aggiuntivi gratuiti e open source che puoi installare sul tuo sito Web Magento PWA Studio.

Generatore di pagine di Magento PWA Studio

Leggi di più:

Magento PWA Studio: link e risorse utili