Comment créer une extension Magento PWA Studio

Publié: 2021-01-06

Table des matières

Normalement, vous voudriez apporter des modifications directement sur le projet pwa-studio , mais cette approche est cependant loin d'être idéale si vous souhaitez créer des extensions. Pour les extensions, vous voulez pouvoir les désactiver facilement ou pouvoir importer facilement plusieurs extensions dans un projet.

Pour ce faire, nous pouvons créer un package dans le projet créé et l'importer à partir du fichier JSON . Ce processus a heureusement été simplifié pour nous à l'aide d'un package npm publié par Lars Roettig, un responsable de Magento : https://www.npmjs.com/package/@larsroettig/create-pwa-extension

Dans ce tutoriel, nous allons essayer d'utiliser ce package pour créer une extension PWA Studio.

1. Installez Magento PWA Studio

Nous devons d'abord installer un projet PWA Studio. C'est assez facile si vous suivez notre guide ici : Comment configurer Magento 2 PWA Studio

*Remarque : à l'étape des questions, pour cette question " Installer les dépendances du package avec le fil après la création du projet ", vous devez sélectionner Non au lieu de Oui comme dans notre tutoriel d'installation.

2. Créer un nouvel itinéraire

cd dans votre répertoire de projet.

Exécutez cette commande :

 fil créer @larsroettig/pwa-extension

Il vous demandera plus d'informations concernant l'extension :

Encore une fois, n'oubliez pas de sélectionner Non à la question " Installer les dépendances du package avec du fil après la création du projet ".

Ouvrez le répertoire créé.

Ouvrir le répertoire créé

Nous pouvons maintenant voir que le fichier intercept.js a été créé et qu'il inclut déjà overridemapping .

Essayons maintenant de créer une nouvelle route dans testextension/src/intercept.js

 /**
 * Fichier d'interception personnalisé pour l'extension
 * Par défaut, vous ne pouvez utiliser que la cible de @magento/pwa-buildpack.
 *
 * Si vous voulez étendre @magento/peregrine ou @magento/venia-ui
 * vous devez les ajouter à peerDependencies dans votre package.json
 *
 * Si vous souhaitez ajouter des écrasements pour les composants @magento/venia-ui, vous pouvez utiliser
 * moduleOverrideWebpackPlugin et componentOverrideMapping
 **/
module.exports = cibles => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Nous avons besoin d'activer esModules et cssModules pour permettre au build pack de charger notre extension
         * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules : vrai, cssModules : vrai } ;
    });
    cibles.of('@magento/venia-ui').routes.tap(
        routesArray => {
            routesArray.push({
                nom : 'Page SimiCart',
                motif : '/simicart',
                chemin : '@simicart/testextension/src/components/page1'
            });

            return routesArray ;
        });
} ;

Créez un composant pour la nouvelle route dans testextension/src/components/page1/index.js :

 importer React depuis 'react' ;
importer {mergeClasses} de '@magento/venia-ui/lib/classify' ;
importer {forme, chaîne} à partir de 'prop-types' ;
 
importer les classes par défaut de './index.css' ;
 
const Page1 = props => {
    const classes = mergeClasses(defaultClasses, props.classes);
    return (<div className={classes.root}>SimiCart</div>);
}

Page1.propTypes = {
    classes : forme ({racine : chaîne})
} ;
Page1.defaultProps = {} ;
exporter la Page1 par défaut ;

Modifiez package.json pour importer le package :

Modifier package.json pour importer le package
 "dépendances": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "lien :./@simicart/testextension"
  },

Après quoi, installez et regardez pour vérifier si le nouvel itinéraire fonctionne.

 installation de fil
montre de fil

3. Remplacement des composants

Suite à la partie précédente, cette partie concernera le remplacement des vues existantes de votre projet.

A partir du projet créé à l'étape précédente, nous ajoutons notre override dans testextension/src/componentOverrideMapping.js :

 /**
 * Mappages pour les écrasements
 * exemple : [`@magento/venia-ui/lib/components/Main/main.js`] : './lib/components/Main/main.js'
 */
module.exports = componentOverride = {
    [`@magento/venia-ui/lib/components/Header/header.js`] : '@simicart/testextension/src/override/header.js'
} ;

Exigez ensuite ce code de remplacement dans require testextension/src/intercept.js :

 /**
 * Fichier d'interception personnalisé pour l'extension
 * Par défaut, vous ne pouvez utiliser que la cible de @magento/pwa-buildpack.
 *
 * Si vous voulez étendre @magento/peregrine ou @magento/venia-ui
 * vous devez les ajouter à peerDependencies dans votre package.json
 *
 * Si vous souhaitez ajouter des écrasements pour les composants @magento/venia-ui, vous pouvez utiliser
 * moduleOverrideWebpackPlugin et componentOverrideMapping
 */
const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin');
const componentOverrideMapping = require('./componentOverrideMapping')

module.exports = cibles => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Nous avons besoin d'activer esModules et cssModules pour permettre au build pack de charger notre extension
         * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules : vrai, cssModules : vrai } ;
    });

    console.log(targets.of('@magento/pwa-buildpack'));
    cibles.of('@magento/venia-ui').routes.tap(
        routesArray => {
            routesArray.push({
                nom : 'SimiCartPage',
                motif : '/simicart',
                chemin : '@simicart/testextension/src/components/page1'
            });

            return routesArray ;
        });
    target.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
        nouveau moduleOverrideWebpackPlugin(componentOverrideMapping).apply(compiler);
    })
} ;

Ensuite, à partir du dossier venia-ui , copiez le composant d'en- tête dans le nouveau composant que nous allons remplacer. Ajoutez ensuite une autre vue dans l'en-tête que nous venons de copier :

 importer SimiCartIcon depuis './simicartIcon' ;
.
.
.
<SimiCartIcon />

Code complet dans testextension/src/override/header.js :

 import React, { Suspense } from 'react' ;
importer { forme, chaîne } à partir de 'prop-types' ;

importer le logo de '@magento/venia-ui/lib/components/Logo' ;
import resourceUrl depuis '@magento/peregrine/lib/util/makeUrl' ;
import {Lien, Route} depuis 'react-router-dom' ;

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

import { mergeClasses } de '@magento/venia-ui/lib/classify' ;
importer les classes par défaut de '@magento/venia-ui/lib/components/Header/header.css' ;
importer PageLoadingIndicator depuis '@magento/venia-ui/lib/components/PageLoadingIndicator' ;
importer SimiCartIcon depuis './simicartIcon' ;

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

const En-tête = props => {
    const {
        handleSearchTriggerClick,
        a été hors ligne,
        est en ligne,
        rechercherOuvrir,
        isPageLoading
    } = useHeader();

    const classes = mergeClasses(defaultClasses, props.classes);
    const rootClass = searchOpen ? cours.ouvert : cours.fermé;
     const searchBarFallback = (
        <div className={classes.searchFallback}>
            <div className={classes.input}>
                <div className={classes.loader} />
            </div>
        </div>
    );
    const searchBar = searchOpen ? (
        <Suspense fallback={searchBarFallback}>
            <Itinéraire>
                <SearchBar isOpen={searchOpen} />
            </Route>
        </Suspense>
    ) : nul;
    const pageLoadingIndicator = isPageLoading ? (
        <IndicateurChargementPage />
    ) : nul;
 
    revenir (
        <header className={rootClass}>
            <div className={classes.toolbar}>
                <div className={classes.primaryActions}>
                    <NavTrigger />
                </div>
                {pageLoadingIndicator}
                <IndicateurEnLigne
                    hasBeenOffline={hasBeenOffline}
                    estEnLigne={estEnLigne}
                />
                <Lien vers={ressourceUrl('/')}>
                    <Logo classes={{ logo : classes.logo }} />
                </Lien>
                <div className={classes.secondaireActions}>
                    <Déclencheur de recherche
                        active={rechercheOuvrir}
                        onClick={handleSearchTriggerClick}
                    />
                    <AccountTrigger />
                    <SimiCartIcon />
                    <CartTrigger />
                </div>
            </div>
            {barre de recherche}
        </header>
    );
} ;

En-tête.propTypes = {
    classes : forme({
        fermé : chaîne,
        logo : chaîne,
        ouvert : chaîne,
        primaryActions : chaîne,
        SecondaryActions : chaîne,
        barre d'outils : chaîne
    })
} ;
 
exporter l'en-tête par défaut ;

Créons cette vue dans testextension/src/override/SimiCartIcon.js :

 importer React depuis 'react' ;
importer l'icône de '@magento/venia-ui/lib/components/Icon' ;
import { FastForward } de 'react-plume' ;
import resourceUrl depuis '@magento/peregrine/lib/util/makeUrl' ;
import { useHistory } de 'react-router-dom' ;
importer { forme, chaîne } à partir de 'prop-types' ;

importer les classes par défaut de './SimiCartIcon.css' ;
import { FormattedMessage, useIntl } de 'react-intl' ;

const SimiCartIcon = props => {
    classes constantes = classes par défaut ;
    const { formatMessage } = useIntl();
    const histoire = useHistory();

    revenir (
        <bouton
            aria-label={formatMessage({
                identifiant : `blog.bloglabel`,
                Message par défaut : 'Blog'
            })}
            nom_classe={classes.root}
            onClick={() => historique.push(urlressource('/simicart'))}
        >
            <Icon src={FastForward} />
            <span className={classes.label}>
                <Identifiant du message formaté={`Blog`} />
            </span>
        </bouton>
    );
}
 
SimiCartIcon.propTypes = {
    classes : forme ({ racine : chaîne })
} ;
SimiCartIcon.defaultProps = {} ;
exporter SimiCartIcon par défaut ;

Ensuite, coiffez-le :

 .racine {
    align-items : center ;
    curseur : pointeur ;
    affichage : flexible en ligne ;
    justifier-contenu : centrer ;
    hauteur de ligne : 1 ;
    événements de pointeur : auto ;
    aligner le texte : centrer ;
    espace blanc : nowrap ;
    propriété de transition : couleur ;
    durée de transition : 224 ms ;
    transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
    hauteur : 3rems ;
    largeur : 3 rems ;
}

.étiquette {
    affichage : aucun ;;
}

@media (largeur minimale : 641px) {
    .racine {
        largeur : automatique ;
    }
    .étiquette {
        affichage : initial ;
        marge-inline-start : 0,25 rem ;
    }
}

Le résultat:

Démo de l'extension personnalisée PWA Studio

Et cela conclut notre tutoriel. N'hésitez pas à nous poser toute question s'il y a une partie déroutante, et si vous pensez que ce tutoriel est utile, n'oubliez pas de le noter comme utile !

De plus, si vous avez envie d'essayer une extension Magento PWA Studio, nous avons des modules complémentaires gratuits et open-source que vous pouvez installer sur votre site Web Magento PWA Studio.

Constructeur de pages Magento PWA Studio

Lire la suite:

Magento PWA Studio : liens et ressources utiles