-
Notifications
You must be signed in to change notification settings - Fork 622
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9277be0
commit 052298e
Showing
9 changed files
with
161 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,39 @@ | ||
const path = require('path'); | ||
const fs = require('fs-extra'); | ||
const qs = require('querystring'); | ||
|
||
const SSRLoader = require.resolve('./loader'); | ||
|
||
module.exports = (rootDir) => { | ||
const appDirectory = rootDir; | ||
const appSrc = path.resolve(appDirectory, 'src'); | ||
|
||
const entries = {}; | ||
const absoluteAppPath = path.join(appDirectory, 'src/app.js'); | ||
const absoluteAppJSONPath = path.join(appDirectory, 'src/app.json'); | ||
const absoluteDocumentPath = path.join(appDirectory, 'src/document/index.jsx'); | ||
const absoluteShellPath = path.join(appDirectory, 'src/shell/index.jsx'); | ||
|
||
const files = fs.readdirSync(path.resolve(appSrc, 'pages')); | ||
files.map((file) => { | ||
const absolutePath = path.resolve(appSrc, 'pages', file); | ||
const pathStat = fs.statSync(absolutePath); | ||
const appJSON = require(absoluteAppJSONPath); | ||
const routes = appJSON.routes; | ||
|
||
if (pathStat.isDirectory()) { | ||
const relativePath = path.relative(appDirectory, absolutePath); | ||
entries[file] = './' + path.join(relativePath, '/'); | ||
} | ||
}); | ||
const entries = {}; | ||
|
||
routes.forEach((route) => { | ||
const entry = route.name || route.component.replace(/\//g, '_'); | ||
const absolutePagePath = path.resolve(appSrc, route.component); | ||
|
||
const documentPath = path.resolve(appSrc, 'document/index.jsx'); | ||
if (fs.existsSync(documentPath)) { | ||
entries._document = documentPath; | ||
} | ||
const query = { | ||
path: route.path, | ||
absoluteDocumentPath, | ||
absoluteShellPath, | ||
absoluteAppPath, | ||
absolutePagePath, | ||
absoluteAppJSONPath, | ||
// errorPath: path.join(appDirectory, 'src/pages/error/index.jsx'), // 从 route 中读取 | ||
// assetsManifestPath: pathConfig.assetsManifest | ||
}; | ||
|
||
const shellPath = path.resolve(appSrc, 'shell/index.jsx'); | ||
if (fs.existsSync(shellPath)) { | ||
entries._shell = shellPath; | ||
} | ||
entries[entry] = `${SSRLoader}?${qs.stringify(query)}!${absolutePagePath}`; | ||
}); | ||
|
||
return entries; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const { parse } = require('querystring'); | ||
const fs = require('fs'); | ||
|
||
module.exports = function(content) { | ||
const query = typeof this.query === 'string' ? parse(this.query.substr(1)) : this.query; | ||
|
||
const { | ||
absoluteDocumentPath, | ||
absoluteShellPath, | ||
absoluteAppPath, | ||
absolutePagePath, | ||
absoluteAppJSONPath | ||
} = query; | ||
|
||
const hasShell = fs.existsSync(absoluteShellPath); | ||
const shellStr = hasShell ? `import Shell from '${absoluteShellPath}'` : 'const Shell = function (props) { return props.children };'; | ||
|
||
return ` | ||
import { createElement } from 'rax'; | ||
import renderer from 'rax-server-renderer'; | ||
import App from '${absoluteAppPath}'; | ||
import Page from '${absolutePagePath}'; | ||
import Document from '${absoluteDocumentPath}'; | ||
import appJSON from '${absoluteAppJSONPath}'; | ||
${shellStr} | ||
async function renderComponentToHTML(req, res, Component) { | ||
const ctx = { | ||
req, | ||
res | ||
}; | ||
const shellData = await getInitialProps(Shell, ctx); | ||
const appData = await getInitialProps(App, ctx); | ||
const pageData = await getInitialProps(Component, ctx); | ||
const initialData = { | ||
shellData, | ||
appData, | ||
pageData | ||
}; | ||
const contentElement = createElement(Shell, null, createElement(App, { | ||
routerConfig: { | ||
defaultComponet: Component, | ||
routes: appJSON.routes | ||
} | ||
})); | ||
const contentHtml = renderer.renderToString(contentElement); | ||
const documentProps = { | ||
pageHtml: contentHtml, | ||
pageData: JSON.stringify(initialData) | ||
}; | ||
await getInitialProps(Document, ctx); | ||
const documentElement = createElement(Document, documentProps);; | ||
const html = '<!doctype html>' + renderer.renderToString(documentElement); | ||
return html; | ||
} | ||
export async function render(req, res) { | ||
const html = await renderToHTML(req, res); | ||
res.setHeader('Content-Type', 'text/html; charset=utf-8'); | ||
res.send(html); | ||
} | ||
export async function renderToHTML(req, res) { | ||
const html = await renderComponentToHTML(req, res, Page); | ||
return html; | ||
} | ||
async function getInitialProps(Component, ctx) { | ||
if (!Component.getInitialProps) return null; | ||
const props = await Component.getInitialProps(ctx); | ||
if (!props || typeof props !== 'object') { | ||
const message = '"getInitialProps()" should resolve to an object. But found "' + props + '" instead.'; | ||
throw new Error(message); | ||
} | ||
if (Component.defaultProps) { | ||
Component.defaultProps = Object.assign({}, props, Component.defaultProps); | ||
} else { | ||
Component.defaultProps = props; | ||
} | ||
return props; | ||
} | ||
`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
这个原因是?