From bc7b2835b0ba981c1cf88e97aca392e4b933350f Mon Sep 17 00:00:00 2001 From: endiliey Date: Wed, 8 Aug 2018 01:33:25 +0800 Subject: [PATCH] feat: prototype custom pages site generation --- lib/core/App.js | 5 +++-- lib/load/index.js | 13 ++++++++++++- lib/load/pages.js | 23 +++++++++++++++++++++++ lib/load/routes.js | 21 ++++++++++++++++++--- lib/load/utils.js | 2 +- lib/webpack/base.js | 1 + lib/webpack/prod.js | 4 ++-- website/pages/index.js | 18 ++++++++++++++++++ 8 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 lib/load/pages.js create mode 100644 website/pages/index.js diff --git a/lib/core/App.js b/lib/core/App.js index 994f141f82..6cef21dbbe 100644 --- a/lib/core/App.js +++ b/lib/core/App.js @@ -1,6 +1,7 @@ import {renderRoutes} from 'react-router-config'; import routes from '@generated/routes'; // eslint-disable-line -import props from '@generated/docsData'; // eslint-disable-line +import docsData from '@generated/docsData'; // eslint-disable-line +import pagesData from '@generated/pagesData'; // eslint-disable-line -export default () => renderRoutes(routes, props); +export default () => renderRoutes(routes, {docsData, pagesData}); diff --git a/lib/load/index.js b/lib/load/index.js index c1729f2251..7ce9b4540a 100644 --- a/lib/load/index.js +++ b/lib/load/index.js @@ -2,6 +2,7 @@ const fs = require('fs-extra'); const path = require('path'); const loadConfig = require('./config'); const loadDocs = require('./docs'); +const loadPages = require('./pages'); const {generate} = require('./utils'); const genRoutesConfig = require('./routes'); @@ -18,7 +19,15 @@ module.exports = async function load(siteDir) { const docsData = await loadDocs(docsDir); await generate( 'docsData.js', - `export const docsData = ${JSON.stringify(docsData, null, 2)}` + `export default ${JSON.stringify(docsData, null, 2)};` + ); + + // pages + const pagesDir = path.resolve(siteDir, 'pages'); + const pagesData = await loadPages(pagesDir); + await generate( + 'pagesData.js', + `export default ${JSON.stringify(pagesData, null, 2)};` ); // resolve outDir @@ -38,6 +47,8 @@ module.exports = async function load(siteDir) { siteDir, docsDir, docsData, + pagesDir, + pagesData, outDir, themePath, baseUrl diff --git a/lib/load/pages.js b/lib/load/pages.js new file mode 100644 index 0000000000..c3023b81ca --- /dev/null +++ b/lib/load/pages.js @@ -0,0 +1,23 @@ +const fs = require('fs-extra'); +const path = require('path'); +const globby = require('globby'); +const {encodePath, fileToPath} = require('./utils'); + +async function loadPages(pagesDir) { + const pagesFiles = await globby(['**/*.js'], { + cwd: pagesDir + }); + + const pagesData = await Promise.all( + pagesFiles.map(async source => { + const filepath = path.resolve(pagesDir, source); + return { + path: encodePath(fileToPath(source)), + source + }; + }) + ); + return pagesData; +} + +module.exports = loadPages; diff --git a/lib/load/routes.js b/lib/load/routes.js index 1482b66ba9..cdfd203e01 100644 --- a/lib/load/routes.js +++ b/lib/load/routes.js @@ -1,7 +1,7 @@ const path = require('path'); const {fileToComponentName} = require('./utils'); -async function genRoutesConfig({docsData, docsDir}) { +async function genRoutesConfig({docsData, docsDir, pagesDir, pagesData}) { function genDocsRoute({path: docsPath, source}) { const componentName = fileToComponentName(source); return ` @@ -17,6 +17,20 @@ async function genRoutesConfig({docsData, docsDir}) { return `import ${componentName} from ${JSON.stringify(filePath)}`; } + function genPagesRoute({path: pagesPath, source}) { + const componentName = fileToComponentName(source); + return ` + { + path: ${JSON.stringify(pagesPath)}, + component: ${componentName} + }`; + } + + function genPagesImport({source}) { + const componentName = fileToComponentName(source); + return `import ${componentName} from '@pages/${source}'`; + } + const notFoundRoute = `, { path: '*', @@ -27,9 +41,10 @@ async function genRoutesConfig({docsData, docsDir}) { `import React from 'react';\n` + `import Docs from '@theme/Docs';\n` + `import NotFound from '@theme/NotFound';\n` + + `${pagesData.map(genPagesImport).join('\n')}\n` + `${docsData.map(genDocsImport).join('\n')}\n` + - `const routes = [${docsData - .map(genDocsRoute) + `const routes = [${docsData.map(genDocsRoute).join(',')},${pagesData + .map(genPagesRoute) .join(',')}${notFoundRoute}\n];\n` + `export default routes;\n` ); diff --git a/lib/load/utils.js b/lib/load/utils.js index 1163c886bf..052f7b24b6 100644 --- a/lib/load/utils.js +++ b/lib/load/utils.js @@ -13,7 +13,7 @@ async function generate(file, content) { } } -const indexRE = /(^|.*\/)index\.md$/i; +const indexRE = /(^|.*\/)index\.(md|js)$/i; const mdRE = /\.md$/; function fileToPath(file) { diff --git a/lib/webpack/base.js b/lib/webpack/base.js index d577671721..711cb0ea44 100644 --- a/lib/webpack/base.js +++ b/lib/webpack/base.js @@ -19,6 +19,7 @@ module.exports = function createBaseConfig(props) { .set('symlinks', true) .alias.set('@theme', themePath) .set('@site', siteDir) + .set('@pages', path.resolve(siteDir, 'pages')) .set('@generated', path.resolve(__dirname, '../core/generated')) .set('@core', path.resolve(__dirname, '../core')) .end(); diff --git a/lib/webpack/prod.js b/lib/webpack/prod.js index 0bca7e7345..d284f706d1 100644 --- a/lib/webpack/prod.js +++ b/lib/webpack/prod.js @@ -11,10 +11,10 @@ module.exports = function createProdConfig(props) { // Workaround for Webpack 4 Bug (https://github.com/webpack/webpack/issues/6522) config.output.globalObject('this'); - const {siteConfig, docsData} = props; + const {siteConfig, docsData, pagesData} = props; // Find all available paths - const paths = docsData.map(docs => docs.path); + const paths = [...docsData, ...pagesData].map(data => data.path); config.plugin('StaticSiteGenerator').use(staticSiteGeneratorPlugin, [ { diff --git a/website/pages/index.js b/website/pages/index.js new file mode 100644 index 0000000000..19f3a8d681 --- /dev/null +++ b/website/pages/index.js @@ -0,0 +1,18 @@ +import React from 'react'; +import {Link} from 'react-router-dom'; + +export default class Home extends React.Component { + render() { + const {pagesData, docsData} = this.props; + const routeLinks = [...pagesData, ...docsData].map(data => ( +
  • + {data.path} +
  • + )); + return ( +
    + +
    + ); + } +}