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: 유용한 링크 및 리소스
