Skip to content

Commit 9dbb7c9

Browse files
wip support react-18 stream render
1 parent 27e47a7 commit 9dbb7c9

File tree

9 files changed

+66
-86
lines changed

9 files changed

+66
-86
lines changed

babel.config.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ function isWebpack(caller) {
99
module.exports = (api) => {
1010
const web = api.caller(isWebTarget);
1111
const webpack = api.caller(isWebpack);
12-
1312

1413
api.cache.using(() => process.env.NODE_ENV === "production");
1514

@@ -39,7 +38,6 @@ module.exports = (api) => {
3938
// plugins.push("@babel/plugin-syntax-dynamic-import");
4039
plugins.push("@babel/plugin-transform-runtime");
4140
plugins.push("@babel/plugin-proposal-export-default-from");
42-
plugins.push("@loadable/babel-plugin");
4341

4442
return {
4543
presets,

package.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
"@emotion/react": "^11.9.0",
2020
"@emotion/server": "^11.4.0",
2121
"@emotion/styled": "^11.8.1",
22-
"@loadable/component": "^5.15.2",
23-
"@loadable/server": "^5.15.2",
2422
"axios": "^0.27.2",
2523
"chalk": "4",
2624
"compression": "^1.7.4",
@@ -64,8 +62,6 @@
6462
"@babel/preset-env": "^7.18.2",
6563
"@babel/preset-react": "^7.17.12",
6664
"@babel/preset-typescript": "^7.17.12",
67-
"@loadable/babel-plugin": "^5.13.2",
68-
"@loadable/webpack-plugin": "^5.15.2",
6965
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
7066
"@types/compression": "^1.7.2",
7167
"@types/cookie-parser": "^1.4.3",
@@ -74,8 +70,6 @@
7470
"@types/express-session": "^1.17.4",
7571
"@types/jest": "^28.1.1",
7672
"@types/js-cookie": "^3.0.2",
77-
"@types/loadable__component": "^5.13.4",
78-
"@types/loadable__server": "^5.12.6",
7973
"@types/lodash": "^4.14.182",
8074
"@types/multer": "^1.4.7",
8175
"@types/node": "^17.0.42",

src/server/middleware/renderPage/renderP_CSR.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { ChunkExtractor } from "@loadable/server";
21
import { renderToString } from "react-dom/server";
32

43
import { ServerError } from "server/utils/error";
54
import { HTML } from "template/Html";
6-
import { manifestLoadable } from "utils/manifest";
5+
import { generateScriptElements, generateStyleElements, getAllStateFileContent, manifestStateFile } from "utils/manifest";
76

87
import { composeRender } from "./compose";
98
import { globalEnv } from "./middleware/globalEnv";
@@ -15,16 +14,37 @@ const targetRender: AnyAction = async ({ res, env, lang }) => {
1514
if (!env || !lang) {
1615
throw new ServerError("server 初始化失败", 500);
1716
}
18-
const webExtractor = new ChunkExtractor({ statsFile: manifestLoadable("client") });
19-
const linkElements = webExtractor.getLinkElements();
20-
const styleElements = webExtractor.getStyleElements();
21-
const scriptElements = webExtractor.getScriptElements();
17+
18+
// get state from state file
19+
20+
const stateFileContent = await getAllStateFileContent(manifestStateFile("client"));
21+
22+
const mainStylePaths = Object.keys(stateFileContent)
23+
.filter((file) => file.endsWith(".css"))
24+
.filter((file) => file.startsWith("main") || file.startsWith("vendor"))
25+
.map((key) => stateFileContent[key]);
26+
27+
const runtimeScript = Object.keys(stateFileContent)
28+
.filter((file) => file.endsWith(".js"))
29+
.filter((file) => file.startsWith("runtime"))
30+
.map((key) => stateFileContent[key]);
31+
32+
const mainScript = Object.keys(stateFileContent)
33+
.filter((file) => file.endsWith(".js"))
34+
.filter((file) => file.startsWith("main") || file.startsWith("vendor") || file.startsWith("react") || file.startsWith("ui"));
2235

2336
env.isSSR = false;
2437

2538
res.send(
2639
"<!doctype html>" +
27-
renderToString(<HTML env={JSON.stringify(env)} lang={JSON.stringify(lang)} script={scriptElements} link={linkElements.concat(styleElements)} />)
40+
renderToString(
41+
<HTML
42+
env={JSON.stringify(env)}
43+
lang={JSON.stringify(lang)}
44+
script={generateScriptElements(runtimeScript.concat(mainScript))}
45+
link={generateStyleElements(mainStylePaths)}
46+
/>
47+
)
2848
);
2949
};
3050

src/template/Html.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ type HTMLProps = {
1010
children?: string;
1111
cookieStorage?: StorageManager;
1212
reduxInitialState?: string;
13-
link?: React.ReactElement[];
14-
script?: React.ReactElement[];
13+
link?: JSX.Element[];
14+
script?: JSX.Element[];
1515
emotionChunks?: EmotionCriticalToChunks;
1616
helmetContext?: { helmet?: HelmetServerState };
1717
};

src/utils/manifest.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
import fs from "fs/promises";
12
import path from "path";
3+
import { createElement } from "react";
24

35
const outputPath = (env: "server" | "client"): string => (__DEVELOPMENT__ ? path.resolve(process.cwd(), "dev", env) : path.resolve(process.cwd(), "dist", env));
46

57
const manifestFile = (): string => (__DEVELOPMENT__ ? "manifest-dev.json" : "manifest-prod.json");
68

7-
const manifestLoadable = (env: "server" | "client"): string => path.resolve(outputPath(env), "manifest-loadable.json");
9+
const manifestStateFile = (env: "server" | "client"): string => path.resolve(outputPath(env), manifestFile());
810

9-
export { manifestFile, manifestLoadable };
11+
const getAllStateFileContent = async (path: string) => await fs.readFile(path, { encoding: "utf-8" }).then((c) => JSON.parse(c));
12+
13+
const generateStyleElements = (paths: string[]) => paths.map((s, i) => createElement("link", { key: i, href: s, rel: "stylesheet" }) as JSX.Element);
14+
15+
const generateScriptElements = (paths: string[]) => paths.map((s, i) => createElement("script", { key: i, src: s, async: true }) as JSX.Element);
16+
17+
export { manifestStateFile, generateStyleElements, generateScriptElements, getAllStateFileContent };

webpack/externals.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const nodeExternals = require("webpack-node-externals");
44
const externalsConfig = ({ env }) => {
55
if (env === "server") {
66
return [
7-
"@loadable/component",
87
nodeExternals({
98
// load non-javascript files with extensions, presumably via loaders
109
allowlist: [/\.(?!(?:jsx?|json)$).{1,5}$/i],

webpack/optimization.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,34 @@ const optimizationConfig = ({ env, isDev = true, isMiddleWareDevelop }) => {
3838
usedExports: true,
3939
runtimeChunk: "single",
4040
splitChunks: {
41-
chunks: "all",
42-
minSize: 20000,
43-
maxSize: 20000,
44-
minChunks: 3,
41+
minChunks: 2,
42+
minSize: 30000,
43+
4544
cacheGroups: {
4645
vendor: {
4746
test: /[\\/]node_modules[\\/]/,
48-
filename: "[name]_vendors.js",
49-
reuseExistingChunk: true,
50-
priority: -10,
51-
},
52-
default: {
53-
minChunks: 3,
54-
filename: "common_[id].js",
55-
priority: -20,
47+
enforce: true,
48+
chunks: "all",
49+
name(module) {
50+
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
51+
52+
switch (packageName) {
53+
case "react":
54+
case "react-dom":
55+
case "scheduler":
56+
case "object-assign":
57+
return "react";
58+
case "chakra":
59+
return "ui";
60+
default:
61+
return "vendor";
62+
}
63+
},
5664
},
5765
},
5866
},
5967
runtimeChunk: {
60-
name: (entrypoint) => `runtime-${entrypoint.name}`,
68+
name: "runtime",
6169
},
6270
};
6371
} else {

webpack/plugins.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@ const webpack = require("webpack");
33
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
44
// 输出所有资源路径
55
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
6-
// loadable json
7-
const LoadablePlugin = require("@loadable/webpack-plugin");
86
// 抽离css文件
97
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
108
// 快速刷新
119
const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
1210
// 打包阶段错误检查
13-
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
1411
const ESLintPlugin = require("eslint-webpack-plugin");
12+
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
1513
// 查看打包
1614
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
1715

1816
const pluginsConfig = ({ env, isDev = true, isSSR = true, isMiddleWareDevelop = false, isAnimationRouter = false, isCSR = false, currentUI }) => {
1917
return [
2018
new CleanWebpackPlugin(),
21-
env === "client" && new LoadablePlugin({ filename: "manifest-loadable.json" }),
2219
env === "client" && new WebpackManifestPlugin({ fileName: isDev ? "manifest-dev.json" : "manifest-prod.json" }),
2320
new webpack.DefinePlugin({
2421
__SSR__: isSSR,
@@ -34,7 +31,7 @@ const pluginsConfig = ({ env, isDev = true, isSSR = true, isMiddleWareDevelop =
3431
env === "client" &&
3532
new MiniCssExtractPlugin({
3633
filename: isDev ? "[name].css" : "[name]-[contenthash].css",
37-
chunkFilename: isDev ? "css/[id].css" : "[id].[contenthash].css",
34+
chunkFilename: isDev ? "[name]-[id].css" : "[name]-[id]-[contenthash].css",
3835
}),
3936
// 快速刷新
4037
env === "client" && isDev && new ReactRefreshPlugin(),

yarn.lock

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@
478478
dependencies:
479479
"@babel/helper-plugin-utils" "^7.17.12"
480480

481-
"@babel/plugin-syntax-dynamic-import@^7.7.4", "@babel/plugin-syntax-dynamic-import@^7.8.3":
481+
"@babel/plugin-syntax-dynamic-import@^7.8.3":
482482
version "7.8.3"
483483
resolved "https://registry.npmmirror.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
484484
integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
@@ -1017,7 +1017,7 @@
10171017
core-js-pure "^3.20.2"
10181018
regenerator-runtime "^0.13.4"
10191019

1020-
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.3", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
1020+
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.3", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
10211021
version "7.18.3"
10221022
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4"
10231023
integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==
@@ -2108,36 +2108,6 @@
21082108
resolved "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
21092109
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
21102110

2111-
"@loadable/babel-plugin@^5.13.2":
2112-
version "5.13.2"
2113-
resolved "https://registry.npmmirror.com/@loadable/babel-plugin/-/babel-plugin-5.13.2.tgz#373cddc64ee5437814f7dca1c1b6a7b2c1665a9f"
2114-
integrity sha512-vSZUVeTH1S1sDbk8Tzft0plZSkN7W4zmVR5w/Bmy4UmvBiu9lin7ztrDpoUTUzxpoups+OJbTc/OosvN0aMXWg==
2115-
dependencies:
2116-
"@babel/plugin-syntax-dynamic-import" "^7.7.4"
2117-
2118-
"@loadable/component@^5.15.2":
2119-
version "5.15.2"
2120-
resolved "https://registry.npmmirror.com/@loadable/component/-/component-5.15.2.tgz#b6c418d592e0a64f16b1d614ca9d3b1443d3b498"
2121-
integrity sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==
2122-
dependencies:
2123-
"@babel/runtime" "^7.7.7"
2124-
hoist-non-react-statics "^3.3.1"
2125-
react-is "^16.12.0"
2126-
2127-
"@loadable/server@^5.15.2":
2128-
version "5.15.2"
2129-
resolved "https://registry.npmmirror.com/@loadable/server/-/server-5.15.2.tgz#2aeefa1604c39fc87a20e567ef3ed8647224dd1a"
2130-
integrity sha512-Nk/6Plz8qTn+A+u2qg/vrbYZwTmzzjy5bw4Ts80pM/rqW8H37IooKU/HVWSje63RZ4vTqEsHsrdiX97RB9dMjw==
2131-
dependencies:
2132-
lodash "^4.17.15"
2133-
2134-
"@loadable/webpack-plugin@^5.15.2":
2135-
version "5.15.2"
2136-
resolved "https://registry.npmmirror.com/@loadable/webpack-plugin/-/webpack-plugin-5.15.2.tgz#460acf5dc0d56c6aef98c7d5f1c2be033422fa8d"
2137-
integrity sha512-+o87jPHn3E8sqW0aBA+qwKuG8JyIfMGdz3zECv0t/JF0KHhxXtzIlTiqzlIYc5ZpFs/vKSQfjzGIR5tPJjoXDw==
2138-
dependencies:
2139-
make-dir "^3.0.2"
2140-
21412111
"@nicolo-ribaudo/[email protected]":
21422112
version "2.1.8-no-fsevents.3"
21432113
resolved "https://registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b"
@@ -2478,20 +2448,6 @@
24782448
resolved "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
24792449
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
24802450

2481-
"@types/loadable__component@^5.13.4":
2482-
version "5.13.4"
2483-
resolved "https://registry.npmmirror.com/@types/loadable__component/-/loadable__component-5.13.4.tgz#a4646b2406b1283efac1a9d9485824a905b33d4a"
2484-
integrity sha512-YhoCCxyuvP2XeZNbHbi8Wb9EMaUJuA2VGHxJffcQYrJKIKSkymJrhbzsf9y4zpTmr5pExAAEh5hbF628PAZ8Dg==
2485-
dependencies:
2486-
"@types/react" "*"
2487-
2488-
"@types/loadable__server@^5.12.6":
2489-
version "5.12.6"
2490-
resolved "https://registry.npmmirror.com/@types/loadable__server/-/loadable__server-5.12.6.tgz#5a64eed56f8d0c5d1e3f636e231f30da20d9eb8d"
2491-
integrity sha512-LgO5aUQJYFQY5bLuAef4anCZ/SwsEo2hG/D4zfREgUGDXjezBjZCwlUmmpfIQLsR64reLTCijS0m7gsd1k9cKA==
2492-
dependencies:
2493-
"@types/react" "*"
2494-
24952451
24962452
version "4.6.6"
24972453
resolved "https://registry.npmmirror.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz#c4698f5b214a433ff35cb2c75ee6ec7f99d79f10"
@@ -6285,7 +6241,7 @@ lodash.uniq@^4.5.0:
62856241
resolved "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
62866242
integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
62876243

6288-
lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
6244+
lodash@^4.17.20, lodash@^4.17.21:
62896245
version "4.17.21"
62906246
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
62916247
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7372,7 +7328,7 @@ react-intl@^6.0.4:
73727328
intl-messageformat "10.1.0"
73737329
tslib "2.4.0"
73747330

7375-
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0:
7331+
react-is@^16.13.1, react-is@^16.7.0:
73767332
version "16.13.1"
73777333
resolved "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
73787334
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==

0 commit comments

Comments
 (0)