如何創建 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導入包:

修改 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;
    }
}

結果:

PWA Studio 自定義擴展演示

我們的教程到此結束。 如果有任何令人困惑的部分,請隨時向我們提出任何問題,如果您認為本教程有幫助,請不要忘記將其評為有幫助!

此外,如果您想嘗試 Magento PWA Studio 擴展,我們提供免費和開源的附加模塊,您可以將其安裝在 Magento PWA Studio 網站之上。

Magento PWA Studio 頁面構建器

閱讀更多:

Magento PWA Studio:有用的鏈接和資源