如何創建 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. 安裝 Magento PWA Studio
首先我們需要安裝一個 PWA Studio 項目。 如果您在此處遵循我們的指南,這將相當容易:如何設置 Magento 2 PWA Studio
*注意:在問題步驟中,對於“在創建項目後使用 yarn 安裝包依賴項”這個問題,您需要像我們的設置教程一樣選擇否而不是是。
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(flags => { /** * 我們需要激活 esModules 和 cssModules 以允許構建包加載我們的擴展 * {@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( 路線數組 => { routesArray.push({ name: 'SimiCart 頁面', 模式:'/simicart', 路徑:'@simicart/testextension/src/components/page1' }); 返迴路由數組; }); };
在testextension/src/components/page1/index.js
中為新路由創建組件:
從“反應”導入反應; 從'@magento/venia-ui/lib/classify'導入{mergeClasses}; 從'prop-types'導入{shape, string}; 從'./index.css'導入defaultClasses; 常量 Page1 = 道具 => { 常量類 = 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' };
然後將此覆蓋代碼放入require
testextension/src/intercept.js
:
/** * 擴展的自定義攔截文件 * 默認情況下,您只能使用@magento/pwa-buildpack 的目標。 * * 如果確實想擴展 @magento/peregrine 或 @magento/venia-ui * 你應該將它們添加到你的 package.json 的 peerDependencies * * 如果你想為 @magento/venia-ui 組件添加覆蓋,你可以使用 * moduleOverrideWebpackPlugin 和 componentOverrideMapping */ const moduleOverrideWebpackPlugin = require('./moduleOverrideWebpackPlugin'); const componentOverrideMapping = require('./componentOverrideMapping') module.exports = 目標 => { target.of('@magento/pwa-buildpack').specialFeatures.tap(flags => { /** * 我們需要激活 esModules 和 cssModules 以允許構建包加載我們的擴展 * {@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( 路線數組 => { routesArray.push({ 名稱:'SimiCartPage', 模式:'/simicart', 路徑:'@simicart/testextension/src/components/page1' }); 返迴路由數組; }); target.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => { new moduleOverrideWebpackPlugin(componentOverrideMapping).apply(compiler); }) };
然後,從venia-ui文件夾中,將header組件複製到我們將覆蓋的新組件中。 然後在我們剛剛複制的標題中再添加一個視圖:

從'./simicartIcon'導入SimiCartIcon; . . . <SimiCartIcon />
testextension/src/override/header.js
中的完整代碼:
從“反應”中導入反應,{懸念}; 從'prop-types'導入{形狀,字符串}; 從'@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'導入defaultClasses; 從'@magento/venia-ui/lib/components/PageLoadingIndicator'導入PageLoadingIndicator; 從'./simicartIcon'導入SimiCartIcon; const SearchBar = React.lazy(() => import('@magento/venia-ui/lib/components/SearchBar')); 常量頭 = 道具 => { 常量 { 處理搜索觸發點擊, 已離線, 在線, 搜索打開, isPageLoading } = useHeader(); 常量類 = mergeClasses(defaultClasses, props.classes); 常量 rootClass = searchOpen ? classes.open:classes.close; 常量 searchBarFallback = ( <div className={classes.searchFallback}> <div className={classes.input}> <div className={classes.loader} /> </div> </div> ); 常量搜索欄 = 搜索打開? ( <Suspense fallback={searchBarFallback}> <路線> <SearchBar isOpen={searchOpen} /> </路線> </懸念> ) : 無效的; 常量 pageLoadingIndicator = isPageLoading ? ( <PageLoadingIndicator /> ) : 無效的; 返回 ( <header className={rootClass}> <div className={classes.toolbar}> <div className={classes.primaryActions}> <導航觸發器 /> </div> {pageLoadingIndicator} <在線指標 hasBeenOffline={hasBeenOffline} isOnline={isOnline} /> <鏈接到={resourceUrl('/')}> <Logo classes={{ logo: classes.logo }} /> </鏈接> <div className={classes.secondaryActions}> <搜索觸發器 主動={搜索打開} onClick={handleSearchTriggerClick} /> <帳戶觸發器 /> <SimiCartIcon /> <購物車觸發器 /> </div> </div> {搜索欄} </標題> ); }; Header.propTypes = { 類:形狀({ 關閉:字符串, 標誌:字符串, 打開:字符串, 主要操作:字符串, 次要動作:字符串, 工具欄:字符串 }) }; 導出默認標題;
讓我們在testextension/src/override/SimiCartIcon.js
中創建這個視圖:
從“反應”導入反應; 從'@magento/venia-ui/lib/components/Icon'導入圖標; 從 'react-feather' 導入 { FastForward }; 從'@magento/peregrine/lib/util/makeUrl'導入resourceUrl; 從 'react-router-dom' 導入 { useHistory }; 從'prop-types'導入{形狀,字符串}; 從'./SimiCartIcon.css'導入defaultClasses; 導入 { FormattedMessage, useIntl } from 'react-intl'; 常量 SimiCartIcon = 道具 => { 常量類 = 默認類; 常量 { formatMessage } = useIntl(); 常量歷史 = useHistory(); 返回 ( <按鈕 詠嘆調標籤={格式信息({ id: `blog.bloglabel`, 默認消息:'博客' })} 類名={classes.root} onClick={() => history.push(resourceUrl('/simicart'))} > <圖標 src={FastForward} /> <span className={classes.label}> <FormattedMessage id={`博客`} /> </span> </按鈕> ); } SimiCartIcon.propTypes = { 類:形狀({根:字符串}) }; SimiCartIcon.defaultProps = {}; 導出默認 SimiCartIcon;
然後樣式它:
。根 { 對齊項目:居中; 光標:指針; 顯示:inline-flex; 證明內容:中心; 行高:1; 指針事件:自動; 文本對齊:居中; 空白:nowrap; 過渡屬性:顏色; 過渡持續時間:224ms; 過渡時間函數:cubic-bezier(0, 0, 0.2, 1); 高度:3rem; 寬度:3rem; } 。標籤 { 顯示:無;; } @media(最小寬度:641px){ 。根 { 寬度:自動; } 。標籤 { 顯示:初始; 邊距內聯開始:0.25rem; } }
結果:

我們的教程到此結束。 如果有任何令人困惑的部分,請隨時向我們提出任何問題,如果您認為本教程有幫助,請不要忘記將其評為有幫助!
此外,如果您想嘗試 Magento PWA Studio 擴展,我們提供免費和開源的附加模塊,您可以將其安裝在 Magento PWA Studio 網站之上。
閱讀更多:
Magento PWA Studio:有用的鏈接和資源