如何创建 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:有用的链接和资源