fix: reload siteConfig.js automatically when locally served page is refreshed (#1509)

* fix: livereload siteConfig

* fix test

* nits
This commit is contained in:
Endi 2019-05-22 22:31:51 +07:00 committed by GitHub
parent aa157969cf
commit 166816af40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 42 deletions

View file

@ -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',

View file

@ -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');

View file

@ -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();

View file

@ -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');
}); });
}); });

View file

@ -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>
); );

View file

@ -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`)

View file

@ -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({

View file

@ -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', '**', '*.*'));

View file

@ -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(

View file

@ -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);

View file

@ -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) {