Create-react-app: Embedding CRA created SPA into a bigger CMS

Created on 28 Feb 2017  路  14Comments  路  Source: facebook/create-react-app

My app should be part of a bigger CMS which has header, navbar, sidebar, footer elements. The app will be just some <div id="root" /> within the main content. I do not really know how to set this up with CRE for development and live deployment?

For development, so far I have just create a rather big index.html in public directory. The index.html includes (hand copied) the header, navbar, sidebar, footer markup as it comes from the CMS and also some of the CMS' css files. For development it's ok (we do not change a lot on the CMS right now, so not much to keep in sync).

For putting the app into production (live), I would like to just include the <div id="root" /> into one of the CMS's content templates and add links to the build CSS and JS files that are under build/static/. Do you think this is the best approach to be taken? Any side-effects I cannot think of at the moment? For instance the index.html for live would need to be cut down to only include the <div id="root" /> and the script/link to include the hashed CSS/JS static files, nothing else. And I would not know how to have a different public/index.html for development and production?

proposal

Most helpful comment

@tbillington

would be best to eject and add a command like build-watch which does the prod build but on webpack file watch.

You can do this without ejecting. Something like

npm i -g watch
"build-watch: watch node_modules/.bin/react-scripts\ build ./src"



md5-5128fbe07087d6d02499fcf4e39e07a1



npm run build-watch

All 14 comments

What you describe sounds like a reasonable way to do it. We don鈥檛 really strongly support this use case, and if you need further adjustments, you might want to npm run eject.

We might want to support index.development.html and index.production.html as optional overrides, similar to https://github.com/facebookincubator/create-react-app/pull/1344. Would that solve your use case better?

@gaearon I can PR this feature 馃槢

@jnachtigall if you add <div id="root"></div> + add the js & css file you should be good. I done this with Drupal and WordPress installs with no issues.

In some cases you might need to adjust the set / adjust the homepage setting in package.json file.

I use CRA for this use case pretty heavily.

I generally don't use the built index.html file at all. I have a shell script that runs at the end of build that brings the css and js to the root of the build dir and deletes everything else in there. From there I just bring those into the other app. Sometimes I even bundle the css into the js for single file installs with tag manager systems.

When I dev I just make a hard copy of the page I'm going to be doing the app inside, like you described. If you want to bring the built version of CRA back into your main apps dev system it would be best to eject and add a command like build-watch which does the prod build but on webpack file watch.

@tbillington

would be best to eject and add a command like build-watch which does the prod build but on webpack file watch.

You can do this without ejecting. Something like

npm i -g watch
"build-watch: watch node_modules/.bin/react-scripts\ build ./src"



md5-5128fbe07087d6d02499fcf4e39e07a1



npm run build-watch

Thanks for all the comments, much clearer now 馃憤

@gaearon

We might want to support index.development.html and index.production.html as optional overrides, similar to #1344. Would that solve your use case better?

I think, yes, a bit. I guess the index.production.html would just contain:

<link href="./static/css/main.1f8335c3.css" rel="stylesheet">
<div id="root"></div>
<script type="text/javascript" src="./static/js/main.10ed2375.js"></script>

This would make postprocessing/embedding into some CMS template easier. What do others think?

@timarney

if you add <div id="root"></div> + add the js & css file you should be good

I guess this is the main point: You need some postprocessing in package.json like:
"build": "react-scripts build&&npm run post-processing-for-the-css"

Obviously, this post-processing-for-the-css is different for each CMS.

Hmm, two questions regarding integration into a CMS:

  1. Is there a way to disable the hashes that are created with run build? That is, just output /static/js/main.js instead of /static/js/main.<hash>.js (same for CSS and *.map files). Background is that the ever-changing filenames make it hard to reference the files for integration into the CMS.
  2. Is there a way to change the build/ directory name based on some .env or other conf? Background is that for CI it would be good to have a build-stage/ and a build-live/ depending on where the SPA should be integrated.
  1. You can read the assets-manifest.json to read the reference to the current filenames
  2. I think this feature is considered, but AFAIK no one's working on that. Here's the issue https://github.com/facebookincubator/create-react-app/issues/1354

@gaearon After building two React Apps for two different kind of CMS (one Java based for govermental usage, another PHP based) I found that the biggest pain point where the file hash numbers. What I did:

Like others suggested in this thread I copied the main..js + main..css from CRE to main.js and main.css of the CMS. The files' hash numbers make this unnecessarily cumbersome. For one, the sourcemaps do not work anymore. If you have media files, e.g. images which also have the hash in the filename, it is even more cumbersome. Even worse, my companies build servers run on Windows (I know, facepalm), so basic Unix tools like sed or mv are not available... Moreover, the postprocessing for removing the hashes is a bit different on build environment and CMS.

Long story short: If there was an option for disabling the hash numbers in the first place like asked for in #1005 this would greatly help.

@jnachtigall You can read asset-manifest.json to get reference of the generated files https://github.com/facebookincubator/create-react-app/issues/2532#issuecomment-308533564

@viankakrisna Yes, I know, but the hassle comes afterwards. In the CMS we use it is easy to "mount" (register/integrate) a CSS or JS file known by path and file name into the CMS. This is how we do it when we build with grunt/gulp which output simple main.min.js or main.min.js. It is much harder to this when the file name is not known in advance. This requires knowledge and skills regarding the CMS' API and CMS scripting language (So I need to setup meetings with the backend devs, who asked me why we cannot do it like with grunt/gulp? Communications...). For instance, your comment links to a PHP based post-processing script. This would look very different for a java, python or whatever based CMS. Usually, it would be even different for each CMS because they all have different APIs for "mounting" (integrating) external JS/CSS files.

Moreover, even when you've done the mounting, e.g. like outlined in your comment. Then still, the path to the source map file is broken.

I'm not saying that it is not possible. It is just cumbersome. And the root cause solution to this would be if the hashes were not generated in the first place (if CRE had an option for this).

I'd say we just don't intend to support this use case.
Please use any of the alternatives that better handle something like this or eject.

@gaearon this use case can be supported with https://github.com/facebook/create-react-app/pull/4014 and https://github.com/facebook/create-react-app/pull/1588

IMO it's a missing opportunity to not support this use case out of the box.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fson picture fson  路  3Comments

alleroux picture alleroux  路  3Comments

dualcnhq picture dualcnhq  路  3Comments

fson picture fson  路  3Comments

barcher picture barcher  路  3Comments