mirror of https://github.com/alibaba/ice.git
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:
parent
8d5f398d28
commit
9a062c08a8
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
// TODO:sync compiler
|
||||
return esbuild.build({
|
||||
outdir,
|
||||
entryPoints: [document],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
external: ['./node_modules/*'],
|
||||
});
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue