feat(v2): generate sitemap (#1065)

* feat(v2): generate sitemap

* cannot snapshot sitemap because xml generated in different order
This commit is contained in:
Endilie Yacop Sucipto 2018-10-25 21:47:13 +08:00 committed by GitHub
parent 8663a63e7d
commit fd780f19a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 127 additions and 1185 deletions

View file

@ -4,6 +4,7 @@ const chalk = require('chalk');
const fs = require('fs-extra');
const globby = require('globby');
const load = require('../load');
const createSitemap = require('../core/sitemap');
const createServerConfig = require('../webpack/server');
const createClientConfig = require('../webpack/client');
const {applyConfigureWebpack} = require('../webpack/utils');
@ -67,6 +68,11 @@ module.exports = async function build(siteDir) {
}),
);
// generate sitemap
const sitemap = await createSitemap(props);
const sitemapPath = path.join(outDir, 'sitemap.xml');
await fs.writeFile(sitemapPath, sitemap);
const relativeDir = path.relative(process.cwd(), outDir);
console.log(
`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan(

38
v2/lib/core/sitemap.js Normal file
View file

@ -0,0 +1,38 @@
const sitemap = require('sitemap');
module.exports = async function createSitemap({
siteConfig = {},
docsMetadatas = {},
pagesMetadatas = [],
blogMetadatas = [],
}) {
const allMetadatas = [
...blogMetadatas,
...Object.values(docsMetadatas),
...pagesMetadatas,
];
const {url: siteUrl} = siteConfig;
if (!siteUrl) {
throw new Error('Url in siteConfig.js cannot be empty/undefined');
}
const urls = [];
allMetadatas.forEach(metadata => {
urls.push({
url: metadata.permalink,
changefreq: 'weekly',
priority: 0.5,
});
});
const sm = sitemap.createSitemap({
hostname: siteUrl,
cacheTime: 600 * 1000, // 600 sec - cache purge period
urls,
});
return sm.toString();
};

View file

@ -17,6 +17,7 @@ module.exports = function loadConfig(siteDir, deleteCache = true) {
'organizationName',
'projectName',
'baseUrl',
'url',
];
const optionalFields = [
'customDocsPath',

View file

@ -84,6 +84,7 @@
"remarkable": "^1.7.1",
"semver": "^5.5.0",
"shelljs": "^0.8.2",
"sitemap": "^2.1.0",
"static-site-generator-webpack-plugin": "endiliey/static-site-generator-webpack-plugin#master",
"style-loader": "^0.22.1",
"uglifyjs-webpack-plugin": "^1.3.0",

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey',
projectName: 'sakura',
baseUrl: '/sakura/',
url: 'https://docusaurus.io',
};

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey',
projectName: 'hello',
baseUrl: '/',
url: 'https://docusaurus.io',
};

View file

@ -5,4 +5,5 @@ module.exports = {
projectName: 'hello',
baseUrl: '/',
defaultLanguage: 'en',
url: 'https://docusaurus.io',
};

View file

@ -5,4 +5,5 @@ module.exports = {
projectName: 'hello',
baseUrl: '/',
defaultLanguage: 'en',
url: 'https://docusaurus.io',
};

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey',
projectName: 'hello',
baseUrl: '/',
url: 'https://docusaurus.io',
};

View file

@ -0,0 +1,44 @@
import '@babel/polyfill';
import createSitemap from '@lib/core/sitemap';
import loadSetup from '../loadSetup';
describe('sitemap', () => {
test('simple site', async () => {
const props = await loadSetup('simple');
const sitemap = await createSitemap(props);
expect(sitemap).toContain(
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">`,
);
});
test('translated site', async () => {
const props = await loadSetup('translated');
const sitemap = await createSitemap(props);
expect(sitemap).toContain(
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">`,
);
});
test('versioned site', async () => {
const props = await loadSetup('versioned');
const sitemap = await createSitemap(props);
expect(sitemap).toContain(
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">`,
);
});
test('translated + versioned site', async () => {
const props = await loadSetup('transversioned');
const sitemap = await createSitemap(props);
expect(sitemap).toContain(
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">`,
);
});
test('empty site', async () => {
const props = await loadSetup('empty');
expect(createSitemap(props)).rejects.toThrowErrorMatchingInlineSnapshot(
`"Url in siteConfig.js cannot be empty/undefined"`,
);
});
});

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey',
projectName: 'hello',
baseUrl: '/',
url: 'https://docusaurus.io',
};

View file

@ -5,4 +5,5 @@ module.exports = {
projectName: 'hello',
baseUrl: '/',
defaultLanguage: 'en',
url: 'https://docusaurus.io',
};

View file

@ -5,4 +5,5 @@ module.exports = {
projectName: 'hello',
baseUrl: '/',
defaultLanguage: 'en',
url: 'https://docusaurus.io',
};

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey',
projectName: 'hello',
baseUrl: '/',
url: 'https://docusaurus.io',
};

View file

@ -8,4 +8,5 @@ module.exports = {
superman: 'lol',
admin: 'endi',
customFields: ['admin', 'superman'],
url: 'https://docusaurus.io',
};

View file

@ -5,15 +5,18 @@ describe('loadConfig', () => {
test('website with valid siteConfig', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'simple-site');
const config = loadConfig(siteDir);
expect(config).toEqual({
baseUrl: '/',
organizationName: 'endiliey',
customDocsPath: 'docs',
docsUrl: 'docs',
projectName: 'hello',
tagline: 'Hello World',
title: 'Hello',
});
expect(config).toMatchInlineSnapshot(`
Object {
"baseUrl": "/",
"customDocsPath": "docs",
"docsUrl": "docs",
"organizationName": "endiliey",
"projectName": "hello",
"tagline": "Hello World",
"title": "Hello",
"url": "https://docusaurus.io",
}
`);
expect(config).not.toEqual({});
});
@ -22,7 +25,7 @@ describe('loadConfig', () => {
expect(() => {
loadConfig(siteDir);
}).toThrowErrorMatchingInlineSnapshot(
`"tagline, organizationName, projectName fields are missing in siteConfig.js"`,
`"tagline, organizationName, projectName, url fields are missing in siteConfig.js"`,
);
});
@ -40,7 +43,7 @@ describe('loadConfig', () => {
expect(() => {
loadConfig(siteDir);
}).toThrowErrorMatchingInlineSnapshot(
`"title, tagline, organizationName, projectName, baseUrl fields are missing in siteConfig.js"`,
`"title, tagline, organizationName, projectName, baseUrl, url fields are missing in siteConfig.js"`,
);
});
});

View file

@ -5,4 +5,5 @@ module.exports = {
projectName: 'docusaurus',
baseUrl: '/',
customDocsPath: '../docs',
url: 'https://docusaurus.io',
};

File diff suppressed because it is too large Load diff