Magento PWA Studio 확장을 만드는 방법

게시 됨: 2021-01-06

목차

일반적으로 pwa-studio 프로젝트에서 직접 변경하고 싶지만 이 접근 방식은 확장을 구축하려는 경우 이상적이지 않습니다. 확장의 경우 쉽게 비활성화하거나 여러 확장을 프로젝트로 쉽게 가져올 수 있기를 원합니다.

그렇게 하려면 생성된 프로젝트 내부에 패키지를 만들고 JSON 파일에서 다시 가져올 수 있습니다. 다행히 이 프로세스는 Magento 유지 관리자인 Lars Roettig가 릴리스한 npm 패키지의 도움으로 간소화되었습니다. https://www.npmjs.com/package/@larsroettig/create-pwa-extension

이 자습서에서는 이 패키지를 사용하여 PWA Studio 확장을 만들려고 합니다.

1. 마젠토 PWA 스튜디오 설치

먼저 PWA Studio 프로젝트를 설치해야 합니다. 여기에서 가이드를 따르면 매우 쉽습니다. Magento 2 PWA Studio 설정 방법

*참고 : 질문 단계에서 " 프로젝트 생성 후 원사로 패키지 종속성 설치 " 질문에 대해 설정 자습서에서와 같이 예 대신 아니오 를 선택해야 합니다.

2. 새 경로 생성

cd 를 프로젝트 디렉토리에 넣습니다.

다음 명령을 실행합니다.

 원사 생성 @larsroettig/pwa-extension

확장 프로그램에 대한 추가 정보를 요청합니다.

다시 말하지만 " 프로젝트 생성 후 실을 사용하여 패키지 종속성 설치 " 질문에서 아니요 를 선택하는 것을 잊지 마십시오.

생성된 디렉토리를 엽니다.

생성된 디렉토리 열기

이제 intercept.js 파일이 생성되었으며 이미 overridemapping 이 포함되어 있음을 알 수 있습니다.

이제 testextension/src/intercept.js 에 새 경로를 생성해 보겠습니다.

 /**
 * 확장에 대한 사용자 정의 가로채기 파일
 * 기본적으로 @magento/pwa-buildpack의 대상만 사용할 수 있습니다.
 *
 * @magento/peregrine 또는 @magento/venia-ui를 확장하려는 경우
 * package.json의 peerDependencies에 추가해야 합니다.
 *
 * @magento/venia-ui 구성 요소에 덮어쓰기를 추가하려면 다음을 사용할 수 있습니다.
 * moduleOverrideWebpackPlugin 및 componentOverrideMapping
 **/
module.exports = 대상 => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(플래그 => {
        /**
         * 빌드 팩이 확장을 로드할 수 있도록 esModules 및 cssModules를 활성화해야 합니다.
         * {@링크 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(
        경로 배열 => {
            routeArray.push({
                이름: 'SimiCart 페이지',
                패턴: '/simicart',
                경로: '@simicart/testextension/src/components/page1'
            });

            반환 경로 배열;
        });
};

testextension/src/components/page1/index.js 에 새 경로에 대한 구성 요소를 만듭니다.

 '반응'에서 React 가져오기;
'@magento/venia-ui/lib/classify'에서 {mergeClasses} 가져오기;
'소품 유형'에서 {모양, 문자열} 가져오기;
 
'./index.css'에서 defaultClass를 가져옵니다.
 
const 페이지1 = 소품 => {
    const 클래스 = mergeClasses(defaultClasses, props.classes);
    반환(<div className={classes.root}>SimiCart</div>);
}

Page1.propTypes = {
    클래스: 모양({루트: 문자열})
};
Page1.defaultProps = {};
기본 Page1 내보내기;

패키지를 가져오도록 package.json 을 수정합니다.

패키지를 가져오도록 package.json 수정
 "종속성": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@simicart/testextension": "링크:./@simicart/testextension"
  },

그런 다음 설치하고 새 경로가 작동하는지 확인하십시오.

 원사 설치
원사 시계

3. 구성 요소 재정의

이전 부분에 이어 이 부분은 프로젝트의 기존 보기를 재정의하는 방법에 대해 설명합니다.

이전 단계에서 생성된 프로젝트에서 testextension/src/componentOverrideMapping.js 에 재정의를 추가합니다.

 /**
 * 덮어쓰기를 위한 매핑
 * 예: [`@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'
};

그런 다음 이 재정의 코드를 testextension/src/intercept.jsrequire 합니다.

 /**
 * 확장에 대한 사용자 정의 가로채기 파일
 * 기본적으로 @magento/pwa-buildpack의 대상만 사용할 수 있습니다.
 *
 * @magento/peregrine 또는 @magento/venia-ui를 확장하려는 경우
 * package.json의 peerDependencies에 추가해야 합니다.
 *
 * @magento/venia-ui 구성 요소에 덮어쓰기를 추가하려면 다음을 사용할 수 있습니다.
 * moduleOverrideWebpackPlugin 및 componentOverrideMapping
 */
const moduleOverrideWebpackPlugin = 요구('./moduleOverrideWebpackPlugin');
const componentOverrideMapping = require('./componentOverrideMapping')

module.exports = 대상 => {
    target.of('@magento/pwa-buildpack').specialFeatures.tap(플래그 => {
        /**
         * 빌드 팩이 확장을 로드할 수 있도록 esModules 및 cssModules를 활성화해야 합니다.
         * {@링크 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(
        경로 배열 => {
            routeArray.push({
                이름: 'SimiCartPage',
                패턴: '/simicart',
                경로: '@simicart/testextension/src/components/page1'
            });

            반환 경로 배열;
        });
    target.of('@magento/pwa-buildpack').webpackCompiler.tap(컴파일러 => {
        새로운 moduleOverrideWebpackPlugin(componentOverrideMapping).apply(컴파일러);
    })
};

그런 다음 venia-ui 폴더에서 헤더 구성 요소를 재정의할 새 구성 요소로 복사합니다. 그런 다음 방금 복사한 헤더에 보기를 하나 더 추가합니다.

 './simicartIcon'에서 SimiCartIcon 가져오기;
.
.
.
<시미카트 아이콘 />

testextension/src/override/header.js 의 전체 코드:

 import React, { Suspense } from 'react';
'소품 유형'에서 { 모양, 문자열 } 가져오기;

'@magento/venia-ui/lib/components/Logo'에서 로고 가져오기;
'@magento/peregrine/lib/util/makeUrl'에서 resourceUrl 가져오기;
'react-router-dom'에서 { 링크, 경로 } 가져오기;

'@magento/venia-ui/lib/components/Header/accountTrigger'에서 AccountTrigger를 가져옵니다.
'@magento/venia-ui/lib/components/Header/cartTrigger'에서 CartTrigger 가져오기;
'@magento/venia-ui/lib/components/Header/navTrigger'에서 NavTrigger 가져오기;
'@magento/venia-ui/lib/components/Header/searchTrigger'에서 SearchTrigger 가져오기;
'@magento/venia-ui/lib/components/Header/onlineIndicator'에서 OnlineIndicator 가져오기;
'@magento/peregrine/lib/talons/Header/useHeader'에서 { useHeader } 가져오기;

'@magento/venia-ui/lib/classify'에서 { mergeClasses } 가져오기;
'@magento/venia-ui/lib/components/Header/header.css'에서 defaultClass를 가져옵니다.
'@magento/venia-ui/lib/components/PageLoadingIndicator'에서 PageLoadingIndicator 가져오기;
'./simicartIcon'에서 SimiCartIcon 가져오기;

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

const 헤더 = 소품 => {
    상수 {
        핸들검색트리거클릭,
        hasBeen오프라인,
        isOnline,
        검색열기,
        isPage로딩
    } = 헤더 사용();

    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 ? (
        <서스펜스 대체={searchBarFallback}>
            <경로>
                <검색바 isOpen={검색열기} />
            </경로>
        </서스펜스>
    ) : 없는;
    const pageLoadingIndicator = isPageLoading? (
        <페이지 로딩 표시기 />
    ) : 없는;
 
    반품 (
        <헤더 클래스 이름={루트 클래스}>
            <div className={classes.toolbar}>
                <div className={classes.primaryActions}>
                    <내비게이터 />
                </div>
                {페이지 로딩 표시기}
                <온라인 지표
                    hasBenOffline={hasBeenOffline}
                    isOnline={isOnline}
                />
                <링크={resourceUrl('/')}>
                    <로고 클래스={{ 로고: classes.logo }} />
                </링크>
                <div className={classes.secondaryActions}>
                    <검색 트리거
                        활성={검색열기}
                        onClick={handleSearchTriggerClick}
                    />
                    <계정 트리거 />
                    <시미카트 아이콘 />
                    <카트트리거 />
                </div>
            </div>
            {검색 창}
        </헤더>
    );
};

Header.propTypes = {
    클래스: 모양({
        닫힘: 문자열,
        로고: 문자열,
        열기: 문자열,
        기본 작업: 문자열,
        secondaryActions: 문자열,
        도구 모음: 문자열
    })
};
 
기본 헤더 내보내기;

testextension/src/override/SimiCartIcon.js 에 이 뷰를 생성해 보겠습니다.

 '반응'에서 React 가져오기;
'@magento/venia-ui/lib/components/Icon'에서 아이콘 가져오기;
'react-feather'에서 { FastForward } 가져오기;
'@magento/peregrine/lib/util/makeUrl'에서 resourceUrl 가져오기;
'react-router-dom'에서 { useHistory } 가져오기;
'소품 유형'에서 { 모양, 문자열 } 가져오기;

'./SimiCartIcon.css'에서 defaultClass를 가져옵니다.
import { FormattedMessage, useIntl } from 'react-intl';

const SimiCartIcon = 소품 => {
    const 클래스 = defaultClasses;
    const { 형식 메시지 } = useIntl();
    const 기록 = useHistory();

    반품 (
        <버튼
            aria-label={형식메시지({
                아이디: `blog.bloglabel`,
                defaultMessage: '블로그'
            })}
            className={classes.root}
            onClick={() => history.push(resourceUrl('/simicart'))}
        >
            <아이콘 src={FastForward} />
            <span className={classes.label}>
                <FormattedMessage id={`블로그`} />
            </span>
        </버튼>
    );
}
 
SimiCartIcon.propTypes = {
    클래스: 모양({ 루트: 문자열 })
};
SimiCartIcon.defaultProps = {};
기본 SimiCartIcon 내보내기;

그런 다음 스타일을 지정하십시오.

 .루트 {
    항목 정렬: 가운데;
    커서: 포인터;
    디스플레이: 인라인 플렉스;
    정당화 내용: 중앙;
    라인 높이: 1;
    포인터 이벤트: 자동;
    텍스트 정렬: 가운데;
    공백: nowrap;
    전환 속성: 색상;
    전환 시간: 224ms;
    전환 타이밍 함수: 3차 베지어(0, 0, 0.2, 1);
    높이: 3rem;
    너비: 3rem;
}

.라벨 {
    디스플레이: 없음;;
}

@미디어(최소 너비: 641px) {
    .루트 {
        너비: 자동;
    }
    .라벨 {
        디스플레이: 초기;
        여백 인라인 시작: 0.25rem;
    }
}

결과:

PWA Studio 사용자 정의 확장 데모

이것으로 튜토리얼을 마칩니다. 혼란스러운 부분이 있으면 언제든지 질문을 보내주세요. 이 튜토리얼이 도움이 된다고 생각되면 도움이 된다고 평가하는 것을 잊지 마세요!

또한 Magento PWA Studio 확장을 사용해 보고 싶다면 Magento PWA Studio 웹사이트 상단에 설치할 수 있는 무료 오픈 소스 애드온 모듈이 있습니다.

Magento PWA 스튜디오 페이지 빌더

더 읽어보기:

Magento PWA Studio: 유용한 링크 및 리소스