如何将现有React应用(只是一个没有后端的UI)插入(注入?)到SilverStripe页面布局中?

时间:2019-04-18 00:21:11

标签: reactjs silverstripe-4

我的问题是: 我一直在阅读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');
        }
    }
}

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

<?php
namespace SilverStripe\Lessons;

use PageController;    

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

然后,我需要以某种方式将React组件注入到ReactPage.ss的布局中(“ 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 App将具有与独立的React App相同的功能。

感谢您阅读我的冗长问题。任何答复将不胜感激。我只是在学习React和SilverStripe,我的问题也可能令人困惑或措辞不佳,如果是这种情况,我们感到抱歉。再次感谢:-)。

2 个答案:

答案 0 :(得分:1)

如果你已经安装了 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

答案 1 :(得分:0)

您可以在控制器中使用Requirements::javascript()调用或在模板中使用<% require %>调用来注入前端应用程序捆绑包。基本概念是“将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 && create-react-app js
  • cd js && 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应用。