Skip to content

Commit 58ca92b

Browse files
Merge pull request #127 from faceyspacey/webpack-4
Updates to support Webpack 4 & Universal 3
2 parents bf7f1bf + d5ad0de commit 58ca92b

File tree

9 files changed

+2573
-1512
lines changed

9 files changed

+2573
-1512
lines changed

.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[ignore]
22
.*/node_modules/config-chain/.*
33
.*/node_modules/npmconf/.*
4+
.*/node_modules/chalk/.*
45

56
[include]
67

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ dist
22
coverage
33
node_modules
44
*.log
5+
.idea
6+
.DS_Store

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ webpack.config.js
1919
.flowconfig
2020
*.png
2121
yarn.lock
22+
.idea

README.md

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,33 @@
4141
</p>
4242

4343
<p align="center">
44-
🍾🍾🍾 <a href="https://github.com/faceyspacey/universal-demo">GIT CLONE 2.0 LOCAL DEMO</a> 🚀🚀🚀
44+
🍾🍾🍾 <a href="https://github.com/faceyspacey/universal-demo">GIT CLONE 3.0 LOCAL DEMO</a> 🚀🚀🚀
4545
</p>
4646

47-
For "power users" the SPA is dead. If you're not universally rendering on the server you're doing it "wrong." You're losing money for you, your clients, your employers. All hail the Google god.
47+
- [React Universal Component](#react-universal-component)
48+
* [Intro](#intro)
49+
* [What makes Universal Rendering so painful](#what-makes-universal-rendering-so-painful)
50+
* [Installation](#installation)
51+
* [Other Packages You Will Need or Want](#other-packages-you-will-need-or-want)
52+
* [API and Options](#api-and-options)
53+
* [Flushing for SSR](#flushing-for-ssr)
54+
* [Preload](#preload)
55+
* [Static Hoisting](#static-hoisting)
56+
* [Props API](#props-api)
57+
* [Usage with CSS-in-JS libraries](#usage-with-css-in-js-libraries)
58+
* [Usage with two-stage rendering](#usage-with-two-stage-rendering)
59+
* [Universal Demo](#universal-demo)
60+
* [Contributing](#contributing)
61+
* [Tests](#tests)
62+
* [More from FaceySpacey](#more-from-faceyspacey-in-reactlandia)
4863

49-
The real problem has been **simultaneous SSR + Splitting**. If you've ever attempted such, *you know*. This is a one-of-a-kind solution that brings it all together.
64+
65+
## Intro
66+
67+
For "power users" the traditional SPA is dead. If you're not universally rendering on the server, you're at risk of choking search engine visibility. As it stands, SEO and client-side rendering are not a match for SSR. Even though many search engines claim better SPA indexing, there are many caveats. **Server-side rendering matters: [JavaScript & SEO Backfire – A Hulu.com Case Study](https://www.elephate.com/blog/javascript-seo-backfire-hulu-com-case-study/)**
68+
69+
70+
The real problem has been **simultaneous SSR + Splitting**. If you've ever attempted such, *you know*. Here is a one-of-a-kind solution that brings it all together.
5071

5172
*This is the final universal component for React you'll ever need, and it looks like this:*
5273

@@ -63,22 +84,19 @@ export default () =>
6384

6485
It's made possible by our [PR to webpack](https://github.com/webpack/webpack/pull/5235) which built support for ```require.resolveWeak(`'./${page}`)```. Before it couldn't be dynamic--i.e. it supported one module, not a folder of modules.
6586

66-
You no longer need to create a hash of all your universal or loadable components. You can frictionlessly support multiple components in one HoC as if imports weren't static. This seamingly small thing--we predict--will lead to universal rendering finally becoming commonplace. It's what a universal component for React is supposed to be.
87+
Dont forget to check out [webpack-flush-chunks](https://github.com/faceyspacey/webpack-flush-chunks) - it provides the server with info about the render so it can deliver the right assets from the start. No additional async imports on first load. [It reduces time to interactive](https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive)
6788

68-
Of course, you also need [webpack-flush-chunks](https://github.com/faceyspacey/webpack-flush-chunks) to bring this together server-side. Ultimately that's the real foundation here and the most challenging part. Packages in the past like *React Loadable* did not address this aspect. They excelled at the SPA. In terms of universal rendering, they got you maybe 15% of the way by providing the module IDs rendered. There's a lot more than that.
89+
> DEFINITION: "Universal Rendering" is *simultaneous* SSR + Splitting, not trading one for the other.
6990
70-
**Webpack Flush Chunks** ensures you serve all the chunks rendered on the server to the client in style. To be clear, it's been impossible until now. This is the first general solution to do it, and still the only one. You *must* use it in combination with React Universal Component to fulfill the universal code splitting dream.
71-
72-
In the future both packages will be distilled into one product called `universal-render`--or ***"Universal"*** for short. The transition will be seamless. We're making this space as easy as possible for "power users" like yourself that prefer the *frameworkless* approach over the constraints of a framework like Next.js.
7391

74-
> DEFINITION: "Universal Rendering" is *simutlaneous* SSR + Splitting, not trading one for the other.
92+
<details> <summary> Read more about Chunk Flushing</summary>
7593

76-
## I didn't know Universal Rendering was such a pain...
77-
That's probably because you were trapped in SPA land. If you didn't know how much of a pain in the ass *universal rendering* has been, check this quote from the React Router docs:
94+
Gone are the days of holding onto file hashes, manual loading conventions, and elaborate lookups on the server or client. You can frictionlessly support multiple components in one HoC as if imports weren't static. This seemingly small thing--we predict--will lead to universal rendering finally becoming commonplace. It's what a universal component for React is supposed to be.
7895

79-
![require-universal-component react-router quote](./react-router-quote.png)
96+
[webpack-flush-chunks](https://github.com/faceyspacey/webpack-flush-chunks) brings it together server-side Ultimately that's the real foundation here and the most challenging part. Packages in the past like *React Loadable* did not address this aspect. They excelled at the SPA. In terms of universal rendering, but stumbled on provisioning whats required beyond the scope of knowing the module IDs that were rendered. There are a few extras to take into account.
8097

81-
> If you were already in the know, you're probably one of our first users, and we thank you for your support and feeling the essence of our mission. Thank god this is over!
98+
**Webpack Flush Chunks** ensures you serve all the chunks rendered on the server to the client in style. To be clear, it's been impossible until now. This is the first general solution to do it, and still the only one. You *must* use it in combination with React Universal Component to fulfill the universal code splitting dream.
99+
</details>
82100

83101

84102
## Installation
@@ -105,7 +123,7 @@ That's probably because you were trapped in SPA land. If you didn't know how muc
105123

106124
- [webpack-import-will-soon-fetch-js-and-css-heres-how-you-do-it-today](https://medium.com/faceyspacey/webpacks-import-will-soon-fetch-js-css-here-s-how-you-do-it-today-4eb5b4929852)
107125

108-
## Other Packages You Will Need/Want
126+
## Other Packages You Will Need or Want
109127

110128
To be clear, you can get started with just the simple `HoC` shown at the top of the page, but to accomplish universal rendering, you will need to follow the directions in the *webpack-flush-chunks* package:
111129

@@ -115,7 +133,7 @@ And if you want CSS chunks *(which we highly recommend)*, you will need:
115133
- [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin)
116134

117135

118-
## API + Options
136+
## API and Options
119137

120138

121139
```js
@@ -173,6 +191,13 @@ onLoad: (module, info, props, context) => {
173191

174192
- `loadingTransition` when set to `false` allows you to keep showing the current component when the `loading` component would otherwise show during transitions from one component to the next.
175193

194+
## What makes Universal Rendering so painful
195+
196+
One wouldn't expect it to be. Sadly the SSR part of react hasn't been as innovative as the CSR side.
197+
198+
If you didn't know how much of a pain in the ass *universal rendering* has been, check this quote from the **React Router** docs:
199+
200+
![require-universal-component react-router quote](./react-router-quote.png)
176201

177202
## Flushing for SSR
178203

package.json

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,28 @@
55
"main": "dist/index.js",
66
"typings": "index.d.ts",
77
"author": "James FaceySpacey Gillmore <[email protected]> (http://www.faceyspacey.com)",
8+
"contributors": [
9+
"Zack Jackson <[email protected]> (https://github.com/ScriptedAlchemy)"
10+
],
811
"license": "MIT",
912
"bugs": {
1013
"url": "https://github.com/faceyspacey/react-universal-component/issues"
1114
},
1215
"homepage": "https://github.com/faceyspacey/react-universal-component#readme",
16+
"keywords": [
17+
"universal",
18+
"ruc",
19+
"unviersal react",
20+
"ssr",
21+
"code splitting",
22+
"aggressive code splitting",
23+
"lodable",
24+
"react",
25+
"async component",
26+
"universal react",
27+
"async rendering",
28+
"webpack 4"
29+
],
1330
"scripts": {
1431
"build": "babel src -d dist",
1532
"flow-copy": "flow-copy-source src dist",
@@ -19,7 +36,7 @@
1936
"test": "jest",
2037
"lint": "eslint --fix ./",
2138
"format": "prettier --single-quote --parser=flow --semi=false --write '{src,__tests__,__fixtures__}/**/*.js' && npm run lint",
22-
"precommit": "lint-staged --verbose && npm test",
39+
"precommit": "lint-staged && npm test",
2340
"cm": "git-cz",
2441
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
2542
"prepublish": "npm run clean && npm run build && npm run flow-copy"
@@ -29,7 +46,7 @@
2946
"babel-core": "^6.24.0",
3047
"babel-eslint": "^7.2.3",
3148
"babel-plugin-transform-flow-strip-types": "^6.22.0",
32-
"babel-plugin-universal-import": "^1.0.5",
49+
"babel-plugin-universal-import": "^3.0.0",
3350
"babel-preset-es2015": "^6.24.1",
3451
"babel-preset-flow": "^6.23.0",
3552
"babel-preset-react": "^6.24.1",
@@ -44,12 +61,12 @@
4461
"eslint-plugin-react": "^7.0.1",
4562
"flow-bin": "^0.49.1",
4663
"flow-copy-source": "^1.1.0",
47-
"husky": "^0.13.2",
64+
"husky": "^0.14.3",
4865
"jest": "^20.0.4",
49-
"lint-staged": "^3.4.0",
66+
"lint-staged": "^7.2.0",
5067
"prettier": "^1.3.1",
51-
"react": "^15.5.4",
52-
"react-test-renderer": "^15.6.1",
68+
"react": "^16.4.1",
69+
"react-test-renderer": "^16.4.1",
5370
"rimraf": "^2.5.4",
5471
"semantic-release": "^6.3.6",
5572
"slash": "^1.0.0",

src/flowTypes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export type ModuleOptions = {
3737
isDynamic: boolean,
3838
modCache: Object,
3939
promCache: Object,
40-
id?: string
40+
id?: string,
41+
usesBabelPlugin?: boolean
4142
}
4243

4344
export type ComponentOptions = {

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default function universal<Props: Props>(
4444

4545
const isDynamic = hasBabelPlugin || testBabelPlugin
4646
options.isDynamic = isDynamic
47+
options.usesBabelPlugin = hasBabelPlugin
4748
options.modCache = {}
4849
options.promCache = {}
4950

src/requireUniversalModule.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export default function requireUniversalModule<Props: Props>(
4040
onError,
4141
isDynamic,
4242
modCache,
43-
promCache
43+
promCache,
44+
usesBabelPlugin
4445
} = options
4546

4647
const config = getConfig(isDynamic, universalConfig, options, props)
@@ -136,7 +137,10 @@ export default function requireUniversalModule<Props: Props>(
136137
const addModule = (props: Object): ?string => {
137138
if (isServer || isTest) {
138139
if (chunkName) {
139-
const name = callForString(chunkName, props)
140+
let name = callForString(chunkName, props)
141+
if (usesBabelPlugin) {
142+
name = name.replace(/\//g, '-')
143+
}
140144
if (name) CHUNK_NAMES.add(name)
141145
if (!isTest) return name // makes tests way smaller to run both kinds
142146
}

0 commit comments

Comments
 (0)