Jak stworzyć rozszerzenie Magento PWA Studio

Opublikowany: 2021-01-06

Spis treści

Normalnie chciałbyś wprowadzać zmiany bezpośrednio w projekcie pwa-studio , ale takie podejście jest dalekie od ideału, jeśli chcesz budować rozszerzenia. W przypadku rozszerzeń chcesz mieć możliwość łatwego ich wyłączania lub łatwego importowania wielu rozszerzeń do projektu.

W tym celu możemy stworzyć pakiet wewnątrz utworzonego projektu i zaimportować go z powrotem z pliku JSON . Ten proces na szczęście został dla nas uproszczony za pomocą pakietu npm wydanego przez Larsa Roettiga, opiekuna Magento: https://www.npmjs.com/package/@larsroettig/create-pwa-extension

W tym samouczku spróbujemy użyć tego pakietu do stworzenia rozszerzenia PWA Studio.

1. Zainstaluj Magento PWA Studio

Najpierw musimy zainstalować projekt PWA Studio. Jest to dość łatwe, jeśli zastosujesz się do naszego przewodnika tutaj: Jak skonfigurować Magento 2 PWA Studio

*Uwaga : w kroku z pytaniami, dla tego pytania „ Zainstaluj zależności pakietów z przędzą po utworzeniu projektu ” musisz wybrać Nie zamiast Tak, jak w naszym samouczku konfiguracji.

2. Utwórz nową trasę

cd do katalogu projektu.

Uruchom to polecenie:

 przędza create @larsroettig/pwa-extension

Poprosi o więcej informacji dotyczących rozszerzenia:

Ponownie pamiętaj, aby wybrać Nie przy pytaniu „ Zainstaluj zależności pakietów z przędzą po utworzeniu projektu ”.

Otwórz utworzony katalog.

Otwórz utworzony katalog

Widzimy teraz, że plik intercept.js został utworzony i zawiera już overridemapping .

Teraz spróbujmy stworzyć nową trasę w testextension/src/intercept.js

 /**
 * Niestandardowy plik przechwytywania dla rozszerzenia
 * Domyślnie możesz używać tylko celu @magento/pwa-buildpack.
 *
 * Jeśli chcesz rozszerzyć @magento/peregrine lub @magento/venia-ui
 * powinieneś dodać je do peerDependencies do swojego package.json
 *
 * Jeśli chcesz dodać nadpisy dla komponentów @magento/venia-ui, których możesz użyć
 * moduleOverrideWebpackPlugin i componentOverrideMapping
 **/
module.exports = cele => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flagi => {
        /**
         * Musimy aktywować moduły esModules i cssModules, aby pakiet kompilacji mógł załadować nasze rozszerzenie
         * {@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(
        tablica tras => {
            routeArray.push({
                nazwa: 'Strona SimiCart',
                wzór: '/simicart',
                ścieżka: '@simicart/testextension/src/components/page1'
            });

            trasy powrotneArray;
        });
};

Utwórz komponent dla nowej trasy w testextension/src/components/page1/index.js :

 importuj React z 'react';
importuj {mergeClasses} z '@magento/venia-ui/lib/classify';
importuj {kształt, ciąg} z 'typów prop';
 
importuj defaultClasses z './index.css';
 
const Strona1 = rekwizyty => {
    const class = mergeClasses(defaultClasses, props.classes);
    return (<div className={classes.root}>SimiCart</div>);
}

Strona1.propTypes = {
    klasy: kształt({root: string})
};
Strona1.defaultProps = {};
eksportuj domyślną stronę 1;

Zmodyfikuj plik package.json , aby zaimportować pakiet:

Zmodyfikuj plik package.json, aby zaimportować pakiet
 "zależności": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "link:./@simicart/testextension"
  },

Następnie zainstaluj i obserwuj, aby sprawdzić, czy nowa trasa działa.

 instalacja przędzy
zegarek z przędzy

3. Nadrzędne komponenty

Po poprzedniej części, ta część będzie dotyczyła nadpisywania istniejących widoków twojego projektu.

Z projektu utworzonego w poprzednim kroku dodajemy nasz override w testextension/src/componentOverrideMapping.js :

 /**
 * Mapowania do nadpisywania
 * przykład: [`@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'
};

Następnie require tego kodu zastępującego w testextension/src/intercept.js :

 /**
 * Niestandardowy plik przechwytywania dla rozszerzenia
 * Domyślnie możesz używać tylko celu @magento/pwa-buildpack.
 *
 * Jeśli chcesz rozszerzyć @magento/peregrine lub @magento/venia-ui
 * powinieneś dodać je do peerDependencies do swojego package.json
 *
 * Jeśli chcesz dodać nadpisy dla komponentów @magento/venia-ui, których możesz użyć
 * moduleOverrideWebpackPlugin i componentOverrideMapping
 */
const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin');
const componentOverrideMapping = require('./componentOverrideMapping')

module.exports = cele => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(flagi => {
        /**
         * Musimy aktywować moduły esModules i cssModules, aby pakiet kompilacji mógł załadować nasze rozszerzenie
         * {@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(
        tablica tras => {
            routeArray.push({
                nazwa: 'SimiCartPage',
                wzór: '/simicart',
                ścieżka: '@simicart/testextension/src/components/page1'
            });

            trasy powrotneArray;
        });
    target.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
        nowy moduleOverrideWebpackPlugin(componentOverrideMapping).apply(kompilator);
    })
};

Następnie z folderu venia-ui skopiuj komponent nagłówka do nowego komponentu, który będziemy nadpisywać. Następnie dodaj jeszcze jeden widok do nagłówka, który właśnie skopiowaliśmy:

 importuj SimiCartIcon z './simicartIcon';
.
.
.
<SimiCartIcon />

Pełny kod w testextension/src/override/header.js :

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

importuj logo z „@magento/venia-ui/lib/components/Logo”;
importuj resourceUrl z „@magento/peregrine/lib/util/makeUrl”;
importuj { Link, Route } z 'react-router-dom';

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

importuj { mergeClasses } z '@magento/venia-ui/lib/classify';
importuj defaultClasses z '@magento/venia-ui/lib/components/Header/header.css';
importuj wskaźnik PageLoadingIndicator z '@magento/venia-ui/lib/components/PageLoadingIndicator';
importuj SimiCartIcon z './simicartIcon';

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

const Nagłówek = rekwizyty => {
    stała {
        handleSearchTriggerClick,
        jest offline,
        jest online,
        szukajOtwórz,
        isPageLoading
    } = useHeader();

    const class = mergeClasses(defaultClasses, props.classes);
    const rootClass = searchOpen ? klasy.otwarte : klasy.zamknięte;
     const searchBarFallback = (
        <div className={classes.searchFallback}>
            <div className={classes.input}>
                <div className={classes.loader} />
            </div>
        </div>
    );
    const searchBar = searchOpen ? (
        <Suspense fallback={searchBarFallback}>
            <Trasa>
                <SearchBar isOpen={searchOpen} />
            </Trasa>
        </Napięcie>
    ) : zero;
    const pageLoadingIndicator = isPageLoading ? (
        <PageLoadingIndicator />
    ) : zero;
 
    zwrócić (
        <header className={rootClass}>
            <div className={classes.toolbar}>
                <div className={classes.primaryActions}>
                    <NavTrigger />
                </div>
                {pageLoadingIndicator}
                <Wskaźnik Online
                    hasBeenOffline={hasBeenOffline}
                    isOnline={isOnline}
                />
                <Link do={resourceUrl('/')}>
                    <Klasy logo={{ logo:klasy.logo }} />
                </Link>
                <div className={classes.secondaryActions}>
                    <Wyzwalacz wyszukiwania
                        active={wyszukiwanieOtwarte}
                        onClick={uchwytSearchTriggerClick}
                    />
                    <AccountTrigger />
                    <SimiCartIcon />
                    <CartTrigger />
                </div>
            </div>
            {pasek wyszukiwania}
        </header>
    );
};

Header.propTypes = {
    klasy: kształt({
        zamknięte: sznurek,
        logo: sznurek,
        otwarte: sznurek,
        primaryActions: ciąg,
        działania drugorzędne: ciąg,
        pasek narzędzi: ciąg
    })
};
 
eksportuj domyślny nagłówek;

Stwórzmy taki widok w testextension/src/override/SimiCartIcon.js :

 importuj React z 'react';
importuj ikonę z „@magento/venia-ui/lib/components/Icon”;
importuj { FastForward } z 'react-feather';
importuj resourceUrl z „@magento/peregrine/lib/util/makeUrl”;
importuj { useHistory } z 'react-router-dom';
importuj { shape, string } z 'prop-types';

importuj defaultClasses z './SimiCartIcon.css';
importuj { FormattedMessage, useIntl } z 'react-intl';

const SimiCartIcon = rekwizyty => {
    const class = defaultClasses;
    const { formatMessage } = useIntl();
    const history = useHistory();

    zwrócić (
        <przycisk
            aria-label={formatWiadomość({
                id: `blog.etykieta bloga`,
                domyślna wiadomość: „Blog”
            })}
            className={classes.root}
            onClick={() => history.push(resourceUrl('/simicart'))}
        >
            <Icon src={FastForward} />
            <span className={classes.label}>
                <FormattedMessage id={`Blog`} />
            </span>
        </button>
    );
}
 
SimiCartIcon.propTypes = {
    klasy: kształt({ root: string })
};
SimiCartIcon.defaultProps = {};
eksportuj domyślny SimiCartIcon;

Następnie stylizuj to:

 .źródło {
    wyrównaj-elementy: centrum;
    kursor: wskaźnik;
    wyświetlacz: wbudowany flex;
    uzasadnić-treść: centrum;
    wysokość linii: 1;
    zdarzenia wskaźnikowe: auto;
    wyrównanie tekstu: środek;
    spacja: nowrap;
    właściwość przejścia: kolor;
    czas trwania przejścia: 224ms;
    funkcja czasu przejścia: sześcienny-bezier (0, 0, 0,2, 1);
    wysokość: 3rem;
    szerokość: 3rem;
}

.etykieta {
    Nie wyświetla się;;
}

@media (minimalna szerokość: 641px) {
    .źródło {
        szerokość: auto;
    }
    .etykieta {
        wyświetlacz: początkowy;
        margines-inline-start: 0,25rem;
    }
}

Wynik:

Demo niestandardowego rozszerzenia PWA Studio

I to kończy nasz samouczek. Zadaj nam dowolne pytanie, jeśli jest jakaś myląca część, a jeśli uważasz, że ten samouczek jest pomocny, nie zapomnij ocenić go jako pomocny!

Dodatkowo, jeśli masz ochotę wypróbować rozszerzenie Magento PWA Studio, mamy darmowe i otwarte moduły dodatkowe, które możesz zainstalować na swojej stronie Magento PWA Studio.

Kreator stron Magento PWA Studio

Czytaj więcej:

Magento PWA Studio: Przydatne linki i zasoby