Giter Site home page Giter Site logo

manuelbieh / react-ssr-setup Goto Github PK

View Code? Open in Web Editor NEW
774.0 35.0 203.0 3.01 MB

React Starter Project with Webpack 4, Babel 7, TypeScript, CSS Modules, Server Side Rendering, i18n and some more niceties

License: MIT License

JavaScript 18.17% CSS 1.76% HTML 0.47% TypeScript 79.51% Shell 0.09%
react webpack redux babel i18n hmr reselect eslint prettier postcss

react-ssr-setup's Introduction

⚛ React + Express – SSR Setup with TypeScript

Maintainability dependencies Status Known Vulnerabilities styled with prettier CircleCI

Advertising: I wrote a book about React. There's a German and an English version. Buy one if you like this project and you want to support my work!

English German
English German

New! You can now use this project as template! Click here to create a new repo on GitHub with this project as template.

TOC

Motivation

This is just another React Starter Project as there are literally hundreds of others out there. The reason I created this one was to have one central repo I can base my own future projects on, which contains most of the packages I usually use, is easily extendable, easy to understand, supports server side rendering, and uses all the configs and settings I made good experiences with in the past.

Another reason I created my own starter project was because I was setting up two new long term projects and I wanted to be able to use Webpack 4 and Babel 7 long before it was stable. None of the bigger and well known starter projects were supporting both by the time I created this starter project. So the idea was born to create my very own. And here we are 🎉

A few things might be familiar when you've worked with other starter projects before. I borrowed many ideas (and will continue to do so) from Create React App, React Starter Kit and other great starter projects because my intention was to create an up-to-date starter project for myself based on best practices and not to completely reinvent the wheel in every possible way just for the sake of it.

Goals

My goal is to provide a well-tested, regularly maintained, easily configurable and adjustable React Starter Project with support for server side rendering that gives you a good basis to start your own project on. As minimal as possible with as much functionality as necessary.

I use this Starter Project in several real-word projects so it is battle-tested and everytime I fix a bug or add a feature I find useful I will also update this Starter Project. I will also keep the dependencies up-to-date on a regular basis and will also stay updated with all the latest and greatest best practices in the React world and integrate them if possible and useful!

If you have any questions you can always open an issue on Github or reach out to me on Twitter!

Features

This project has out-of-the-box support for the following things:

  • General Setup

    • 🔥 Babel 7
    • 📦 Webpack 4
    • 🔥 ESLint 7 (with a set of custom rules which may be mostly identical to AirBnB with some personal flavor added)
    • 🔥 TypeScript (via Babel)
    • 🔥 Prettier
    • 🔥 Jest
    • 🐐 React Testing Library
    • ✅ React i18next for multi language support
    • ✅ Server Side Rendering with Express
    • 🏎 React Fast Refresh
    • ✅ CSS Modules
    • ✅ PostCSS
    • ✅ Precommit hooks via lint-staged + Husky
    • ✅ Optional static build without the need for Node.js on the server
    • 📕 Support for Storybook (>= 5.0.0)
  • Libs and Dependencies

    • ✅ React i18next for multi language support
    • ⚛ React 16.x (latest), with Hooks!
    • ✅ Redux + Thunk middleware
    • ✅ Immer
    • ✅ Reselect
    • ✅ React Router 5
    • ✅ React Helmet

Since it's only using standard APIs so far it is ready to be used with the new React Suspense feature coming in React 17!

Installation

As a general recommendation you should create a fork of this project first or use GitHub's use this template function so you can adjust it to your own needs, add all the dependencies you need and commit everything back into your own repository.

Once you've forked the repository here on Github, clone it, cd into the directory and run yarn (or npm install) on your command line to install all the dependencies. You're ready to go now!

Usage

There are npm scripts for all the relevant things. The server will always be started on port 8500 unless otherwise specified in process.env.PORT. You can use a .env file to specify env vars. If you want to use them in your client side code, don't forget to add them in config/env.js.

Noteworthy scripts:

yarn start

Starts the app in development mode: creates a new client and server dev build using webpack, starts the Express server build (for both file serving and server side pre-rendering) and keeps webpack open in watchmode. Updates the app (if possible) on change using HMR.

yarn build

Creates a new build, optimized for production. Does not start a dev server or anything else.

yarn test

Run all tests using jest.

yarn test:update

Update all Jest snapshots (if there are any)

yarn lint:js

Run ESLint for all JavaScript and TypeScript files

yarn lint:css

Run Stylelint for all CSS files

yarn lint

Run lint:js and lint:css in parallel

yarn analyze

Starts webpack-bundle-analyzer to give you the opportunity to analyze your bundle(s)

yarn depgraph

Creates an image of your dependency graph. Requires GraphVIZ to be in your system's PATH

yarn plop

Run plop to create new React components or Redux reducers via CLI

Environment Variables

There are a few environment variables you can set to adjust the setup to your needs

Variable Default Description
PORT 8500 Port number your application will be served on.
HOST http://localhost Host (including protocol!) your application will be served on. This is usually neglectable as most of the time your application will be served via remote proxy (e.g. Nginx) on localhost. Note: this is only for convenience. The server itself will not be bound exclusively to that host.
DEVSERVER_HOST http://localhost Optional. Different host for the Webpack Dev Server to be served on.

Tricks

Client side version (opt-in)

Beginning with v1.3.0, a static index.html is also generated and written to your clientBuild directory. You are now able to deploy the build/client directory to a static webhost (such as Netlify or AWS S3) and serve your application from there!

For the generation of the index.html the server side build gets started right after building, a headless Chrome then visits the site and writes the content of the server side response to your client directory. So you still need the src/server directory and the server side build but you're now flexible and can decide on your own whether you want to have the full server side experience or only deploy your completely static app somewhere.

Component scaffolding using plop

Along with this starter kit comes plop - a great command line tool to keep the structure of your Redux components and Redux reducers consistent. Run yarn plop (or npm run plop) to have components and Redux reducers created for you automatically! Just enter a name, answer a few questions and you're ready to go! You can of course adjust everything to your needs. All Plop templates can be found in the config/plop directory.

📕 Storybook support

I've successfully tested Storybook and it integrates seamlessly and without any issues into this setup. If you want to add Storybook to your project, install Storybook ^4.0.0 and run getstorybook to have the basic setup created for you. You must then replace all the content in .storybook/webpack.config.js with the following line:

module.exports = require('../config/webpack.config.js/storybook');

Afterwards you should be able to run yarn storybook to start the Storybook Dev Server.

Keep your project up to date

If you want your project to stay up to date with recent changes to this project, you can add React SSR Starter as remote to your local git repo. Use the following line:

git remote add upstream [email protected]:manuelbieh/react-ssr-setup.git

More on that can be found on Github: Syncing a fork.

Avoid source map generation for faster builds

In some cases you might not want to generate source maps for the generated files. In this case you can set the OMIT_SOURCEMAP environment variable to true. No source map files will be generated then. This works no matter if you're in devmode or building for production.

Change the port of the dev environment

By default if you run yarn start the development server will use port 8500. You can change this by specifying a PORT environment variable.

Import SVGs as ReactComponent

You can import SVG files as React components exactly the way you can do it in Create React App 2.0:

import { ReactComponent as Logo } from './Logo.svg';

Then you can use it in JSX like <div><Logo /></div>.

Here is a video that explains that a bit more.

Caveats

  • [1] MiniCSSExtractPlugin doesn't play nicely with consecutive builds in Webpack's watchmode yet (Github issue here). So I'm using ExtractTextWebpackPlugin until this is fixed Fixed! 490e6e9
  • [2] Hot Module Replacement is still a bit buggy. Not all components have been configured and updated to play nicely with HMR (namely Redux and React-Router) Seems to be fixed (still validating) 66875a1
  • Running the build in production: I strongly recommend to serve your static assets using Nginx or Apache instead of the Express.static middleware. That's how I usually do it and that's why you won't see any assets when starting the production server build with Node. If you still want to use Express.static in production despite the warning, have a look at the first few lines of ./src/server/index.js. There's a short comment with a description what you need to do.

Todo

  • Replace ExtractTextWebpackPlugin with MiniCSSExtractPlugin once it's working properly
  • Get HMR working (done, mostly)
  • Add HMR for Redux
  • Add HMR for CSS Modules (depends a bit on MiniCSSExtractPlugin) (using ExtractTextWebpackPlugin)
  • Add React Error Overlay from Create-React-App
  • Add react-loadable or react-universal-component (or both, still investigating what makes most sense). Update: react-loadable is out due to questionable license change Just use React.lazy which was introduced in React 16.6.
  • Improve server side template
  • Add (and use) react-helmet
  • Add/improve server side chunk loading - Wait for the new React Fizz Renderer to land
  • Add test setup using Jest
  • Add optimize-css-assets-webpack-plugin and postcss-safe-parser similar to how CRA 2 is doing it
  • Modify svg-loader babel-loader so SVGs can be imported as React component (see CRA 2)
  • Add proper offline support using Workbox
  • Document i18n functionality (scan, pull, push, ...)
  • Move i18n scripts to an external package to clean up the dependency tree
  • Fine tuning different minor things (ongoing task)

Changelog

Moved to its own file: CHANGELOG.md

License

MIT.

react-ssr-setup's People

Contributors

aimeelaplant avatar andriibyk avatar dependabot[bot] avatar limeandcoconut avatar manuelbieh avatar snyk-bot avatar sverweij avatar vinayraghu avatar youmoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-ssr-setup's Issues

Question: res.locals

Hi! First of all I would thank you for this project, its truly awesome!
Recently I moved to @loadable/component + ssr. But still can't understand one thing in your code:

css={[res.locals.assetPath('bundle.css'), res.locals.assetPath('vendor.css')]}

There is res.locals.assetPath function there. But I can't realize where it appear from? If I do console.log I'll get another functions which I suggest related to chunk extractor or something like that. But I wan't keep my res.locals clean. How can I remove it?

{
user: null // passportjs
store: {...}, // it's store
history: {...}, // it's history
...
// where next func came from?
  getSources: [Function: getSources],
  getStylesheetSources: [Function: getStylesheetSources],
  getStylesheets: [Function: getStylesheets],
  getJavascriptSources: [Function: getJavascriptSources],
  getJavascripts: [Function: getJavascripts],
  getImageSources: [Function: getImageSources],
  getImages: [Function: getImages],
  getManifest: [Function: getManifest],
  assetPath: [Function: assetPath],
  imageTag: [Function: imageTag],
  javascriptTag: [Function: javascriptTag],
  stylesheetTag: [Function: stylesheetTag] }

Search trough project didn't found anything

lazy loading

Hi,

I tried React lazy as you recommend, but it isn't supported for server-side rendering.
Is there any workaround you know of?
Or will you change your mind to implement react loadable? They changed their license back so it should be ok.

Thanks

Upgrade to React Helmet 6 once it is released to avoid maximum call stack error

When using this:

<Helmet
    defaultTitle="React SSR Starter – TypeScript Edition"
    titleTemplate="%s – React SSR Starter – TypeScript Edition"
>
    <link rel="icon" type="image/png" href={favicon} sizes="16x16" />
</Helmet>

This error occurs after a (short) while: nfl/react-helmet#373

Temporary workaround is to use the following until [email protected] stable is released:

<Helmet
    defaultTitle="React SSR Starter – TypeScript Edition"
    titleTemplate="%s – React SSR Starter – TypeScript Edition"
    link={[{ rel: 'icon', type: 'image/png', href: favicon }]}
/>

Problem with running eslint command

Hello! Thank you for your work!

This command from package.json not correctly working for me:

...
"lint:js": "eslint src/**/*.{js,ts,tsx}",
...

But if I add quotes - working fine.

...
"lint:js": "eslint \"src/**/*.{js,ts,tsx}\"",
...

Could you check it, please?

Migrate to TypeScript

It's time to say good bye to Flow. It gets more and more annoying, eats more and more RAM. Whenever I start VSCode my CPU cooler goes crazy and the reason for that is Flow. While I still very much like the idea of Flow as being a type checker only without a whole own ecosystem of tools I still see no other choice due to its laggyness and performance hunger.

I will soon start to configure everything to be TypeScript ready (which I have done in my last client project already) and I will use TypeScript with Babel 7 for the type checking only. So it should basically not feel much different to Flow and will be completely opt-in.

I will leave the Flow config intact so you can still install and use Flow if you prefer that.

How can loader SCSS

I add some code below in loaders.js
When I run yarn start it runs ok , but yarn build, It can't get css. Please help me.

const scssLoaderServer = {
  test: /\.scss$/,
  exclude: /node_modules/,
  use: [
    {
      loader: 'css-loader/locals',
      options: {
        camelCase: true,
        importLoaders: 1,
        modules: true,
        localIdentName: '[name]__[local]--[hash:base64:5]'
      }
    },
    {
      loader: 'sass-loader',
      options: {
        sourceMap: true
      }
    }
  ]
};`

express.static on both ports

Hi, again. Could you please explain why you serve a client bundle on both 8500(in src/server/index.js) and 8501(scripts/start.js) ports if you use only that served client bundle which is on host 8501. You setup HMR for the client bundle on 8501 and you link styles and scripts to HTML response which are on 8501 host too. But you do nothing with the served client bundle which is on host 8500. Thank you.

here
https://github.com/manuelbieh/react-ssr-setup/blob/master/src/server/index.js#L20
and here
https://github.com/manuelbieh/react-ssr-setup/blob/master/scripts/start.js#L72

Assets loading

Hello,

I have simple question about assets loading like manifest, favicons and other stuff, how i can load it from shared/assets? The problem is that wasn't copy those files into build folder.

How i can solve this little trouble?

Thanks

Error: Cannot find module 'core-js/fn/string/pad-start'

I liked your approach and setup but was confronted with a build error; details below:

OS: macOS Mojave 10.14
NPM: 6.4.1
Node: 10.13.0

Repro steps:

  1. clone repo
  2. npm i
  3. npm start

Console output:
Note: I removed the absolute path to the directory react-ssr-setup.

> [email protected] start ./react-ssr-setup
> cross-env NODE_ENV=development node scripts/start.js

[2018-11-30T20:15:49.130Z] [client] Compiling
[2018-11-30T20:15:49.155Z] [server] Compiling
Hash: 1fa189826e0428df7eea
Version: webpack 4.26.1
Time: 3884ms
Built at: 11/30/2018 12:15:53 PM
    Asset    Size  Chunks             Chunk Names
server.js  89 KiB  server  [emitted]  server
Entrypoint server = server.js
[0] multi ./node_modules/@babel/polyfill/lib/index.js ./src/server/index.js 40 bytes {server} [built]
[./config/paths.js] 574 bytes {server} [built]
[./node_modules/@babel/polyfill/lib/index.js] 893 bytes {server} [built]
[./src/server/index.js] 1.71 KiB {server} [built]
[./src/server/render.js] 885 bytes {server} [built]
[./src/shared/store/index.js] 1.46 KiB {server} [built]
[body-parser] external "body-parser" 42 bytes {server} [built]
[chalk] external "chalk" 42 bytes {server} [built]
[core-js/es6] external "core-js/es6" 42 bytes {server} [built]
[core-js/fn/array/includes] external "core-js/fn/array/includes" 42 bytes {server} [built]
[core-js/fn/object/entries] external "core-js/fn/object/entries" 42 bytes {server} [built]
[core-js/fn/object/get-own-property-descriptors] external "core-js/fn/object/get-own-property-descriptors" 42 bytes {server} [built]
[core-js/fn/object/values] external "core-js/fn/object/values" 42 bytes {server} [built]
[core-js/fn/promise/finally] external "core-js/fn/promise/finally" 42 bytes {server} [built]
[core-js/fn/string/pad-end] external "core-js/fn/string/pad-end" 42 bytes {server} [built]
    + 34 hidden modules
webpack built client 14b9a97258757ac60758 in 5157ms
ℹ 「wdm」: Time: 5157ms
Built at: 11/30/2018 12:15:54 PM
                    Asset       Size  Chunks                    Chunk Names
assets/react.9a28da9f.svg   7.72 KiB          [emitted]
               bundle.css   18.8 KiB  bundle  [emitted]         bundle
                bundle.js    136 KiB  bundle  [emitted]         bundle
            manifest.json  270 bytes          [emitted]
 vendor.c63ffa3b.chunk.js   4.34 MiB  vendor  [emitted]  [big]  vendor
Entrypoint bundle [big] = vendor.c63ffa3b.chunk.js bundle.css bundle.js
Child mini-css-extract-plugin node_modules/css-loader/index.js??ref--4-oneOf-1-2!node_modules/postcss-loader/src/index.js??ref--4-oneOf-1-3!src/shared/App.module.css:
    Entrypoint mini-css-extract-plugin = *
Child mini-css-extract-plugin node_modules/css-loader/index.js??ref--4-oneOf-1-2!node_modules/postcss-loader/src/index.js??ref--4-oneOf-1-3!src/shared/components/Features/Features.module.css:
    Entrypoint mini-css-extract-plugin = *
ℹ 「wdm」: Compiled successfully.
internal/modules/cjs/loader.js:582
    throw err;
    ^

Error: Cannot find module 'core-js/fn/string/pad-start'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
    at Function.Module._load (internal/modules/cjs/loader.js:506:25)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at eval (webpack:///external_%22core-js/fn/string/pad-start%22?:1:18)
    at Object.core-js/fn/string/pad-start (./react-ssr-setup/build/server/server.js:1083:1)
    at __webpack_require__ (./react-ssr-setup/build/server/server.js:683:30)
    at fn (./react-ssr-setup/build/server/server.js:60:20)
    at eval (webpack:///./node_modules/@babel/polyfill/lib/index.js?:7:1)
    at Object../node_modules/@babel/polyfill/lib/index.js (./react-ssr-setup/build/server/server.js:774:1)

Use https for local dev server

First of all thanks for an amazing repo.

How can I serve local files in development mode with https server? with webpack-dev-server you get a https: true option but I guess that is not available here?

Hot css chunks

Hey dude. I’ve gotton around to updating HMR CSS chunking. If it’s still a challenge for you, the upcoming release will work standalone and perform true HMR.
Check faceyspaceys css chunk plugin. I’ve commented in an issue you were part of.

Async data html not visible in html dom

Hi
Thanks for the great SSR setup. I have implemented all the things but i am not able to see Async data html.

Data from API not visible in DOM. Do we need to do anything else.
Please guide me.

Implement a nicer demo layout

When you kickstart a project with Gatsby or CRA you actually see a demo page in a clean and simple but nice looking layout. When you start React SSR Setup after cloning the repo it just looks plain and ugly. Maybe it's time to provide a layout that's a bit nicer than the current one.

Build Performance Warnings

In the build npm process output you get two warnings messages from webpack performance issues. This is the full message:

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
  vendor.c2612e40.chunk.js (434 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  bundle (456 KiB)
      vendor.c2612e40.chunk.js
      bundle.77a055c929b7e8b02f25.css
      bundle.6e20225a.js


WARNING in webpack performance recommendations:
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/

I think it could be a performance improvement to resolve this by a new webpack implementation.

How using file server.js after build ?

Hi,
I'm using resource and build it. But when the build a show file server.js in folder build/server/server.js and I don't know using it.
So, how to use file server.js. Thank you so much :)

unexpected token export lodash-es

Hi, I try to use your ssr setup for an existing project and i have a problem with lodash-es, which has es module import/export, and can't be compiled by server, i try to use babel/plugin-transform-modules-commonjs, and include node_modules for babel-loader, but gave no result :(, can you help me pls?

Serve for production

Hi,

How are you supposed to serve your build for in production?
I tried something like node dist/server/server.js but I got troubles with assets.

Thanks for sharing your configuration.

How does build/.../server.js find the client?

Hi,

First of all, good job with this repo. It's a really great example.

I think this should be on stackoverflow but I will post it here anyway. I followed this project as an example for my own project, but there's something that I'm not being able to fix.

My project is really similar to yours, the biggest difference is that my client and my server are in different packages.

Right now whenever I use your start.js it builds both server and client however it fails saying the following:

C:\Users\Leandro Soares\source\repos\poc-modular\poc-frame-client\src\entry.js
(function (exports, require, module, __filename, __dirname) { import React from "react";
                                                                     ^^^^^
SyntaxError: Unexpected identifier

Noticing the first line I can see that server.js is calling poc-frame-client entry.js which is supposed, but I was expecting the transpiled version to call something else than the source package.

I think this has to do with the resolvers.js you have, more specifically resolve.modules.

So my question is, since src/server/render.js imports App from the Shared and the final bundle build/server/server.js doesn't contain the code for App, how does it find it?

Edit 1
I guess I have this problem because my package that contains App is symlinked.

Manifest localhost

Hi. You generate manifest.json under build/client/static with the following content:

{
  "bundle.css": "http://localhost:8501/static/bundle.css",
  "bundle.js": "http://localhost:8501/static/bundle.js",
  "vendor.js": "http://localhost:8501/static/vendor.4e558245.chunk.js",
  "assets/react.svg": "http://localhost:8501/static/assets/react.9a28da9f.svg"
}

Could you tell where in the code you add localhost prefix for file aliases? I mean http://localhost:8501/static/assets/react.9a28da9f.svg?

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Clarification on env vars?

I've gotten myself mixed up and I could use a sanity check. Could you explain again why it's necessary to pass NODE_ENV to Webpack? I must be missing something but where is it not using the same process?

const webpackConfig = require('../config/webpack.config.js')(process.env.NODE_ENV || 'development');

// and

module.exports = (env = 'production') => {
...
}

how do use ant.design UI in this project?

I try write it in babal.config.js:

['import', { 'libraryName': 'antd', 'libraryDirectory': 'lib', 'style': 'css' }],

and use:
import { Modal } from 'antd'

but, throw error:

`
/Users/zkeyword/Documents/ssr/node_modules/antd/lib/style/index.css:7
body {
^
SyntaxError: Unexpected token {
at Module._compile (internal/modules/cjs/loader.js:718:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
at Module.load (internal/modules/cjs/loader.js:641:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
at Module.require (internal/modules/cjs/loader.js:681:19)

`

Importing CSS files causes TypeError: this[MODULE_TYPE] is not a function

App.css

body {
    background-color: #fcfcfc;
    display: block;
    font-family: Helvetica Neue, Arial, sans-serif;
    font-feature-settings: "kern", "liga", "clig", "calt";
    font-kerning: normal;
    font-size: 16px;
    font-weight: normal;
    letter-spacing: 0.7px;
    margin: 0;
    position: relative;
    text-rendering: optimizelegibility;
    word-wrap: break-word;
}

App.tsx

import React from "react"

import NavigationBar from "../shared/components/navigation_bar"

import "./App.css" // importing it here

interface IAppProps {
    children: React.ReactNode | React.ReactNode[],
}

const App = ({ children }: IAppProps) => (
    <>
        <NavigationBar />
        {children}
    </>
)

export default App

Results in:

[2019-06-27T16:51:24.881Z] ./src/shared/App.css
[2019-06-27T16:51:24.881Z] Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
[2019-06-27T16:51:24.881Z] TypeError: this[MODULE_TYPE] is not a function
[2019-06-27T16:51:24.885Z] Failed to compile server
webpack:///./src/shared/App.css?:1
throw new Error("Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):\nTypeError: this[MODULE_TYPE] is not a function\n    at childCompiler.runAsChild

Question: Dockerize

I currently try to Dockerize my Project on this Template with the help of a Container as a Builder
But the Building is not working correctly in any Dockerfile variation i know.
Therefore my Question does a "Example" Dockerfile exists to Dockerize a Application based on this template?

Loading data from API using SSR.

I really like your setup repo just wondering how would you go about importing data from API to be available on server render?

How to pass a language variable from ssr server to client?

When we use the URL with the locale parameter, the locale is expected to be transmitted to the client. For example,
http://localhost/en/my-page -> en is the locale parameter
We want to transfer the locale parameter to the client.

i18next.init({
fallbackLng: 'en', <<- we want to change this
fallbackNS: ['translation'],
resources: { ... },
});

i18next-express-middleware does not work because in the react-ssr-setup we use react-router instead of express-router

Make dev host configurable

Currently the default development host is localhost with no way to configure or change it. There should be an env var to configure other hostnames for development.

Express.static good enought ? Nginx Apache not necessary ?

What you mean when you said that in commentary https://github.com/manuelbieh/react-ssr-setup/blob/master/src/server/index.ts#L20

// Use Nginx or Apache to serve static assets in production or remove the if() around the following
// lines to use the express.static middleware to serve assets for production (not recommended!)
if (process.env.NODE_ENV === 'development') {
    app.use(paths.publicPath, express.static(path.join(paths.clientBuild, paths.publicPath)));
}

Me I would like to use express.static middleware to serve assets, what's wrong with it ?

Serve multiple routes with different components.

I looked through the code but can't find an example of serving multiple routes with a 404 if the route isn't found.

I'm assuming adding a new route would be somewhere in src/server/render.js here:

        <Provider store={req.store}>
            <Router location={req.url} context={{}}>
                <IntlProvider>
                    <App />
                </IntlProvider>
            </Router>
        </Provider>

And to serve the client router, I would have to add the same thing in src/client/index.js?

Do you have an example of serving multiple components with routes? The current configuration is a catch all, so it matches any link to the browser.

With react-router, the documentation says to do this for multiple routes:

But this context switching doesn't work in src/server/render.js.

Project Structure for scalability and maintainability

Hi Manuel, do you have any suggestion how to structure for scalability and maintainability?

I was reading this article: https://levelup.gitconnected.com/structure-your-react-redux-project-for-scalability-and-maintainability-618ad82e32b7

And I was checking your project structure, you have shared > store > app > actions/reducer, sounds different compared to other structures that i saw, I'll have many pages, I was thinking something like this:

src
| src
|-- client
|---- actions
|---- pages
|---- reducers
....

or

src
| src
|-- client
|---- home (page)
|------ actions, reducers (duck pattern)
|---- about (page)
|------ actions, reducers (duck pattern)
....

What is your thoughts?

And awesome setup, its the stack i was looking for 👍 very nice

ConnectedRouter always loading / on hydration due to unpopulated router state from server

EDIT:
I was being foolish here and misrepresented the issue.
The problem is not that <StaticRouter> isn't rendering the correct route, it's that <ConnectedRouter> is switching to / no matter what is rendered by <StaticRouter>.

The issue seems to be that state.router.location isn't being initialized to the proper route.

I knew this was actually the problem but wrote the wrong thing initially because I'm a dummy.
☕️fixed me
/EDIT

When adding a <StaticRouter> to the app all pages are SSRed as /.

// in render.js

<Provider store={req.store}>
    <StaticRouter location={req.url} context={{}}>
        ...
    </StaticRouter>
</Provider>

const state = JSON.stringify(req.store.getState())
console.log('state', state)
// {"app":{"locale":"en_US"},
// "router":{"location":{"pathname":"/","search":"","hash":"","key":"hnge0b"},
// "action":"POP"}}

It looks to me like passing an inital state to createMemoryHistory would solve this problem. Something like:

return createMemoryHistory({
    initialEntries: [req.url],
})

This seems like a pretty large oversight, however, and I imagine there's a better way to do this or a fix I'm not aware of? Is this an error?

EDIT:
I also tried:

// sec/server/index.js
app.use((req, res, next) => {
    req.store = configureStore()
    req.store.dispatch(push('/page1')) //Add this line
    return next()
})

To no avail...
/EDIT

How is the production build of an application started

I have ran npm run build and the build directory was generated containing the client and server directories. Then I tried running node build/server/server.js and it ran the application, but without the styles loaded.

Is there a way to run the production build of the application using node rather than npm start?

i18next-scanner doesn't pick up Trans tags

Hi,
I am wondering if you were able to successfully extract Trans tags from the transpiled js files?
If I modify src/shared/components/Features/index.tsx to look like this:

import React from 'react';
import { Trans } from 'react-i18next';
import { withTranslation, WithTranslation } from 'react-i18next';
import css from './Features.module.css';

const Features = ({ t }: WithTranslation) => (
    <React.Fragment>
        <h2>{t('features')}</h2>
        <ul className={css.wrapper}>
            <li className={css.react}>React 16.x (latest)</li>
            <li className={css.webpack}>Webpack 4</li>
            <li className={css.hot}>Babel 7</li>
            <li className={css.hot}>ESLint 5</li>
            <li className={css.hot}>TypeScript (using Babel 7)</li>
            <li className={css.hot}>Jest 24</li>
            <li>React Testing Library</li>
            <li>React Router 5</li>
            <li>Redux (+ Thunk)</li>
            <li>Immer</li>
            <li>Reselect</li>
            <li>React Helmet</li>
            <li>Express Webserver + Server Side Rerendering</li>
            <li>{t('i18n-support')}</li>
            <li>CSS Modules</li>
            <li>PostCSS</li>
            <li>Prettier (incl. precommit-hook via lint-staged + husky)</li>
            <li>HMR (buggy, see Readme)</li>
            <Trans i18nKey="some.key">Some text</Trans>
        </ul>
    </React.Fragment>
);

export default withTranslation()(Features);

Then if I run yarn i18n:scan; it extracts the ones with t() but not the Trans tags. Would you have any idea why is that or did anyone get it working?

I read all the issues from i18next-scanner and read through the documentation multiple times. In theory the setup you have should work out of the box. (Except if there is no keys set if you want to use the value as fallback)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.