【问题标题】:How to insert (inject?) an existing React app (just a UI without a backend) into a SilverStripe page layout?如何将现有的 React 应用程序(只是没有后端的 UI)插入(注入?)到 SilverStripe 页面布局中?
【发布时间】:2019-09-08 07:01:31
【问题描述】:

我的问题是: 我一直在阅读 SilverStripe 4 文档,以便找到一种将现有 React 应用程序(只是没有后端的嵌套 React 组件的 UI)插入 SilverStripe 页面布局的方法。这可能吗?您如何确保 SilverStripe 具有正确的依赖关系?

到目前为止,我的研究试图回答这个问题: 由于传统的 React 项目使用 NPM(节点包管理器)来获取所有正确的依赖项并将 Node.js 作为服务器,我想知道如何在我的 SilverStripe 项目在 Apache 服务器上运行时处理这个问题。我找到了这个包,我需要将它添加到我的项目中吗? https://www.npmjs.com/package/@silverstripe/webpack-config

我遇到的最接近的是一篇关于在 SilverStripe 项目中包含 React 组件的文章,其中讨论了自定义 CMS 的管理界面。我想在网站的公共页面上显示 React 组件。 https://docs.silverstripe.org/en/4/developer_guides/customising_the_admin_interface/reactjs_redux_and_graphql/

在文章中提到了一个客户端框架,它有自己的依赖注入实现,称为 Injector。我找不到关于此的其他文档。

我有一个 PageController 类,它目前只有与 SilverStripe 相关的要求(JavaScript 和 css)。这是按照 SilverStripe 第 1 -4 课完成的。

<?php

namespace {

    use SilverStripe\CMS\Controllers\ContentController;

    use SilverStripe\View\Requirements;

    class PageController extends ContentController
    {

        private static $allowed_actions = [];

        protected function init()
        {
            parent::init();
            // You can include any CSS or JS required by your project here.
            // See: https://docs.silverstripe.org/en/developer_guides/templates/requirements/
                Requirements::css('css/bootstrap.min.css');
                Requirements::css('css/style.css');
                Requirements::javascript('javascript/common/modernizr.js');
                Requirements::javascript('javascript/common/jquery-1.11.1.min.js');
                Requirements::javascript('javascript/common/bootstrap.min.js');
                Requirements::javascript('javascript/common/bootstrap-datepicker.js');
                Requirements::javascript('javascript/common/chosen.min.js');
                Requirements::javascript('javascript/common/bootstrap-checkbox.js');
                Requirements::javascript('javascript/common/nice-scroll.js');
                Requirements::javascript('javascript/common/jquery-browser.js');
                Requirements::javascript('javascript/scripts.js');
        }
    }
}

我还有一个扩展 PageController 类的 ReactPageController 类。我是否在此处包含 React 的要求(依赖项?)?

<?php
namespace SilverStripe\Lessons;

use PageController;    

class ReactPageController extends PageController 
{
//include another init method here?
}
?>

然后我需要以某种方式在 ReactPage.ss 的布局中注入 React 组件('ReactPage.php' 类扩展了 'Page.php' 类)。注意:Page.ss 的布局包括 ReactPage.ss 将继承的简单导航栏、页眉和页脚。

ReactPage.ss 模板

<!-- BEGIN CONTENT -->
        <div class="content">
            <div class="container">
                <div class="row">
                    <div class="main col-sm-8"> 
                        <div>
                           <!-- INSERT REACT CONTENT HERE:replace Hello World!-->
                           <h1>Hello World!</h1>
                        </div>                  

                    </div>

                    <div class="sidebar gray col-sm-4">
                        <% if $Menu(2) %>
                        <h3>In this section</h3>
                            <ul class="subnav">  
                                <% loop $Menu(2) %>
                                    <li><a class="$LinkingMode" 
                                     href="$Link">$MenuTitle</a></li>
                                <% end_loop %>
                            </ul>
                        <% end_if %>
                    </div>
                </div>
            </div>
        </div>
        <!-- END CONTENT -->

结果将是一个页面,其中不是硬编码的“Hello World!”,而是一个根组件,其中嵌套了很多组件。嵌套的 React 应用与独立的 React 应用具有相同的功能。

感谢您抽出宝贵时间阅读我的长问题。任何回应将不胜感激。我只是在学习 React 和 SilverStripe,如果是这种情况,我的问题也可能令人困惑或措辞不当。再次感谢:-)。

【问题讨论】:

    标签: reactjs silverstripe-4


    【解决方案1】:

    您可以在控制器中使用Requirements::javascript() 调用注入前端应用程序包,或者使用&lt;% require %&gt; 调用从模板中注入。基本概念是“将您的 JavaScript(和/或 CSS)包添加到我的前端视图”。鉴于捆绑包在页面上可用,从那里开始由您的捆绑包自行启动。


    这是一个添加到主题的轻量级示例:

    • 添加主题文件夹,例如themes/my-theme
    • 通过将其添加到app/_config/theme.yml 来启用它
    • 添加 ReactPage 布局(注意:布局是内容部分,而不是整页布局)
    # File: ./themes/my-theme/templates/Layout/ReactPage.ss
    <div id="my-react-app">
        If you can see this, your React app hasn't initialised yet
    </div>
    
    • 刷新(浏览器中的?flush)缓存

    如果您在 CMS 中添加一个 ReactPage,然后在前端打开它,您现在应该会看到您的 React 应用程序尚未初始化的消息。这是因为 SilverStripe 将查找页面的继承链以找到一个模板与其类名匹配的页面。请注意,这包括类的命名空间,因此,如果您的类有一个命名空间,则需要改为 templates/Foo/Bar/Layout/ReactPage.ss

    现在初始化一个演示 React 应用:

    • cd themes/my-theme &amp;&amp; create-react-app js
    • cd js &amp;&amp; yarn build

    您现在需要将 SilverStripe 告知 "expose" your theme assets,这会将它们符号链接(默认情况下)到 public/resources 目录,以便您可以从您的 webroot(public/ 文件夹)访问它们。

    # File: ./composer.json
    ...
    "extra": {
        "expose": [
            "themes/my-theme/build/static/js/bundle.js"
        ]
    }
    

    从您的根项目文件夹运行composer vendor-expose 以重新公开您的所有资源。

    最后,将您的要求添加到您的 SilverStripe 模板或控制器中。您可以通过控制器的 init() 方法或直接在模板中执行此操作:

    # File: ReactPageController.php (note that this may not exist and doesn't need to necessarily)
    use SilverStripe\View\Requirements;
    
    // ...
    
    protected function init()
    {
        parent::init();
    
        Requirements::javascript('themes/my-theme/js/build/static/js/main.ad956de7.chunk.js');
        Requirements::javascript('themes/my-theme/js/build/static/js/2.6efc73d3.chunk.js');
        Requirements::javascript('themes/my-theme/js/build/static/js/runtime~main.a8a9905a.js');
        Requirements::css('themes/my-theme/js/build/static/css/main.5c68d653.chunk.css');
    }
    

    在本示例中,我使用了由create-react-app 创建的文件的哈希名称。如果您有一个一致的文件名,例如 bundle.js 或其他名称,那么在 SilverStripe 中集成会更容易。

    您也可以在模板中执行此操作:

    # File: ./themes/my-theme/templates/Layout/ReactPage.ss
    ...
    <% require javascript('themes/my-theme/js/build/static/js/main.ad956de7.chunk.js') %>
    <% require javascript('themes/my-theme/js/build/static/js/2.6efc73d3.chunk.js') %>
    <% require javascript('themes/my-theme/js/build/static/js/runtime~main.a8a9905a.js') %>
    <% require css('themes/my-theme/js/build/static/css/main.5c68d653.chunk.css') %>
    

    现在加载您的浏览器,您将看到 React 应用程序正在运行。它会有点损坏,但就这个示例而言,它足以展示如何让 React 应用程序在您的页面上运行。

    【讨论】:

    • 嗨,罗比,感谢您的慷慨回复。我目前正在尝试实施该解决方案,但不幸的是我被困在这条指令上。这是因为 SilverStripe 第 1-4 课改变了 Composer 生成的初始项目的结构,并让您删除主题文件夹:“您现在需要告诉 SilverStripe “公开”您的主题资产,这将符号链接(默认情况下) 将它们放到 public/resources 目录中,这样您就可以从您的 webroot(public/ 文件夹)访问它们..."
    • 我已经将一个演示 React 应用程序移动到 App 文件夹中,并且认为暴露应该类似于“expose”:[“app/build/static/js/bundle.js”]。不幸的是,我认为这不起作用,因为没有构建文件夹或静态文件夹。这是调整文件夹结构的课程(初学者抓狂)silverstripe.org/learn/lessons/v4/creating-your-first-project
    • 是的,您需要调整 React 应用文件夹的文件路径
    • 是我公开的进入 React 演示应用程序的路径,例如'themes/my-theme/react-demo-app/build/static/js/main.ad956de7.chunk.js' ?
    • 目前正在尝试查找您在哪里可以找到由 create-react-app 创建的文件的哈希名称。你能告诉我吗?我正在尝试确定我需要公开的文件。非常感谢您抽出宝贵时间回答我的问题。
    【解决方案2】:

    如果你已经安装了 NPM、webpack 和 babel,那么你需要在 webpack.config.js 中创建一个入口点来触发 .jsx 文件。 例如

    module.export = [
       entry:[
       ],
        output: [
        ]
    ]enter code here
    

    请看这个链接
    https://webpack.js.org/configuration/output/
    要么 how to export function with webpack

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 2019-09-21
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      相关资源
      最近更新 更多