react-simple-universal icon indicating copy to clipboard operation
react-simple-universal copied to clipboard

Examples Folder

Open enbits opened this issue 8 years ago • 9 comments

First of all this is a great boilerplate, one of the best I found in terms of simplicity. However since I'm pretty new with all these modern JS frameworks I find a bit confusing having an examples folder because its running its own server (devServer.js) and is not using a layout like in the root folder (render-layout.js)

Wouldn't it be easier that the examples use the same files that the app located in root? Or maybe not having an example folder at all and adding examples as 'tags' in the repository branch instead.

enbits avatar Apr 01 '16 02:04 enbits

What we do in the examples folder is requiring the react-simple-universal module itself, so devServer.js will be used, although we don't explicitly import it at the top. We do this so you can just git clone this repository and run the example. You can even copy the example if you want to use it as a starting point in your next project.

guidsen avatar Apr 01 '16 11:04 guidsen

I can see that now. DevServer is like a wrapper for react-simple-universal boilerplate. What caused the confusion originally is that I modified render-layout.js and then restart the app but it didn't change. Even I checked in dist folder that the layout file was modified correctly with the changes, but somehow when I go to localhost:3000 I see the old layout.

enbits avatar Apr 01 '16 20:04 enbits

Did you use the booklist example?

guidsen avatar Apr 01 '16 20:04 guidsen

Yes, didn't have time to check the code in depth so maybe is just me making a silly mistake. I will check tomorrow.

enbits avatar Apr 02 '16 00:04 enbits

@enbits In #21 I've added the ability to pass your own layout to render. As default we use render-layout.js, but now you can pass your own layout with extra scripts etc to the server.

Example:

const createLayout = ({ rootMarkup, initialState }) => {
  return `
    <!doctype html>
    <html>
      <head>
        <title>My really cool React App!</title>
        <script src="./my/script.js"></script>
      </head>
      <body>
        <div id='root'>${rootMarkup}</div>
        <script>
          window.BOOTSTRAP_CLIENT_STATE = ${JSON.stringify(initialState)}
        </script>
        <script src="/static/index.js"></script>
      </body>
    </html>
  `;
};

universal({ routes, reducers, app: expressDevServer(config), layout: createLayout });

I'm not sure yet if this will be a good solution, because the code below always have to be present in your layout to be able to render everything properly.

<div id='root'>${rootMarkup}</div>
<script>
  window.BOOTSTRAP_CLIENT_STATE = ${JSON.stringify(initialState)}
</script>
<script src="/static/index.js"></script>

Maybe just two functions to add code in the head and below the body as footer will be better. For example:

const header = `
  <link rel="stylesheet" href="my/styles.css">
  <script src="my/script.js"></script>
`;

const footer = `
  <script src="my/other-script.js"></script>
`;

const includes = { header, footer };

universal({ routes, reducers, app: expressDevServer(config), includes });

What do guys think of this API? Other suggestions?

cc @liamhubers @jackfranklin

guidsen avatar Apr 02 '16 09:04 guidsen

I don't like the idea of allowing a header and footer, I'd rather give full control as you have with the layout: createLayout option.

Potentially you could provide a function to provide the boilerplate:

function boilerplate(rootMarkup) {
  return `
<div id='root'>${rootMarkup}</div>
<script>
  window.BOOTSTRAP_CLIENT_STATE = ${JSON.stringify(initialState)}
</script>
<script src="/static/index.js"></script>
  `;
}

So it's easier for people making custom layouts to do this. Also then if you need to change what is required in the template you can update the above function and you don't suddenly get loads of broken usages. WDYT?

jackfranklin avatar Apr 07 '16 13:04 jackfranklin

It's indeed better to give full control, but there are some things that are currently not configurable like the /static/index.js part, the window variable name (BOOTSTRAP_CLIENT_STATE) and the id of the root div.

So if we want to give full control I guess we should be able to pass some kind of config or options object to make sure things don't break or don't work like they should. Right?

guidsen avatar Apr 08 '16 10:04 guidsen

Can't we give "full control" with the exception of the bit of boilerplate above?

Else I agree a full config option is the way to go but that feels a bit excessive at the moment perhaps?

jackfranklin avatar Apr 11 '16 12:04 jackfranklin

Well then we must document that the root always need to have an id of root, the window variable name has to be BOOTSTRAP_CLIENT_STATE and the script must be /static/index.js. If not, things won't work.

guidsen avatar Apr 14 '16 07:04 guidsen