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 fs = require('fs-extra');
const globby = require('globby'); const globby = require('globby');
const load = require('../load'); const load = require('../load');
const createSitemap = require('../core/sitemap');
const createServerConfig = require('../webpack/server'); const createServerConfig = require('../webpack/server');
const createClientConfig = require('../webpack/client'); const createClientConfig = require('../webpack/client');
const {applyConfigureWebpack} = require('../webpack/utils'); 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); const relativeDir = path.relative(process.cwd(), outDir);
console.log( console.log(
`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan( `\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', 'organizationName',
'projectName', 'projectName',
'baseUrl', 'baseUrl',
'url',
]; ];
const optionalFields = [ const optionalFields = [
'customDocsPath', 'customDocsPath',

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,4 +4,5 @@ module.exports = {
organizationName: 'endiliey', organizationName: 'endiliey',
projectName: 'hello', projectName: 'hello',
baseUrl: '/', 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', organizationName: 'endiliey',
projectName: 'hello', projectName: 'hello',
baseUrl: '/', baseUrl: '/',
url: 'https://docusaurus.io',
}; };

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff