mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-18 11:36:53 +02:00
fix: reload siteConfig.js automatically when locally served page is refreshed (#1509)
* fix: livereload siteConfig * fix test * nits
This commit is contained in:
parent
aa157969cf
commit
166816af40
11 changed files with 53 additions and 42 deletions
|
@ -15,7 +15,8 @@ module.exports = {
|
||||||
testPathIgnorePatterns: [
|
testPathIgnorePatterns: [
|
||||||
'/node_modules/',
|
'/node_modules/',
|
||||||
'__fixtures__',
|
'__fixtures__',
|
||||||
'/packages/.*/lib',
|
'/packages/docusaurus/lib',
|
||||||
|
'/packages/docusaurus-utils/lib',
|
||||||
],
|
],
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.[jt]sx?$': 'babel-jest',
|
'^.+\\.[jt]sx?$': 'babel-jest',
|
||||||
|
|
|
@ -10,9 +10,9 @@ const blog = require('../blog');
|
||||||
const metadataUtils = require('../metadataUtils');
|
const metadataUtils = require('../metadataUtils');
|
||||||
const {replaceAssetsLink} = require('../utils.js');
|
const {replaceAssetsLink} = require('../utils.js');
|
||||||
|
|
||||||
jest.mock(`${process.cwd()}/siteConfig.js`, () => ({baseUrl: '/'}), {
|
const siteConfig = {
|
||||||
virtual: true,
|
baseUrl: '/',
|
||||||
});
|
};
|
||||||
|
|
||||||
const testFile = path.join(
|
const testFile = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
|
@ -25,16 +25,18 @@ fs.existsSync = jest.fn().mockReturnValue(true);
|
||||||
describe('getMetadata', () => {
|
describe('getMetadata', () => {
|
||||||
test('file does not exist', () => {
|
test('file does not exist', () => {
|
||||||
fs.existsSync.mockReturnValueOnce(null);
|
fs.existsSync.mockReturnValueOnce(null);
|
||||||
expect(blog.getMetadata('/this/path/does-not-exist/')).toBeNull();
|
expect(
|
||||||
|
blog.getMetadata('/this/path/does-not-exist/', siteConfig),
|
||||||
|
).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('null/undefined', () => {
|
test('null/undefined', () => {
|
||||||
expect(blog.getMetadata(null)).toBeNull();
|
expect(blog.getMetadata(null, siteConfig)).toBeNull();
|
||||||
expect(blog.getMetadata(undefined)).toBeNull();
|
expect(blog.getMetadata(undefined, siteConfig)).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('blog file', () => {
|
test('blog file', () => {
|
||||||
const metadata = blog.getMetadata(testFile);
|
const metadata = blog.getMetadata(testFile, siteConfig);
|
||||||
expect(metadata).toMatchSnapshot();
|
expect(metadata).toMatchSnapshot();
|
||||||
expect(metadata).not.toBeNull();
|
expect(metadata).not.toBeNull();
|
||||||
expect(metadata).toHaveProperty('id');
|
expect(metadata).toHaveProperty('id');
|
||||||
|
|
|
@ -71,6 +71,7 @@ describe('mdToHtmlify', () => {
|
||||||
const siteConfig = {
|
const siteConfig = {
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
docsUrl: 'docs',
|
docsUrl: 'docs',
|
||||||
|
cleanUrl: true,
|
||||||
};
|
};
|
||||||
const mdToHtml = metadataUtils.mdToHtml(Metadata, siteConfig);
|
const mdToHtml = metadataUtils.mdToHtml(Metadata, siteConfig);
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ describe('mdToHtmlify', () => {
|
||||||
rawContent1,
|
rawContent1,
|
||||||
mdToHtml,
|
mdToHtml,
|
||||||
Metadata['en-doc1'],
|
Metadata['en-doc1'],
|
||||||
|
siteConfig,
|
||||||
);
|
);
|
||||||
expect(content1).not.toContain('/docs/en/next/');
|
expect(content1).not.toContain('/docs/en/next/');
|
||||||
expect(content1).toMatchSnapshot();
|
expect(content1).toMatchSnapshot();
|
||||||
|
@ -90,6 +92,7 @@ describe('mdToHtmlify', () => {
|
||||||
rawContent2,
|
rawContent2,
|
||||||
mdToHtml,
|
mdToHtml,
|
||||||
Metadata['en-doc2'],
|
Metadata['en-doc2'],
|
||||||
|
siteConfig,
|
||||||
);
|
);
|
||||||
expect(content2).toContain('/docs/en/next/');
|
expect(content2).toContain('/docs/en/next/');
|
||||||
expect(content2).toMatchSnapshot();
|
expect(content2).toMatchSnapshot();
|
||||||
|
@ -111,6 +114,7 @@ describe('mdToHtmlify', () => {
|
||||||
rawContent3,
|
rawContent3,
|
||||||
customMdToHtml,
|
customMdToHtml,
|
||||||
customMetadata['subdir-doc3'],
|
customMetadata['subdir-doc3'],
|
||||||
|
siteConfig,
|
||||||
);
|
);
|
||||||
expect(content3).toContain('/docs/subdir/doc3');
|
expect(content3).toContain('/docs/subdir/doc3');
|
||||||
expect(content3).not.toContain('subdir/doc3.md');
|
expect(content3).not.toContain('subdir/doc3.md');
|
||||||
|
@ -123,6 +127,7 @@ describe('mdToHtmlify', () => {
|
||||||
rawContentRefLinks,
|
rawContentRefLinks,
|
||||||
mdToHtml,
|
mdToHtml,
|
||||||
Metadata['en-reflinks'],
|
Metadata['en-reflinks'],
|
||||||
|
siteConfig,
|
||||||
);
|
);
|
||||||
expect(contentRefLinks).toContain('/docs/en/next/');
|
expect(contentRefLinks).toContain('/docs/en/next/');
|
||||||
expect(contentRefLinks).toMatchSnapshot();
|
expect(contentRefLinks).toMatchSnapshot();
|
||||||
|
|
|
@ -87,7 +87,7 @@ describe('start server', () => {
|
||||||
const port = 1357;
|
const port = 1357;
|
||||||
portFinder.getPortPromise.mockResolvedValue(port);
|
portFinder.getPortPromise.mockResolvedValue(port);
|
||||||
return start.startServer().then(() => {
|
return start.startServer().then(() => {
|
||||||
expect(server).toHaveBeenCalledWith(port);
|
expect(server).toHaveBeenCalledWith(port, 'localhost');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,13 @@
|
||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
const CWD = process.cwd();
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const metadataUtils = require('./metadataUtils');
|
const metadataUtils = require('./metadataUtils');
|
||||||
const {replaceAssetsLink} = require('./utils.js');
|
const {replaceAssetsLink} = require('./utils.js');
|
||||||
const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
|
const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
|
||||||
const loadConfig = require('./config');
|
|
||||||
|
|
||||||
const siteConfig = loadConfig(`${CWD}/siteConfig.js`);
|
|
||||||
|
|
||||||
function urlToSource(url) {
|
function urlToSource(url) {
|
||||||
if (!url || typeof url !== 'string') {
|
if (!url || typeof url !== 'string') {
|
||||||
|
@ -34,14 +31,14 @@ function fileToUrl(file) {
|
||||||
.replace(/\.md$/, '.html');
|
.replace(/\.md$/, '.html');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPagesMarkup(numOfBlog, config) {
|
function getPagesMarkup(numOfBlog, siteConfig) {
|
||||||
const BlogPageLayout = require('../core/BlogPageLayout.js');
|
const BlogPageLayout = require('../core/BlogPageLayout.js');
|
||||||
const blogPages = {};
|
const blogPages = {};
|
||||||
const perPage = 10;
|
const perPage = 10;
|
||||||
for (let page = 0; page < Math.ceil(numOfBlog / perPage); page++) {
|
for (let page = 0; page < Math.ceil(numOfBlog / perPage); page++) {
|
||||||
const metadata = {page, perPage};
|
const metadata = {page, perPage};
|
||||||
const blogPageComp = (
|
const blogPageComp = (
|
||||||
<BlogPageLayout metadata={metadata} language="en" config={config} />
|
<BlogPageLayout metadata={metadata} language="en" config={siteConfig} />
|
||||||
);
|
);
|
||||||
const str = renderToStaticMarkupWithDoctype(blogPageComp);
|
const str = renderToStaticMarkupWithDoctype(blogPageComp);
|
||||||
const pagePath = `${page > 0 ? `page${page + 1}` : ''}/index.html`;
|
const pagePath = `${page > 0 ? `page${page + 1}` : ''}/index.html`;
|
||||||
|
@ -50,7 +47,7 @@ function getPagesMarkup(numOfBlog, config) {
|
||||||
return blogPages;
|
return blogPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMetadata(file) {
|
function getMetadata(file, siteConfig) {
|
||||||
if (!file || !fs.existsSync(file)) {
|
if (!file || !fs.existsSync(file)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -71,14 +68,14 @@ function getMetadata(file) {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostMarkup(file, config) {
|
function getPostMarkup(file, siteConfig) {
|
||||||
const metadata = getMetadata(file);
|
const metadata = getMetadata(file, siteConfig);
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const BlogPostLayout = require('../core/BlogPostLayout.js');
|
const BlogPostLayout = require('../core/BlogPostLayout.js');
|
||||||
const blogPostComp = (
|
const blogPostComp = (
|
||||||
<BlogPostLayout metadata={metadata} language="en" config={config}>
|
<BlogPostLayout metadata={metadata} language="en" config={siteConfig}>
|
||||||
{metadata.content}
|
{metadata.content}
|
||||||
</BlogPostLayout>
|
</BlogPostLayout>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,9 +9,7 @@ const {join} = require('path');
|
||||||
const {resolve} = require('url');
|
const {resolve} = require('url');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const loadConfig = require('./config');
|
|
||||||
|
|
||||||
const siteConfig = loadConfig(`${CWD}/siteConfig.js`);
|
|
||||||
const env = require('./env.js');
|
const env = require('./env.js');
|
||||||
const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
|
const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
|
||||||
const readMetadata = require('./readMetadata.js');
|
const readMetadata = require('./readMetadata.js');
|
||||||
|
@ -19,8 +17,6 @@ const {insertTOC} = require('../core/toc.js');
|
||||||
const {replaceAssetsLink} = require('./utils.js');
|
const {replaceAssetsLink} = require('./utils.js');
|
||||||
const {getPath} = require('../core/utils.js');
|
const {getPath} = require('../core/utils.js');
|
||||||
|
|
||||||
const docsPart = `${siteConfig.docsUrl ? `${siteConfig.docsUrl}/` : ''}`;
|
|
||||||
|
|
||||||
function getFilePath(metadata) {
|
function getFilePath(metadata) {
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -51,7 +47,7 @@ function getFile(metadata) {
|
||||||
return fs.readFileSync(file, 'utf8');
|
return fs.readFileSync(file, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
function mdToHtmlify(oldContent, mdToHtml, metadata) {
|
function mdToHtmlify(oldContent, mdToHtml, metadata, siteConfig) {
|
||||||
/* Store broken links */
|
/* Store broken links */
|
||||||
const mdBrokenLinks = [];
|
const mdBrokenLinks = [];
|
||||||
|
|
||||||
|
@ -106,12 +102,12 @@ function mdToHtmlify(oldContent, mdToHtml, metadata) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMarkup(rawContent, mdToHtml, metadata) {
|
function getMarkup(rawContent, mdToHtml, metadata, siteConfig) {
|
||||||
// generate table of contents
|
// generate table of contents
|
||||||
let content = insertTOC(rawContent);
|
let content = insertTOC(rawContent);
|
||||||
|
|
||||||
// replace any links to markdown files to their website html links
|
// replace any links to markdown files to their website html links
|
||||||
content = mdToHtmlify(content, mdToHtml, metadata);
|
content = mdToHtmlify(content, mdToHtml, metadata, siteConfig);
|
||||||
|
|
||||||
// replace any relative links to static assets (not in fenced code blocks) to absolute links
|
// replace any relative links to static assets (not in fenced code blocks) to absolute links
|
||||||
const docsAssetsLocation = siteConfig.docsUrl
|
const docsAssetsLocation = siteConfig.docsUrl
|
||||||
|
@ -130,7 +126,8 @@ function getMarkup(rawContent, mdToHtml, metadata) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRedirectMarkup(metadata) {
|
function getRedirectMarkup(metadata, siteConfig) {
|
||||||
|
const docsPart = `${siteConfig.docsUrl ? `${siteConfig.docsUrl}/` : ''}`;
|
||||||
if (
|
if (
|
||||||
!env.translation.enabled ||
|
!env.translation.enabled ||
|
||||||
!metadata.permalink.includes(`${docsPart}en`)
|
!metadata.permalink.includes(`${docsPart}en`)
|
||||||
|
|
|
@ -26,7 +26,7 @@ module.exports = function(type) {
|
||||||
|
|
||||||
type = type || 'rss';
|
type = type || 'rss';
|
||||||
|
|
||||||
readMetadata.generateMetadataBlog();
|
readMetadata.generateMetadataBlog(siteConfig);
|
||||||
const MetadataBlog = require('../core/MetadataBlog.js');
|
const MetadataBlog = require('../core/MetadataBlog.js');
|
||||||
|
|
||||||
const feed = new Feed({
|
const feed = new Feed({
|
||||||
|
|
|
@ -79,12 +79,12 @@ async function execute() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rawContent = metadataUtils.extractMetadata(file).rawContent;
|
const rawContent = metadataUtils.extractMetadata(file).rawContent;
|
||||||
const str = docs.getMarkup(rawContent, mdToHtml, metadata);
|
const str = docs.getMarkup(rawContent, mdToHtml, metadata, siteConfig);
|
||||||
const targetFile = join(buildDir, metadata.permalink);
|
const targetFile = join(buildDir, metadata.permalink);
|
||||||
writeFileAndCreateFolder(targetFile, str);
|
writeFileAndCreateFolder(targetFile, str);
|
||||||
|
|
||||||
// generate english page redirects when languages are enabled
|
// generate english page redirects when languages are enabled
|
||||||
const redirectMarkup = docs.getRedirectMarkup(metadata);
|
const redirectMarkup = docs.getRedirectMarkup(metadata, siteConfig);
|
||||||
if (!redirectMarkup) {
|
if (!redirectMarkup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ async function execute() {
|
||||||
if (fs.existsSync(join(__dirname, '..', 'core', 'MetadataBlog.js'))) {
|
if (fs.existsSync(join(__dirname, '..', 'core', 'MetadataBlog.js'))) {
|
||||||
fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
|
fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
|
||||||
}
|
}
|
||||||
readMetadata.generateMetadataBlog();
|
readMetadata.generateMetadataBlog(siteConfig);
|
||||||
const MetadataBlog = require('../core/MetadataBlog.js');
|
const MetadataBlog = require('../core/MetadataBlog.js');
|
||||||
|
|
||||||
let files = glob.sync(join(CWD, 'blog', '**', '*.*'));
|
let files = glob.sync(join(CWD, 'blog', '**', '*.*'));
|
||||||
|
|
|
@ -360,7 +360,7 @@ function generateMetadataDocs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// process metadata for blog posts and save into core/MetadataBlog.js
|
// process metadata for blog posts and save into core/MetadataBlog.js
|
||||||
function generateMetadataBlog() {
|
function generateMetadataBlog(config = siteConfig) {
|
||||||
const metadatas = [];
|
const metadatas = [];
|
||||||
|
|
||||||
const files = glob.sync(`${CWD}/blog/**/*.*`);
|
const files = glob.sync(`${CWD}/blog/**/*.*`);
|
||||||
|
@ -372,7 +372,7 @@ function generateMetadataBlog() {
|
||||||
if (extension !== '.md' && extension !== '.markdown') {
|
if (extension !== '.md' && extension !== '.markdown') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const metadata = blog.getMetadata(file);
|
const metadata = blog.getMetadata(file, config);
|
||||||
// Extract, YYYY, MM, DD from the file name
|
// Extract, YYYY, MM, DD from the file name
|
||||||
const filePathDateArr = path.basename(file).split('-');
|
const filePathDateArr = path.basename(file).split('-');
|
||||||
metadata.date = new Date(
|
metadata.date = new Date(
|
||||||
|
|
|
@ -60,6 +60,18 @@ function execute(port, host) {
|
||||||
let MetadataBlog;
|
let MetadataBlog;
|
||||||
let siteConfig;
|
let siteConfig;
|
||||||
|
|
||||||
|
function reloadSiteConfig() {
|
||||||
|
const siteConfigPath = join(CWD, 'siteConfig.js');
|
||||||
|
removeModuleAndChildrenFromCache(siteConfigPath);
|
||||||
|
const oldBaseUrl = siteConfig && siteConfig.baseUrl;
|
||||||
|
siteConfig = loadConfig(siteConfigPath);
|
||||||
|
|
||||||
|
if (oldBaseUrl && oldBaseUrl !== siteConfig.baseUrl) {
|
||||||
|
console.log('Base url has changed. Please restart server ...');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reloadMetadata() {
|
function reloadMetadata() {
|
||||||
removeModuleAndChildrenFromCache('./readMetadata.js');
|
removeModuleAndChildrenFromCache('./readMetadata.js');
|
||||||
readMetadata.generateMetadataDocs();
|
readMetadata.generateMetadataDocs();
|
||||||
|
@ -72,16 +84,11 @@ function execute(port, host) {
|
||||||
removeModuleAndChildrenFromCache(join('..', 'core', 'MetadataBlog.js'));
|
removeModuleAndChildrenFromCache(join('..', 'core', 'MetadataBlog.js'));
|
||||||
fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
|
fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
|
||||||
}
|
}
|
||||||
readMetadata.generateMetadataBlog();
|
reloadSiteConfig();
|
||||||
|
readMetadata.generateMetadataBlog(siteConfig);
|
||||||
MetadataBlog = require(join('..', 'core', 'MetadataBlog.js'));
|
MetadataBlog = require(join('..', 'core', 'MetadataBlog.js'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function reloadSiteConfig() {
|
|
||||||
const siteConfigPath = join(CWD, 'siteConfig.js');
|
|
||||||
removeModuleAndChildrenFromCache(siteConfigPath);
|
|
||||||
siteConfig = loadConfig(siteConfigPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestFile(url, res, notFoundCallback) {
|
function requestFile(url, res, notFoundCallback) {
|
||||||
request.get(url, (error, response, body) => {
|
request.get(url, (error, response, body) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
|
@ -119,10 +126,11 @@ function execute(port, host) {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
reloadSiteConfig();
|
||||||
const rawContent = metadataUtils.extractMetadata(file).rawContent;
|
const rawContent = metadataUtils.extractMetadata(file).rawContent;
|
||||||
removeModuleAndChildrenFromCache('../core/DocsLayout.js');
|
removeModuleAndChildrenFromCache('../core/DocsLayout.js');
|
||||||
const mdToHtml = metadataUtils.mdToHtml(Metadata, siteConfig);
|
const mdToHtml = metadataUtils.mdToHtml(Metadata, siteConfig);
|
||||||
res.send(docs.getMarkup(rawContent, mdToHtml, metadata));
|
res.send(docs.getMarkup(rawContent, mdToHtml, metadata, siteConfig));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get(routing.sitemap(siteConfig), (req, res) => {
|
app.get(routing.sitemap(siteConfig), (req, res) => {
|
||||||
|
@ -177,6 +185,7 @@ function execute(port, host) {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get(routing.page(siteConfig), (req, res, next) => {
|
app.get(routing.page(siteConfig), (req, res, next) => {
|
||||||
|
reloadSiteConfig();
|
||||||
// Look for user-provided HTML file first.
|
// Look for user-provided HTML file first.
|
||||||
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
|
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
|
||||||
htmlFile = join(CWD, 'pages', htmlFile);
|
htmlFile = join(CWD, 'pages', htmlFile);
|
||||||
|
|
|
@ -23,7 +23,7 @@ const readMetadata = require('./readMetadata.js');
|
||||||
readMetadata.generateMetadataDocs();
|
readMetadata.generateMetadataDocs();
|
||||||
const Metadata = require('../core/metadata.js');
|
const Metadata = require('../core/metadata.js');
|
||||||
|
|
||||||
readMetadata.generateMetadataBlog();
|
readMetadata.generateMetadataBlog(siteConfig);
|
||||||
const MetadataBlog = require('../core/MetadataBlog.js');
|
const MetadataBlog = require('../core/MetadataBlog.js');
|
||||||
|
|
||||||
module.exports = function(callback) {
|
module.exports = function(callback) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue