How to build a React app (containing SVG files) in

2019-07-28 19:13发布

问题:

I have been using npm run buildto create build files for my React project which automatically produces three folders in the build directory inside the React project static/js, static/css and static/media (containing the SVG files). The first two folders static/js and static/css can be dealt with by using the SilverStripe Requirements class on the init method of the ReactPageController (the PageController for the SilverStripe layout with the nested React app), adding the paths to the composer.json file

"extra": {
        "expose": [
            "app/react-complete-guide-app/build/static/js",
            "app/react-complete-guide-app/build/static/css",

        ],

and running composer vendor-expose to create SymLinking in the SilverStripeProject/public/app/react-app directory.

The media file is not so easy beacause the Requirements class of SilverStripe only deals with JavaScript or CSS files. ALso the script npm run build automatically configures the relative path of the react-app build files without considering the SilverStripe project structure that it will be nested within e.g. the relative path after npm run build is /static/media/icon.svg.

To get the static/media/icon.svg files to be picked up by the virtual host means I have to manually place a copy of the static/media folder (containing the icons for the site as svg files) in the my-SS4-project/public directory. I want to place the svg files in the my-SS4-project/public/resources folder where they should be located. But then I can't point the virtual host at that folder without the virtual host losing access to the SymLinks for the static/js and static/css build folders.

The generated build folder paths and files are:

build/static/js:

- main.f8fcfe77.js
- main.f8fcfe77.js.map

build/static/css:

- main.417390ae.css
- main.417390ae.css.map

build/static/media:

- bottom_image_height_improved_enlarged.0242eccb.svg
- glyphicons-halflings-regular.448c34a5.woff2
- glyphicons-halflings-regular.89889688.svg
- glyphicons-halflings-regular.e18bbf61.ttf
- glyphicons-halflings-regular.f4769f9b.eot
- glyphicons-halflings-regular.fa277232.woff
- ic_cloud_download.0258cc94.svg
- ic_cloud_upload.6bf269d8.svg
- ic_help.bb8f97ab.svg
- ic_local_download.ddb824a7.svg
- ic_menu.7f39fb5c.svg
- ic_new.57667fef.svg
- ic_open.ddb824a7.svg
- ic_print.420fc2c5.svg
- ic_save.3fee4fd0.svg
- logo.d6c538c9.svg
- master_menu_cancel_btn.53591bb8.svg

Below shows the CircleAppPageController.php file using the init function and Requirements class to bring in the JavaScript and CSS files from the react-app build files. Note: react-app is nested inside the SilverStripe project app folder.

<?php
namespace SilverStripe\Lessons;

use SilverStripe\View\Requirements;

use PageController;    

class ReactAppPageController extends PageController 
{
    protected function init()
    {
        parent::init();
        // Requiring build files for react-app - Doesn't include media folder files!
        Requirements::javascript('app/react-app/build/static/js/main.f8fcfe77.js');
        Requirements::css('app/react-app/build/static/css/main.417390ae.css');

    }
}
?>

Here is where the react-app to appears in the layout of the ReactAppPage.ss (Note: ReactAppPage.php class extends Page.php class. The layout for Page.ss includes a simple navbar, header and footer which ReactAppPage.ss will inherit).

<% include Banner %>
<!-- BEGIN CONTENT -->
        <div class="content">
            <div class="container">
                <div class="row">
                    <div class="main col-sm-8"> 
                        <div>

                            <div id="root">
                                I want the react-app with it's independent CSS stylings to appear here.
                            </div>

                        </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 -->

I am new to all this and have been advised to try writing a DOS batch script to automatically do all the manual hack I am doing to get the icons to work every time something changes in my react-app requiring a new build.

I have researched a lot and read that SS4 decided to not let the public folder be configurable. Also SS4 dropped support for SVG files in December 2018 fro security reasons. I have also heard that changing the build paths of the SVG files post build is possible with the SilverStripe 4 back end. Any thoughts about this would be great.

The expected results would be that I can automate the build process as much as possible and have the files in the correct place in the SilverStripe project. Maybe I am trying to do something more complicated than needed?