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 을 수정합니다.

"종속성": { "@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.js
에 require
합니다.
/** * 확장에 대한 사용자 정의 가로채기 파일 * 기본적으로 @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; } }
결과:

이것으로 튜토리얼을 마칩니다. 혼란스러운 부분이 있으면 언제든지 질문을 보내주세요. 이 튜토리얼이 도움이 된다고 생각되면 도움이 된다고 평가하는 것을 잊지 마세요!
또한 Magento PWA Studio 확장을 사용해 보고 싶다면 Magento PWA Studio 웹사이트 상단에 설치할 수 있는 무료 오픈 소스 애드온 모듈이 있습니다.
더 읽어보기:
Magento PWA Studio: 유용한 링크 및 리소스