mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-13 09:07:29 +02:00
feat(v2): generate sitemap (#1065)
* feat(v2): generate sitemap * cannot snapshot sitemap because xml generated in different order
This commit is contained in:
parent
8663a63e7d
commit
fd780f19a2
18 changed files with 127 additions and 1185 deletions
|
@ -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
38
v2/lib/core/sitemap.js
Normal 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();
|
||||||
|
};
|
|
@ -17,6 +17,7 @@ module.exports = function loadConfig(siteDir, deleteCache = true) {
|
||||||
'organizationName',
|
'organizationName',
|
||||||
'projectName',
|
'projectName',
|
||||||
'baseUrl',
|
'baseUrl',
|
||||||
|
'url',
|
||||||
];
|
];
|
||||||
const optionalFields = [
|
const optionalFields = [
|
||||||
'customDocsPath',
|
'customDocsPath',
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -4,4 +4,5 @@ module.exports = {
|
||||||
organizationName: 'endiliey',
|
organizationName: 'endiliey',
|
||||||
projectName: 'sakura',
|
projectName: 'sakura',
|
||||||
baseUrl: '/sakura/',
|
baseUrl: '/sakura/',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,4 +4,5 @@ module.exports = {
|
||||||
organizationName: 'endiliey',
|
organizationName: 'endiliey',
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,4 +5,5 @@ module.exports = {
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
defaultLanguage: 'en',
|
defaultLanguage: 'en',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,4 +5,5 @@ module.exports = {
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
defaultLanguage: 'en',
|
defaultLanguage: 'en',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,4 +4,5 @@ module.exports = {
|
||||||
organizationName: 'endiliey',
|
organizationName: 'endiliey',
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
44
v2/test/core/sitemap.test.js
Normal file
44
v2/test/core/sitemap.test.js
Normal 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"`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,4 +4,5 @@ module.exports = {
|
||||||
organizationName: 'endiliey',
|
organizationName: 'endiliey',
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,4 +5,5 @@ module.exports = {
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
defaultLanguage: 'en',
|
defaultLanguage: 'en',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,4 +5,5 @@ module.exports = {
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
defaultLanguage: 'en',
|
defaultLanguage: 'en',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,4 +4,5 @@ module.exports = {
|
||||||
organizationName: 'endiliey',
|
organizationName: 'endiliey',
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,4 +8,5 @@ module.exports = {
|
||||||
superman: 'lol',
|
superman: 'lol',
|
||||||
admin: 'endi',
|
admin: 'endi',
|
||||||
customFields: ['admin', 'superman'],
|
customFields: ['admin', 'superman'],
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
|
@ -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"`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,4 +5,5 @@ module.exports = {
|
||||||
projectName: 'docusaurus',
|
projectName: 'docusaurus',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
customDocsPath: '../docs',
|
customDocsPath: '../docs',
|
||||||
|
url: 'https://docusaurus.io',
|
||||||
};
|
};
|
||||||
|
|
1186
v2/yarn.lock
1186
v2/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue