Skip to content

Commit 4052ef6

Browse files
authored
fix(ssr): OOM when dev rendering (umijs#6157)
* fix(ssr): dev render OOM * fix: clear cache * chore: style * chore: reset yarn.lock * fix: isDev
1 parent 988be39 commit 4052ef6

File tree

4 files changed

+30
-43
lines changed

4 files changed

+30
-43
lines changed

examples/ssr-koa/server.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ const mount = require('koa-mount');
44
const { join, extname } = require('path');
55
const { parseCookie, parseNavLang } = require('./serverHelper');
66

7-
const isDev = process.env.NODE_ENV === 'development';
8-
97
const root = join(__dirname, 'dist');
108

119
const app = new Koa();
@@ -52,15 +50,6 @@ app.use(async (ctx, next) => {
5250
console.log('----------------服务端报错-------------------', error);
5351
ctx.throw(500, error);
5452
}
55-
/**
56-
* 这里fix了由于没有使用内部server而造成的缓存问题,
57-
* 原因是require会带有缓存,在修改代码以后会不更新
58-
* 这里判断的环境变量,如果是dev环境,自动删除require
59-
* 缓存
60-
*/
61-
if (isDev) {
62-
delete require.cache[require.resolve('./dist/umi.server')];
63-
}
6453
ctx.body = html;
6554
} else {
6655
await next();

examples/ssr-with-eggjs/app/controller/home.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ class HomeController extends Controller {
1111
global.href = ctx.request.href;
1212
global._cookies = ctx.helper.parseCookie(ctx);
1313
global._navigatorLang = ctx.helper.parseNavLang(ctx);
14-
/**
15-
* 这里可以根据自己的环境配置修改,
16-
* 规则就是开发环境需要删除require缓存
17-
* 重新load文件
18-
*
19-
*/
20-
21-
const isDev = app.config.env != 'prod';
22-
if (isDev) {
23-
delete require.cache[require.resolve('../public/umi.server')];
24-
}
2514

2615
// 先走 eggjs 的v iew 渲染
2716
const htmlTemplate = await ctx.view.render('index.html');

packages/preset-built-in/src/plugins/features/ssr/ssr.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import serialize from 'serialize-javascript';
66
import { performance } from 'perf_hooks';
77
import { Route } from '@umijs/core';
88
import { IApi, BundlerConfigType } from '@umijs/types';
9-
import { winPath, Mustache, lodash as _, routeToChunkName } from '@umijs/utils';
9+
import {
10+
winPath,
11+
Mustache,
12+
lodash as _,
13+
routeToChunkName,
14+
cleanRequireCache,
15+
} from '@umijs/utils';
1016
import { matchRoutes, RouteConfig } from 'react-router-config';
1117
import { webpack } from '@umijs/bundler-webpack';
1218
import ServerTypePlugin from './serverTypePlugin';
@@ -230,10 +236,21 @@ export default (api: IApi) => {
230236
return config;
231237
});
232238

239+
// make sure to clear umi.server.js cache
240+
api.onDevCompileDone(() => {
241+
const serverExp = new RegExp(_.escapeRegExp(OUTPUT_SERVER_FILENAME));
242+
// clear require cache
243+
for (const moduleId of Object.keys(require.cache)) {
244+
if (serverExp.test(moduleId)) {
245+
cleanRequireCache(moduleId);
246+
}
247+
}
248+
});
249+
233250
// modify devServer content
234251
api.modifyDevHTMLContent(async (defaultHtml, { req }) => {
235252
// umi dev to enable server side render by default
236-
const { stream, devServerRender = true } = api.config?.ssr || {};
253+
const { mode, devServerRender = true } = api.config?.ssr || {};
237254
const serverPath = path.join(
238255
api.paths.absOutputPath!,
239256
OUTPUT_SERVER_FILENAME,
@@ -245,7 +262,7 @@ export default (api: IApi) => {
245262

246263
try {
247264
const startTime = performance.nodeTiming.duration;
248-
const render = require(serverPath);
265+
let render = require(serverPath);
249266
const context = {};
250267
const { html, error } = await render({
251268
origin: `${req.protocol}://${req.get('host')}`,
@@ -257,18 +274,14 @@ export default (api: IApi) => {
257274
});
258275
const endTime = performance.nodeTiming.duration;
259276
console.log(
260-
`[SSR] ${stream ? 'stream' : ''} render ${req.url} start: ${(
277+
`[SSR] ${mode === 'stream' ? 'stream' : ''} render ${req.url} start: ${(
261278
endTime - startTime
262279
).toFixed(2)}ms`,
263280
);
264281
if (error) {
265282
throw error;
266283
}
267-
// if dev clear cache, OOM
268-
if (require.cache[serverPath]) {
269-
// replace default html
270-
delete require.cache[serverPath];
271-
}
284+
render = null;
272285
return html;
273286
} catch (e) {
274287
api.logger.error('[SSR]', e);

packages/preset-built-in/src/plugins/features/ssr/templates/server.tpl

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import './pluginRegister';
1616
// https://github.com/webpack/webpack/issues/4175#issuecomment-342931035
1717
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
1818

19-
let routes;
20-
2119
/**
2220
* server render function
2321
* @param params
@@ -71,16 +69,14 @@ const render: IServerRender = async (params) => {
7169
* routes init and patch only once
7270
* beforeRenderServer must before routes init avoding require error
7371
*/
74-
if (!routes) {
75-
// 主要为后面支持按需服务端渲染,单独用 routes 会全编译
76-
routes = {{{ Routes }}};
77-
// allow user to extend routes
78-
plugin.applyPlugins({
79-
key: 'patchRoutes',
80-
type: ApplyPluginsType.event,
81-
args: { routes },
82-
});
83-
}
72+
// 主要为后面支持按需服务端渲染,单独用 routes 会全编译
73+
const routes = {{{ Routes }}};
74+
// allow user to extend routes
75+
plugin.applyPlugins({
76+
key: 'patchRoutes',
77+
type: ApplyPluginsType.event,
78+
args: { routes },
79+
});
8480

8581
// for renderServer
8682
const opts = {

0 commit comments

Comments
 (0)