refactor(v2): determine all available routes/url (#1264)

* refactor(v2): determine all available routes/url

* nits

* test(v2): routes snapshot

* sort for consistent snapshot test due to async ordering
This commit is contained in:
Endilie Yacop Sucipto 2019-03-07 02:51:16 +08:00 committed by Yangshun Tay
parent c73da00252
commit 2ad7413dd7
5 changed files with 114 additions and 41 deletions

View file

@ -10,17 +10,8 @@ const loadConfig = require('../load/config');
module.exports = async function createSitemap({
siteConfig = {},
docsMetadatas = {},
pagesMetadatas = [],
// TODO: Generalize for blog plugin.
blogMetadatas = [],
routesPaths = [],
}) {
const allMetadatas = [
...blogMetadatas,
...Object.values(docsMetadatas),
...pagesMetadatas,
];
const {url: siteUrl} = siteConfig;
if (!siteUrl) {
@ -29,8 +20,8 @@ module.exports = async function createSitemap({
);
}
const urls = allMetadatas.map(metadata => ({
url: metadata.permalink,
const urls = routesPaths.map(routesPath => ({
url: routesPath,
changefreq: 'weekly',
priority: 0.5,
}));

View file

@ -13,7 +13,7 @@ const loadEnv = require('./env');
const loadPages = require('./pages');
const loadTheme = require('./theme');
const {generate} = require('./utils');
const genRoutesConfig = require('./routes');
const loadRoutes = require('./routes');
const constants = require('../constants');
module.exports = async function load(siteDir) {
@ -96,6 +96,7 @@ module.exports = async function load(siteDir) {
});
// Plugin lifecycle - loadContents().
// TODO: consider whether we still need contentsStore since it is not being used elsewhere now
const contentsStore = {};
// Currently plugins run lifecycle in parallel and are not order-dependent. We could change
// this in future if there are plugins which need to run in certain order or depend on
@ -153,6 +154,15 @@ module.exports = async function load(siteDir) {
const versionedDir = path.join(siteDir, 'versioned_docs');
const translatedDir = path.join(siteDir, 'translated_docs');
// Generate React Router Config.
const {routesConfig, routesPaths} = await loadRoutes({
siteConfig,
docsMetadatas,
pagesMetadatas,
pluginRouteConfigs,
});
await generate(generatedFilesDir, 'routes.js', routesConfig);
const props = {
siteConfig,
siteDir,
@ -170,14 +180,8 @@ module.exports = async function load(siteDir) {
translatedDir,
generatedFilesDir,
contentsStore,
routesPaths,
};
// Generate React Router Config.
const routesConfig = await genRoutesConfig({
...props,
pluginRouteConfigs,
});
await generate(generatedFilesDir, 'routes.js', routesConfig);
return props;
};

View file

@ -7,7 +7,7 @@
const {normalizeUrl} = require('./utils');
async function genRoutesConfig({
async function loadRoutes({
siteConfig = {},
docsMetadatas = {},
pagesMetadatas = [],
@ -23,10 +23,18 @@ async function genRoutesConfig({
`import NotFound from '@theme/NotFound';`,
];
const routesPaths = [];
const addRoutesPath = permalink => {
if (permalink && !/:|\*/.test(permalink)) {
routesPaths.push(permalink);
}
};
// Docs.
const {docsUrl, baseUrl} = siteConfig;
function genDocsRoute(metadata) {
const {permalink, source} = metadata;
addRoutesPath(permalink);
return `
{
path: '${permalink}',
@ -59,6 +67,7 @@ async function genRoutesConfig({
// Pages.
function genPagesRoute(metadata) {
const {permalink, source} = metadata;
addRoutesPath(permalink);
return `
{
path: '${permalink}',
@ -86,6 +95,7 @@ async function genRoutesConfig({
const routes = pluginRouteConfigs.map(pluginRouteConfig => {
const {path, component, metadata, modules} = pluginRouteConfig;
addRoutesPath(path);
return `
{
path: '${path}',
@ -117,7 +127,7 @@ ${modules
}`;
});
return `
const routesConfig = `
${imports.join('\n')}
const routes = [
@ -131,6 +141,8 @@ const routes = [
];
export default routes;\n`;
return {routesConfig, routesPaths};
}
module.exports = genRoutesConfig;
module.exports = loadRoutes;

View file

@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
const _ = require('lodash');
const path = require('path');
const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');
const webpackNiceLog = require('webpack-nicelog');
@ -22,25 +21,16 @@ module.exports = function createServerConfig(props) {
// Workaround for Webpack 4 Bug (https://github.com/webpack/webpack/issues/6522)
config.output.globalObject('this');
const {siteConfig, docsMetadatas, pagesMetadatas, contentsStore} = props;
const {siteConfig, routesPaths} = props;
// Static site generator webpack plugin.
const docsFlatMetadatas = Object.values(docsMetadatas);
// TODO: Generalize for blog plugin.
const blogPermalinks = _.get(contentsStore, ['blog', 'contents'], []);
const paths = [
...blogPermalinks,
...docsFlatMetadatas,
...pagesMetadatas,
].map(data => data.permalink);
config.plugin('siteGenerator').use(StaticSiteGeneratorPlugin, [
{
entry: 'main',
locals: {
baseUrl: siteConfig.baseUrl,
},
paths,
paths: routesPaths,
},
]);

View file

@ -5,27 +5,103 @@
* LICENSE file in the root directory of this source tree.
*/
import genRoutesConfig from '@lib/load/routes';
import loadRoutes from '@lib/load/routes';
import loadSetup from '../loadSetup';
describe('genRoutesConfig', () => {
describe('loadRoutes', () => {
test('simple website', async () => {
const props = await loadSetup('simple');
await genRoutesConfig(props);
const {routesPaths} = await loadRoutes(props);
expect(routesPaths.length).toBeGreaterThan(0);
expect(routesPaths.sort()).toMatchInlineSnapshot(`
Array [
"/",
"/docs/endiliey/permalink",
"/docs/foo/bar",
"/docs/foo/baz",
"/docs/hello",
"/hello/world",
]
`);
});
test('versioned website', async () => {
const props = await loadSetup('versioned');
await genRoutesConfig(props);
const {routesPaths} = await loadRoutes(props);
expect(routesPaths.length).toBeGreaterThan(0);
expect(routesPaths.sort()).toMatchInlineSnapshot(`
Array [
"/",
"/docs/1.0.0/foo/bar",
"/docs/1.0.0/foo/baz",
"/docs/1.0.0/hello",
"/docs/foo/bar",
"/docs/foo/baz",
"/docs/hello",
"/docs/next/endiliey/permalink",
"/docs/next/foo/bar",
"/docs/next/foo/baz",
"/docs/next/hello",
"/hello/world",
]
`);
});
test('versioned & translated website', async () => {
const props = await loadSetup('transversioned');
await genRoutesConfig(props);
const {routesPaths} = await loadRoutes(props);
expect(routesPaths.length).toBeGreaterThan(0);
expect(routesPaths.sort()).toMatchInlineSnapshot(`
Array [
"/",
"/docs/en/1.0.0/foo/bar",
"/docs/en/1.0.0/foo/baz",
"/docs/en/1.0.0/hello",
"/docs/en/foo/bar",
"/docs/en/foo/baz",
"/docs/en/hello",
"/docs/en/next/endiliey/permalink",
"/docs/en/next/foo/bar",
"/docs/en/next/foo/baz",
"/docs/en/next/hello",
"/docs/ko/1.0.0/foo/bar",
"/docs/ko/1.0.0/foo/baz",
"/docs/ko/1.0.0/hello",
"/docs/ko/foo/bar",
"/docs/ko/foo/baz",
"/docs/ko/hello",
"/docs/ko/next/foo/bar",
"/docs/ko/next/foo/baz",
"/docs/ko/next/hello",
"/en/",
"/en/hello/world",
"/hello/world",
"/ko/",
"/ko/hello/world",
]
`);
});
test('translated website', async () => {
const props = await loadSetup('translated');
await genRoutesConfig(props);
const {routesPaths} = await loadRoutes(props);
expect(routesPaths.length).toBeGreaterThan(0);
expect(routesPaths.sort()).toMatchInlineSnapshot(`
Array [
"/",
"/docs/en/endiliey/permalink",
"/docs/en/foo/bar",
"/docs/en/foo/baz",
"/docs/en/hello",
"/docs/ko/foo/bar",
"/docs/ko/foo/baz",
"/docs/ko/hello",
"/en/",
"/en/hello/world",
"/hello/world",
"/ko/",
"/ko/hello/world",
]
`);
});
});