feat: render document (#8)

* feat: render document

* fix: lint

* fix: ts lint

* chore: update lock info

* fix: lint

* fix: conflict

* fix: conflict

Co-authored-by: luhc228 <luhengchang228@gmail.com>
This commit is contained in:
水澜 2022-02-24 19:57:57 +08:00 committed by ClarkXia
parent 8d5f398d28
commit 9a062c08a8
8 changed files with 110 additions and 15 deletions

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script src="./main.js"></script>
</body>
</html>

View File

@ -0,0 +1,21 @@
/* eslint-disable react/self-closing-comp */
import React from 'react';
function Document() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="description" content="ICE 3.0 Demo" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ICE Demo</title>
</head>
<body>
<div id="root"></div>
<script src="./main.js"></script>
</body>
</html>
);
}
export default Document;

View File

@ -11,7 +11,8 @@
"webpack-dev-server": "^4.7.4"
},
"devDependencies": {
"webpack": "^5.69.1"
"webpack": "^5.69.1",
"webpack-dev-server": "^4.7.4"
},
"files": [
"lib",

View File

@ -16,6 +16,11 @@
"lib"
],
"license": "MIT",
"dependencies": {
"esbuild": "^0.14.23",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@ice/service": "^1.0.0"
}

View File

@ -1,11 +1,40 @@
import type { FrameworkPlugin } from '@ice/service';
import { setupRenderServer } from './ssr/server';
import { buildServerEntry } from './ssr/build';
const plugin: FrameworkPlugin = ({ registerTask, context }) => {
const { command } = context;
const plugin: FrameworkPlugin = ({ registerTask, context, onHook }) => {
const { command, rootDir } = context;
const mode = command === 'start' ? 'development' : 'production';
// mock routeManifest
const routeManifest = {
'/': '/src/pages/index',
};
onHook(`before.${command}.run`, async () => {
// TODO: watch file changes and rebuild
await buildServerEntry({
rootDir,
});
});
registerTask('web', {
mode,
middlewares: (middlewares, devServer) => {
if (!devServer) {
throw new Error('webpack-dev-server is not defined');
}
middlewares.push({
name: 'document-render-server',
middleware: setupRenderServer({
rootDir,
routeManifest,
}),
});
return middlewares;
},
});
};

View File

@ -0,0 +1,18 @@
import * as path from 'path';
import * as esbuild from 'esbuild';
export async function buildServerEntry(options: any): Promise<esbuild.BuildResult> {
const { rootDir } = options;
const outdir = path.join(rootDir, 'build');
const document = path.join(rootDir, 'src/document.jsx');
// TODOsync compiler
return esbuild.build({
outdir,
entryPoints: [document],
bundle: true,
platform: 'node',
external: ['./node_modules/*'],
});
}

View File

@ -0,0 +1,26 @@
import * as path from 'path';
import * as React from 'react';
import * as ReactDOMServer from 'react-dom/server';
export function setupRenderServer(options: any) {
const {
rootDir,
routeManifest,
} = options;
return (req, res) => {
if (!routeManifest[req.path]) {
return;
}
// TODO: disable cache
const document = path.resolve(rootDir, 'build/document.js');
const Document = require(document).default;
const html = ReactDOMServer.renderToString(<Document />);
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.send(html);
};
}

View File

@ -177,6 +177,13 @@ importers:
packages/plugin-app:
specifiers:
'@ice/service': ^1.0.0
esbuild: ^0.14.23
react: ^17.0.2
react-dom: ^17.0.2
dependencies:
esbuild: 0.14.23
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
devDependencies:
'@ice/service': link:../ice-service