npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

create-react-scripts-ssr

v0.1.10

Published

Make universal react app easy using create-react-scripts

Downloads

11

Readme

create-react-scripts-ssr


This module is useful if you want to make an universal app.

Important Note


  • This Module does not automate the Server-Side-Rendeirng.
  • It just make you able to require files that without js or json extensions in server side.
  • The index.html is no longer necessary in universal app, and it could be cached by service-worker accidentally with default setting of create-react-app. This module will detect if index-static.html exists instead of index.html to apply HTML related webpack plugins. The generated html would also be index-static.html

Scripts


start:server

start the both client side bundling and server side bundling webpack tasks in development mode. The server will auto reload if code changes. By default, webpack-dev-server is running on port: 3001 while the server is running on 3000. The following environment variables are injected to server side bundling

HOST: The host that the server should be running on.
PORT: The port number that the server should be running on.
PROTOCOL: The protocol that the server should be running on.
PUBLIC_URL: The absolute url that the webpack-dev-server is running.

All client side log would be supressed in the console. The client build is located in build/client
The server build is located in build/server
An assets json manifest is located in build/assets.json, which is useful for server-side-rendering.
If autodll plugin is detected, an assets json manifest is located in build/dll-assets.json, which is useful for server-side-rendering.
This script will start the webpack-dev-server and the server.js

build:server

trigger both client side and server side webpack tasks build.
An assets json manifest is located in build/assets.json, which is useful for server-side-rendering.
You can start the server by node build/server after build.

How it works?


Webpack bundle both different environment, the client side and the server side.
Make use of assets-webpack-plugin to produce assets mapping so that server side can know the filename produced in client side build.

Usage


Modify crs.config

Modify crs.config as below.

const { compose } = require('create-react-scripts')

module.exports = compose(
  require('create-react-scripts-ssr')(),
  ...
);
Modify package.json

Modify package.json as below.

{
-   "start": "react-scripts start",
+   "start": "create-react-scripts start",
+   "start:server": "create-react-scripts start:server",
-   "build": "react-scripts build",
+   "build": "create-react-scripts build",
+   "build:server": "create-react-scripts build:server",
-   "test": "react-scripts test --env=jsdom",
+   "test": "create-react-scripts test --env=jsdom"
}
Add Server.js

Create server.js under src directory

import React from 'react';
import HTMLDocument from 'react-html-document';
import ReactDOMServer from 'react-dom/server';
import express from 'express';
import url from 'url';
import serveStatic from 'serve-static';
import path from 'path';
import fs from 'fs';
import App from './App';

// To obtain the actual HOST, PORT, and PROTOCOL
const HOST = process.env.HOST || '0.0.0.0';
const PORT = parseInt(process.env.PORT, 10) || 5000;
const PROTOCOL = process.env.PROTOCOL || 'http';

// Assets manifest path from client-side dll build (if create-react-scripts-dll is using)
const DLL_ASSETS_PATH = path.join(process.cwd(), 'build/dll-assets.json');
// Assets manifest path from client-side build
const ASSETS_PATH = path.join(process.cwd(), 'build/assets.json');

// Wait until client-side bundling finished so that assets.json is produced
console.log('Waiting client-side bundling...');
while (!fs.existsSync(ASSETS_PATH));

// Read the assets
const assets = {
  // make sure dll assets before the assets of client-side build
  // ensure browser require the vendor module first
  ...JSON.parse(fs.readFileSync(DLL_ASSETS_PATH)),
  ...JSON.parse(fs.readFileSync(ASSETS_PATH)),
};

const app = express();
// in production, the serving files are under build/client folder
if (process.env.NODE_ENV === 'production') {
  app.use(serveStatic(path.join(process.cwd(), 'build/client'), { index: false }));
}

// render the app
app.get('*', async (req, res) => {
  // you may have some data prefetching logic here
  // ...
  res.set('content-type', 'text/html').send(
    ReactDOMServer.renderToStaticMarkup(
      <html lang="en">
        <head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="width=device-width,initial-scale=1,shrink-to-fit=no"
          />
          <meta name="theme-color" content="#000000" />
          <link rel="manifest" href={`${process.env.PUBLIC_URL}/manifest.json`} />
          <link rel="shortcut icon" href={`${process.env.PUBLIC_URL}/favicon.ico`} />
          <title>React App</title>
          {
            Object.values(assets).map(mod => mod.css ? (
              <link key={mod.css} href={mod.css} rel="stylesheet" />
            ) : null)
          }
        </head>
        <body>
          <div
            id="root"
            dangerouslySetInnerHTML={{
              __html: ReactDOMServer.renderToString(<App />),
            }}
          />
          {
            Object.values(assets).map(mod => mod.js ? (
              <script key={mod.js} src={mod.js} />
            ) : null)
          }
        </body>
      </html>
    )
  );
});

app.listen(PORT, () => {
  console.log(`Server is Running on ${url.format({ hostname: HOST, port: PORT, protocol: PROTOCOL })}!`);
});
Install source-map-support

This step is to make the source mapping correct in the stack trace if error is thrown from server-side npm i -S source-map-support or yarn add source-map-support

Start Server in Development Mode

npm run start:server or yarn start:server

Start Server in Production Mode

npm run build:server or yarn build:server

Working Example

raymondsze/example-universal-react-app