@xxx-ssr/express
TypeScript icon, indicating that this package has built-in type declarations

0.12.4 • Public • Published

😎 @xxx-ssr/express 😎

Overview

  • SSR (Server Side Rendering) as a view template engine
  • Passing the server data to the client props
  • Dynamic props without caring about SSR
    • Suitable for dynamic routes like blogging
  • Dynamic Head component
  • HMR when process.env.NODE_ENV !== 'production'

Usage

Install it:

$ npm install --save @xxx-ssr/express express react react-dom

And add a script to your package.json like this:

{
  "scripts": {
    "start": "node server.js"
  }
}

Populate files below inside your project:

./.babelrc

{
  "presets": [
    "@xxx-ssr/express/babel"
  ]
}

./server.js

const express = require('express');
const register = require('@xxx-ssr/express/register');

const app = express();

(async () => {
  // register `.jsx` or `.tsx` as a view template engine
  await register(app);

  app.get('/', (req, res) => {
    const message = 'Hello World!';
    res.render('index', { message });
  });

  app.listen(3000, () => {
    console.log('> Ready on http://localhost:3000');
  });
})();

./views/index.jsx

export default function Index({ message }) {
  return <p>{message}</p>;
}

Then just run npm start and go to http://localhost:3000.

You'll see Hello World!.

Configuration (ssr.config.js)

Here is the default ssr.config.js, which is used by xxx-ssr when there are no valid values:

module.exports = {
  id: 'default',
  distDir: '.ssr',
  viewsDir: 'views',
  dynamicViews: [],
  webpack: (config /* webpack.Configuration */, env /* 'development' | 'production' */) => {
    return config;
  },
};

ssr.config.js#id

The id of UI framework. (default: default)

It can be ignored only when the project does not use any UI frameworks.

Supported UI frameworks are:

For example, if we want to use emotion, ssr.config.js is like this:

module.exports = {
  id: 'emotion',
};

ssr.config.js#distDir

The place where xxx-ssr generates production results. (default: .ssr)

If we use TypeScript or any other library which must be compiled, the config below may be useful:

module.exports = {
  // dist folder should be ignored by `.gitignore`
  distDir: 'dist/.ssr',
};

ssr.config.js#viewsDir

The place where we put views. (default: views)

A function res.render('xxx') will render views/xxx.jsx or views/xxx.tsx.

A working example is here: examples/custom-views

ssr.config.js#dynamicViews

If specified, xxx-ssr won't generate html cache when production.

This is suitable for search-engine-optimized dynamic routes like blogging:

module.exports = {
  dynamicViews: [
    // this means `views/posts.jsx` is a dynamic view
    'posts',
  ],
};

A working example is here: examples/basic-blogging

ssr.config.js#webpack()

module.exports = {
  webpack: (config /* webpack.Configuration */, env /* 'development' | 'production' */) => {
    // we can override default webpack config here
    return config;
  },
};

Custom Document

Just put _document.jsx or _document.tsx into the views root:

./views/_document.jsx

import React from 'react';
import {
  Document,
  Head,
  Main,
} from '@xxx-ssr/express';

export default class extends Document {
  render() {
    return (
      <html>
        <Head>
          <title>Default Title</title>
        </Head>
        <body>
          <Main />
        </body>
      </html>
    );
  }
};

Note: Please put <Main /> component directly under <body> tag AND don't wrap <Main /> component with another components because this is a hydration target for the client.

And then, use it as always:

./views/index.jsx

const Index = (props) => {
  return <p>Hello Layout!</p>;
};

export default Index;

A working example is here: examples/custom-document

Dynamic Head

We can use the Head component anyware:

./views/index.jsx

import React from 'react';
import { Head } from '@xxx-ssr/express';

const Index = (props) => {
  return (
    <React.Fragment>
      <Head>
        <title>Dynamic Title</title>
        <meta name="description" content="Dynamic Description" />
      </Head>
      <p>Of course, SSR Ready!</p>
    </React.Fragment>
  );
};

export default Index;

A working example is here: examples/basic-dynamic-head

Supported UI Framework

Non CSS-in-JS framework

Like semantic-ui, non CSS-in-JS frameworks are supported without extra configuration.

All we have to do is to load global CSS in _document or each page:

./views/_document.jsx

import React from 'react';
import {
  Document,
  Head,
  Main,
} from '@xxx-ssr/express';

export default class extends Document {
  render() {
    return (
      <html>
        <Head>
          <title>A Sample of Semantic UI React</title>
          <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css" />
        </Head>
        <body>
          <Main />
        </body>
      </html>
    );
  }
}

With Emotion

In order to enable SSR, we must install these packages:

And then, populate .babelrc in your project root:

{
  "presets": [
    "@xxx-ssr/express/babel"
  ],
  "plugins": [
    "emotion"
  ]
}

A working example is here: examples/with-jsx-emotion

With styled-components

In order to enable SSR, we must install babel-plugin-styled-components as devDependencies.

And then, populate .babelrc in your project root:

{
  "presets": [
    "@xxx-ssr/express/babel"
  ],
  "plugins": [
    "styled-components"
  ]
}

A working example is here: examples/with-jsx-styled-components

With Material UI

We can use material-ui without extra configuration.

A working example is here: examples/with-jsx-material-ui

With Ant Design

In order to enable SSR, we must install babel-plugin-import as devDependencies.

And then, populate .babelrc in your project root:

{
  "presets": [
    "@xxx-ssr/express/babel"
  ],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "style": "css"
      }
    ]
  ]
}

A working example is here: examples/with-jsx-antd

TypeScript Support

To enable TypeScript engine (.tsx), just put tsconfig.json in your project root directory.

The code of TypeScript will be like this:

./package.json

{
  "scripts": {
    "start": "ts-node server.ts"
  }
}

./server.ts

import express, { Request, Response } from '@xxx-ssr/express';

const app = express();

app.get('/', (req: Request, res: Response) => {
  const message = 'Hello World!';
  res.render('index', { message });
});

app.listen(3000, () => {
  console.log('> Ready on http://localhost:3000');
});

./views/index.tsx

interface IndexProps {
  message: string;
}

export default function Index({ message }: IndexProps) {
  return <p>{message}</p>;
}

Examples

Starters

Articles

The React View Template Engine for Express

[Express] React as a View Template Engine?

Related

reactjs/express-react-views

Package Sidebar

Install

npm i @xxx-ssr/express

Weekly Downloads

2

Version

0.12.4

License

MIT

Unpacked Size

13.7 kB

Total Files

8

Last publish

Collaborators

  • zan