Como criar uma extensão Magento PWA Studio

Publicados: 2021-01-06

Índice

Normalmente, você deseja fazer alterações diretamente no projeto pwa-studio , mas essa abordagem está, no entanto, longe de ser ideal se você deseja criar extensões. Para extensões, você deseja desativá-las facilmente ou importar várias extensões em um projeto com facilidade.

Para isso, podemos criar um pacote dentro do projeto criado e importar de volta do arquivo JSON . Este processo foi, felizmente, simplificado para nós com a ajuda de um pacote npm lançado por Lars Roettig, um mantenedor do Magento: https://www.npmjs.com/package/@larsroettig/create-pwa-extension

Neste tutorial, tentaremos usar este pacote para criar uma extensão do PWA Studio.

1. Instale o Magento PWA Studio

Primeiro precisamos instalar um projeto PWA Studio. Isso é bastante fácil se você seguir nosso guia aqui: Como configurar o Magento 2 PWA Studio

*Observação : na etapa de perguntas, para esta pergunta “ Instalar dependências de pacotes com yarn após a criação do projeto ” você precisa selecionar Não em vez de Sim como em nosso tutorial de configuração.

2. Crie uma nova rota

cd em seu diretório de projeto.

Execute este comando:

 fios criam @larsroettig/pwa-extension

Ele solicitará mais informações sobre a extensão:

Novamente, lembre-se de selecionar Não na pergunta “ Instalar dependências do pacote com fio após criar o projeto ”.

Abra o diretório criado.

Abra o diretório criado

Agora podemos ver que o arquivo intercept.js foi criado e já inclui overridemapping .

Agora vamos tentar criar uma nova rota em testextension/src/intercept.js

 /**
 * Arquivo de interceptação personalizado para a extensão
 * Por padrão, você só pode usar o destino de @magento/pwa-buildpack.
 *
 * Se quiser estender @magento/peregrine ou @magento/venia-ui
 * você deve adicioná-los ao peerDependencies ao seu package.json
 *
 * Se você deseja adicionar substituições para componentes @magento/venia-ui, você pode usar
 * moduleOverrideWebpackPlugin e componentOverrideMapping
 **/
module.exports = destinos => {
    targets.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Precisamos ativar esModules e cssModules para permitir que o pacote de compilação carregue nossa extensão
         * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
         */
        flags[targets.name] = { esModules: true, cssModules: true };
    });
    targets.of('@magento/venia-ui').routes.tap(
        rotasArray => {
            rotasArray.push({
                nome: 'Página SimiCart',
                padrão: '/simicart',
                caminho: '@simicart/testextension/src/components/page1'
            });

            return rotasArray;
        });
};

Crie um componente para a nova rota em testextension/src/components/page1/index.js :

 importe React de 'react';
importe {mergeClasses} de '@magento/venia-ui/lib/classify';
import {forma, string} de 'prop-types';
 
importar defaultClasses de './index.css';
 
const Page1 = adereços => {
    classes const = mergeClasses(defaultClasses, props.classes);
    return (<div className={classes.root}>SimiCart</div>);
}

Page1.propTypes = {
    classes: forma({raiz: string})
};
Page1.defaultProps = {};
exportar a página1 padrão;

Modifique package.json para importar o pacote:

Modifique o package.json para importar o pacote
 "dependências": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "link:./@simicart/testextension"
  },

Depois disso, instale e assista para verificar se a nova rota está funcionando.

 instalação de fios
relógio de fio

3. Substituindo componentes

Seguindo a parte anterior, esta parte será sobre a substituição das visualizações existentes do seu projeto.

Do projeto criado na etapa anterior, adicionamos nossa substituição em testextension/src/componentOverrideMapping.js :

 /**
 * Mapeamentos para substituições
 * exemplo: [`@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'
};

Em seguida, require este código de substituição em testextension/src/intercept.js :

 /**
 * Arquivo de interceptação personalizado para a extensão
 * Por padrão, você só pode usar o destino de @magento/pwa-buildpack.
 *
 * Se quiser estender @magento/peregrine ou @magento/venia-ui
 * você deve adicioná-los ao peerDependencies ao seu package.json
 *
 * Se você deseja adicionar substituições para componentes @magento/venia-ui, você pode usar
 * moduleOverrideWebpackPlugin e componentOverrideMapping
 */
const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin');
const componentOverrideMapping = require('./componentOverrideMapping')

module.exports = destinos => {
    targets.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
        /**
         * Precisamos ativar esModules e cssModules para permitir que o pacote de compilação carregue nossa extensão
         * {@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'));
    targets.of('@magento/venia-ui').routes.tap(
        rotasArray => {
            rotasArray.push({
                nome: 'SimiCartPage',
                padrão: '/simicart',
                caminho: '@simicart/testextension/src/components/page1'
            });

            return rotasArray;
        });
    targets.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
        new moduleOverrideWebpackPlugin(componentOverrideMapping).apply(compilador);
    })
};

Em seguida, da pasta venia-ui , copie o componente de cabeçalho para o novo componente que substituiremos. Em seguida, adicione mais uma visualização ao cabeçalho que acabamos de copiar:

 importar SimiCartIcon de './simicartIcon';
.
.
.
<SimiCartIcon />

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

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

importe o logotipo de '@magento/venia-ui/lib/components/Logo';
import resourceUrl de '@magento/peregrine/lib/util/makeUrl';
import { Link, Route } from 'react-router-dom';

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

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

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

const Cabeçalho = adereços => {
    const {
        handleSearchTriggerClick,
        temEstadoOffline,
        está online,
        pesquisaAbrir,
        isPageLoading
    } = useCabeçalho();

    classes const = mergeClasses(defaultClasses, props.classes);
    const rootClass = searchOpen ? classes.open : classes.closed;
     const searchBarFallback = (
        <div className={classes.searchFallback}>
            <div className={classes.input}>
                <div className={classes.loader} />
            </div>
        </div>
    );
    const searchBar = searchOpen ? (
        <Suspense fallback={searchBarFallback}>
            <Rota>
                <SearchBar isOpen={searchOpen} />
            </Rota>
        </Suspense>
    ) : nulo;
    const pageLoadingIndicator = isPageLoading ? (
        <PageLoadingIndicator />
    ) : nulo;
 
    Retorna (
        <header className={rootClass}>
            <div className={classes.toolbar}>
                <div className={classes.primaryActions}>
                    <NavTrigger />
                </div>
                {pageLoadingIndicator}
                <Indicador Online
                    hasBeenOffline={hasBeenOffline}
                    isOnline={isOnline}
                />
                <Link to={resourceUrl('/')}>
                    <Logo classes={{ logo: classes.logo }} />
                </Link>
                <div className={classes.secondaryActions}>
                    <SearchTrigger
                        active={searchOpen}
                        onClick={handleSearchTriggerClick}
                    />
                    <AccountTrigger />
                    <SimiCartIcon />
                    <CartTrigger />
                </div>
            </div>
            {Barra de pesquisa}
        </header>
    );
};

Header.propTypes = {
    classes: forma({
        fechado: corda,
        logotipo: corda,
        aberto: corda,
        Ações primárias: string,
        Ações secundárias: string,
        barra de ferramentas: string
    })
};
 
exportar cabeçalho padrão;

Vamos criar esta visualização em testextension/src/override/SimiCartIcon.js :

 importe React de 'react';
importe o ícone de '@magento/venia-ui/lib/components/Icon';
import { FastForward } de 'react-feather';
import resourceUrl de '@magento/peregrine/lib/util/makeUrl';
import { useHistory } from 'react-router-dom';
import { shape, string } from 'prop-types';

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

const SimiCartIcon = adereços => {
    classes const = defaultClasses;
    const { formatMessage } = useIntl();
    const histórico = useHistória();

    Retorna (
        <botão
            aria-label={formatMessage({
                id: `blog.bloglabel`,
                mensagem padrão: 'Blog'
            })}
            className={classes.root}
            onClick={() => history.push(resourceUrl('/simicart'))}
        >
            <Icon src={FastForward} />
            <span className={classes.label}>
                <FormattedMessage id={`Blog`} />
            </span>
        </button>
    );
}
 
SimiCartIcon.propTypes = {
    classes: forma({ raiz: string })
};
SimiCartIcon.defaultProps = {};
exportar padrão SimiCartIcon;

Então estilize:

 .raiz {
    alinhar-itens: centro;
    cursor: ponteiro;
    exibição: inline-flex;
    justificar-conteúdo: centro;
    altura da linha: 1;
    eventos de ponteiro: auto;
    alinhamento de texto: centro;
    espaço em branco: nowrap;
    propriedade de transição: cor;
    duração da transição: 224ms;
    função de tempo de transição: cubic-bezier(0, 0, 0.2, 1);
    altura: 3rem;
    largura: 3rem;
}

.etiqueta {
    Mostrar nenhum;;
}

@media (largura mínima: 641px) {
    .raiz {
        largura: automático;
    }
    .etiqueta {
        exibição: inicial;
        margin-inline-start: 0.25rem;
    }
}

O resultado:

Demonstração da extensão personalizada do PWA Studio

E isso conclui nosso tutorial. Sinta-se à vontade para nos tirar qualquer dúvida se houver alguma parte confusa, e se você acha que este tutorial é útil, não se esqueça de classificá-lo como útil!

Além disso, se você quiser experimentar uma extensão do Magento PWA Studio, temos módulos complementares gratuitos e de código aberto que você pode instalar no site do Magento PWA Studio.

Construtor de Páginas Magento PWA Studio

Consulte Mais informação:

Magento PWA Studio: links e recursos úteis