Use Path module functions and properties in server and generate (#490)

This commit is contained in:
Joel Marcey 2018-03-12 16:01:40 -07:00 committed by GitHub
parent 7647ba3484
commit cbdab2ba11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 75 deletions

View file

@ -23,11 +23,11 @@ function execute() {
const env = require('./env.js'); const env = require('./env.js');
const siteConfig = require(CWD + '/siteConfig.js'); const siteConfig = require(CWD + '/siteConfig.js');
const translate = require('./translate.js'); const translate = require('./translate.js');
const feed = require('./feed.js'); const feed = require('./feed.js');
const sitemap = require('./sitemap.js'); const sitemap = require('./sitemap.js');
const join = path.join; const join = path.join;
const sep = path.sep;
const escapeStringRegexp = require('escape-string-regexp');
// create the folder path for a file if it does not exist, then write the file // create the folder path for a file if it does not exist, then write the file
function writeFileAndCreateFolder(file, content) { function writeFileAndCreateFolder(file, content) {
@ -230,20 +230,23 @@ function execute() {
.sort() .sort()
.reverse() .reverse()
.forEach(file => { .forEach(file => {
const extension = path.extname(file); // Why normalize? In case we are on Windows.
// Remember the nuance of glob: https://www.npmjs.com/package/glob#windows
let normalizedFile = path.normalize(file);
const extension = path.extname(normalizedFile);
if (extension !== '.md' && extension !== '.markdown') { if (extension !== '.md' && extension !== '.markdown') {
return; return;
} }
// convert filename to use slashes // convert filename to use slashes
const filePath = path const filePath = path
.basename(file) .basename(normalizedFile)
.replace('-', '/') .replace('-', '/')
.replace('-', '/') .replace('-', '/')
.replace('-', '/') .replace('-', '/')
.replace(/\.md$/, '.html'); .replace(/\.md$/, '.html');
const result = readMetadata.extractMetadata( const result = readMetadata.extractMetadata(
fs.readFileSync(file, {encoding: 'utf8'}) fs.readFileSync(normalizedFile, {encoding: 'utf8'})
); );
const rawContent = result.rawContent; const rawContent = result.rawContent;
const metadata = Object.assign( const metadata = Object.assign(
@ -313,10 +316,12 @@ function execute() {
// copy all static files from docusaurus // copy all static files from docusaurus
files = glob.sync(join(__dirname, '..', 'static', '**')); files = glob.sync(join(__dirname, '..', 'static', '**'));
files.forEach(file => { files.forEach(file => {
let targetFile = join( // Why normalize? In case we are on Windows.
// Remember the nuance of glob: https://www.npmjs.com/package/glob#windows
let targetFile = path.normalize(file);
targetFile = join(
buildDir, buildDir,
// TODO: use x-platform path functions targetFile.split(sep + 'static' + sep)[1] || ''
file.split('/static/')[1] || ''
); );
// parse css files to replace colors according to siteConfig // parse css files to replace colors according to siteConfig
if (file.match(/\.css$/)) { if (file.match(/\.css$/)) {
@ -369,10 +374,13 @@ function execute() {
// copy all static files from user // copy all static files from user
files = glob.sync(join(CWD, 'static', '**'), {dot: true}); files = glob.sync(join(CWD, 'static', '**'), {dot: true});
files.forEach(file => { files.forEach(file => {
// Why normalize? In case we are on Windows.
// Remember the nuance of glob: https://www.npmjs.com/package/glob#windows
let normalizedFile = path.normalize(file);
// parse css files to replace colors and fonts according to siteConfig // parse css files to replace colors and fonts according to siteConfig
if (file.match(/\.css$/) && !isSeparateCss(file)) { if (normalizedFile.match(/\.css$/) && !isSeparateCss(normalizedFile)) {
const mainCss = join(buildDir, 'css', 'main.css'); const mainCss = join(buildDir, 'css', 'main.css');
let cssContent = fs.readFileSync(file, 'utf8'); let cssContent = fs.readFileSync(normalizedFile, 'utf8');
cssContent = fs.readFileSync(mainCss, 'utf8') + '\n' + cssContent; cssContent = fs.readFileSync(mainCss, 'utf8') + '\n' + cssContent;
Object.keys(siteConfig.colors).forEach(key => { Object.keys(siteConfig.colors).forEach(key => {
@ -393,11 +401,11 @@ function execute() {
} }
fs.writeFileSync(mainCss, cssContent); fs.writeFileSync(mainCss, cssContent);
} else if (!fs.lstatSync(file).isDirectory()) { } else if (!fs.lstatSync(normalizedFile).isDirectory()) {
let parts = file.split('/static/'); let parts = normalizedFile.split(sep + 'static' + sep);
let targetFile = join(buildDir, parts[1]); let targetFile = join(buildDir, parts[1]);
mkdirp.sync(path.dirname(targetFile)); mkdirp.sync(path.dirname(targetFile));
fs.copySync(file, targetFile); fs.copySync(normalizedFile, targetFile);
} }
}); });
@ -405,28 +413,35 @@ function execute() {
let pagesArr = []; let pagesArr = [];
files = glob.sync(join(CWD, 'pages', '**')); files = glob.sync(join(CWD, 'pages', '**'));
files.forEach(file => { files.forEach(file => {
// Why normalize? In case we are on Windows.
// Remember the nuance of glob: https://www.npmjs.com/package/glob#windows
let normalizedFile = path.normalize(file);
// render .js files to strings // render .js files to strings
if (file.match(/\.js$/)) { if (normalizedFile.match(/\.js$/)) {
const pageID = path.basename(file, '.js'); const pageID = path.basename(normalizedFile, '.js');
// make temp file for sake of require paths // make temp file for sake of require paths
const parts = file.split('pages'); const parts = normalizedFile.split('pages');
let tempFile = join(__dirname, '..', 'pages', parts[1]); let tempFile = join(__dirname, '..', 'pages', parts[1]);
tempFile = tempFile.replace( tempFile = tempFile.replace(
path.basename(file), path.basename(normalizedFile),
'temp' + path.basename(file) 'temp' + path.basename(normalizedFile)
); );
mkdirp.sync(path.dirname(tempFile)); mkdirp.sync(path.dirname(tempFile));
fs.copySync(file, tempFile); fs.copySync(normalizedFile, tempFile);
const ReactComp = require(tempFile); const ReactComp = require(tempFile);
let targetFile = join(buildDir, parts[1]); let targetFile = join(buildDir, parts[1]);
targetFile = targetFile.replace(/\.js$/, '.html'); targetFile = targetFile.replace(/\.js$/, '.html');
const regexLang = /\/pages\/(.*)\//; const regexLang = new RegExp(
const match = regexLang.exec(file); escapeStringRegexp(sep + 'pages' + sep) +
const langParts = match[1].split('/'); '(.*)' +
escapeStringRegexp(sep)
);
const match = regexLang.exec(normalizedFile);
const langParts = match[1].split(sep);
if (langParts.indexOf('en') !== -1) { if (langParts.indexOf('en') !== -1) {
// copy and compile a page for each enabled language from the English file // copy and compile a page for each enabled language from the English file
for (let i = 0; i < enabledLanguages.length; i++) { for (let i = 0; i < enabledLanguages.length; i++) {
@ -434,8 +449,9 @@ function execute() {
// skip conversion from english file if a file exists for this language // skip conversion from english file if a file exists for this language
if ( if (
language !== 'en' && language !== 'en' &&
// TODO: use path functions fs.existsSync(
fs.existsSync(file.replace('/en/', '/' + language + '/')) normalizedFile.replace(sep + 'en' + sep, sep + language + sep)
)
) { ) {
continue; continue;
} }
@ -450,7 +466,7 @@ function execute() {
); );
writeFileAndCreateFolder( writeFileAndCreateFolder(
// TODO: use path functions // TODO: use path functions
targetFile.replace('/en/', '/' + language + '/'), targetFile.replace(sep + 'en' + sep, sep + language + sep),
str str
); );
} }
@ -463,7 +479,10 @@ function execute() {
<ReactComp language={language} /> <ReactComp language={language} />
</Site> </Site>
); );
writeFileAndCreateFolder(targetFile.replace('/en/', '/'), str); writeFileAndCreateFolder(
targetFile.replace(sep + 'en' + sep, sep),
str
);
} else { } else {
// allow for rendering of other files not in pages/en folder // allow for rendering of other files not in pages/en folder
let language = env.translation.enabled ? 'en' : ''; let language = env.translation.enabled ? 'en' : '';
@ -473,30 +492,30 @@ function execute() {
<ReactComp language={language} /> <ReactComp language={language} />
</Site> </Site>
); );
writeFileAndCreateFolder(targetFile.replace('/en/', '/'), str); writeFileAndCreateFolder(targetFile.replace(sep + en + sep, sep), str);
} }
fs.removeSync(tempFile); fs.removeSync(tempFile);
} else if (siteConfig.wrapPagesHTML && file.match(/\.html$/)) { } else if (siteConfig.wrapPagesHTML && normalizedFile.match(/\.html$/)) {
const pageID = path.basename(file, '.html'); const pageID = path.basename(normalizedFile, '.html');
const parts = file.split('pages'); const parts = normalizedFile.split('pages');
const targetFile = join(buildDir, parts[1]); const targetFile = join(buildDir, parts[1]);
const str = renderToStaticMarkup( const str = renderToStaticMarkup(
<Site language="en" config={siteConfig} metadata={{id: pageID}}> <Site language="en" config={siteConfig} metadata={{id: pageID}}>
<div <div
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: fs.readFileSync(file, {encoding: 'utf8'}), __html: fs.readFileSync(normalizedFile, {encoding: 'utf8'}),
}} }}
/> />
</Site> </Site>
); );
writeFileAndCreateFolder(targetFile, str); writeFileAndCreateFolder(targetFile, str);
} else if (!fs.lstatSync(file).isDirectory()) { } else if (!fs.lstatSync(normalizedFile).isDirectory()) {
// copy other non .js files // copy other non .js files
let parts = file.split('pages'); let parts = normalizedFile.split('pages');
let targetFile = join(buildDir, parts[1]); let targetFile = join(buildDir, parts[1]);
mkdirp.sync(path.dirname(targetFile)); mkdirp.sync(path.dirname(targetFile));
fs.copySync(file, targetFile); fs.copySync(normalizedFile, targetFile);
} }
}); });

View file

@ -31,6 +31,9 @@ function execute(port) {
const CWD = process.cwd(); const CWD = process.cwd();
const join = path.join;
const sep = path.sep;
// remove a module and child modules from require cache, so server does not have // remove a module and child modules from require cache, so server does not have
// to be restarted // to be restarted
function removeModuleAndChildrenFromCache(moduleName) { function removeModuleAndChildrenFromCache(moduleName) {
@ -68,17 +71,17 @@ function execute(port) {
} }
function reloadMetadataBlog() { function reloadMetadataBlog() {
if (fs.existsSync(__dirname + '/../core/MetadataBlog.js')) { if (fs.existsSync(join(__dirname, '..', 'core', 'MetadataBlog.js'))) {
removeModuleAndChildrenFromCache('../core/MetadataBlog.js'); removeModuleAndChildrenFromCache(join('..', 'core', 'MetadataBlog.js'));
fs.removeSync(__dirname + '/../core/MetadataBlog.js'); fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
} }
readMetadata.generateMetadataBlog(); readMetadata.generateMetadataBlog();
MetadataBlog = require('../core/MetadataBlog.js'); MetadataBlog = require(join('..', 'core', 'MetadataBlog.js'));
} }
function reloadSiteConfig() { function reloadSiteConfig() {
removeModuleAndChildrenFromCache(CWD + '/siteConfig.js'); removeModuleAndChildrenFromCache(join(CWD, 'siteConfig.js'));
siteConfig = require(CWD + '/siteConfig.js'); siteConfig = require(join(CWD, '/siteConfig.js'));
if (siteConfig.highlight && siteConfig.highlight.hljs) { if (siteConfig.highlight && siteConfig.highlight.hljs) {
siteConfig.highlight.hljs(require('highlight.js')); siteConfig.highlight.hljs(require('highlight.js'));
@ -167,18 +170,15 @@ function execute(port) {
let file; let file;
if (metadata.original_id) { if (metadata.original_id) {
if (env.translation.enabled && metadata.language !== 'en') { if (env.translation.enabled && metadata.language !== 'en') {
file = file = join(CWD, 'translated_docs', metadata.language, metadata.source);
CWD + '/translated_docs/' + metadata.language + '/' + metadata.source;
} else { } else {
file = CWD + '/versioned_docs/' + metadata.source; file = join(CWD, 'versioned_docs' + metadata.source);
} }
} else { } else {
if (!env.translation.enabled || metadata.language === 'en') { if (!env.translation.enabled || metadata.language === 'en') {
file = file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
CWD + '/../' + readMetadata.getDocsPath() + '/' + metadata.source;
} else { } else {
file = file = join(CWD, 'translated_docs', metadata.language, metadata.source);
CWD + '/translated_docs/' + metadata.language + '/' + metadata.source;
} }
} }
@ -274,8 +274,8 @@ function execute(port) {
// handle all requests for blog pages and posts // handle all requests for blog pages and posts
app.get(/blog\/.*html$/, (req, res) => { app.get(/blog\/.*html$/, (req, res) => {
// generate all of the blog pages // generate all of the blog pages
removeModuleAndChildrenFromCache('../core/BlogPageLayout.js'); removeModuleAndChildrenFromCache(join('..', 'core', 'BlogPageLayout.js'));
const BlogPageLayout = require('../core/BlogPageLayout.js'); const BlogPageLayout = require(join('..', 'core', 'BlogPageLayout.js'));
const blogPages = {}; const blogPages = {};
// make blog pages with 10 posts per page // make blog pages with 10 posts per page
const perPage = 10; const perPage = 10;
@ -316,7 +316,7 @@ function execute(port) {
let file = parts[1]; let file = parts[1];
file = file.replace(/\.html$/, '.md'); file = file.replace(/\.html$/, '.md');
file = file.replace(new RegExp('/', 'g'), '-'); file = file.replace(new RegExp('/', 'g'), '-');
file = CWD + '/blog/' + file; file = join(CWD, 'blog', file);
const result = readMetadata.extractMetadata( const result = readMetadata.extractMetadata(
fs.readFileSync(file, {encoding: 'utf8'}) fs.readFileSync(file, {encoding: 'utf8'})
@ -333,8 +333,8 @@ function execute(port) {
metadata.id = metadata.title; metadata.id = metadata.title;
let language = 'en'; let language = 'en';
removeModuleAndChildrenFromCache('../core/BlogPostLayout.js'); removeModuleAndChildrenFromCache(join('..', 'core', 'BlogPostLayout.js'));
const BlogPostLayout = require('../core/BlogPostLayout.js'); const BlogPostLayout = require(join('..', 'core', 'BlogPostLayout.js'));
const blogPostComp = ( const blogPostComp = (
<BlogPostLayout <BlogPostLayout
@ -352,19 +352,19 @@ function execute(port) {
app.get('*.html', (req, res, next) => { app.get('*.html', (req, res, next) => {
// 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 = CWD + '/pages/' + htmlFile; htmlFile = join(CWD, 'pages', htmlFile);
if ( if (
fs.existsSync(htmlFile) || fs.existsSync(htmlFile) ||
fs.existsSync( fs.existsSync(
(htmlFile = htmlFile.replace( (htmlFile = htmlFile.replace(
path.basename(htmlFile), path.basename(htmlFile),
'en/' + path.basename(htmlFile) join('en', path.basename(htmlFile))
)) ))
) )
) { ) {
if (siteConfig.wrapPagesHTML) { if (siteConfig.wrapPagesHTML) {
removeModuleAndChildrenFromCache('../core/Site.js'); removeModuleAndChildrenFromCache(join('..', 'core', 'Site.js'));
const Site = require('../core/Site.js'); const Site = require(join('..', 'core', 'Site.js'));
const str = renderToStaticMarkup( const str = renderToStaticMarkup(
<Site <Site
language="en" language="en"
@ -388,7 +388,7 @@ function execute(port) {
// look for user provided react file either in specified path or in path for english files // look for user provided react file either in specified path or in path for english files
let file = req.path.toString().replace(/\.html$/, '.js'); let file = req.path.toString().replace(/\.html$/, '.js');
file = file.replace(siteConfig.baseUrl, ''); file = file.replace(siteConfig.baseUrl, '');
let userFile = CWD + '/pages/' + file; let userFile = join(CWD, 'pages', file);
let language = env.translation.enabled ? 'en' : ''; let language = env.translation.enabled ? 'en' : '';
const regexLang = /(.*)\/.*\.html$/; const regexLang = /(.*)\/.*\.html$/;
@ -403,9 +403,9 @@ function execute(port) {
language = parts[i]; language = parts[i];
} }
} }
let englishFile = CWD + '/pages/' + file; let englishFile = join(CWD, 'pages', file);
if (language && language !== 'en') { if (language && language !== 'en') {
englishFile = englishFile.replace('/' + language + '/', '/en/'); englishFile = englishFile.replace(sep + language + sep, sep + 'en' + sep);
} }
// check for: a file for the page, an english file for page with unspecified language, or an // check for: a file for the page, an english file for page with unspecified language, or an
@ -415,14 +415,14 @@ function execute(port) {
fs.existsSync( fs.existsSync(
(userFile = userFile.replace( (userFile = userFile.replace(
path.basename(userFile), path.basename(userFile),
'en/' + path.basename(userFile) 'en' + sep + path.basename(userFile)
)) ))
) || ) ||
fs.existsSync((userFile = englishFile)) fs.existsSync((userFile = englishFile))
) { ) {
// copy into docusaurus so require paths work // copy into docusaurus so require paths work
let parts = userFile.split('pages/'); let parts = userFile.split('pages' + sep);
let tempFile = __dirname + '/../pages/' + parts[1]; let tempFile = join(__dirname, '..', 'pages', parts[1]);
tempFile = tempFile.replace( tempFile = tempFile.replace(
path.basename(file), path.basename(file),
'temp' + path.basename(file) 'temp' + path.basename(file)
@ -433,8 +433,8 @@ function execute(port) {
// render into a string // render into a string
removeModuleAndChildrenFromCache(tempFile); removeModuleAndChildrenFromCache(tempFile);
const ReactComp = require(tempFile); const ReactComp = require(tempFile);
removeModuleAndChildrenFromCache('../core/Site.js'); removeModuleAndChildrenFromCache(join('..', 'core', 'Site.js'));
const Site = require('../core/Site.js'); const Site = require(join('..', 'core', 'Site.js'));
translate.setLanguage(language); translate.setLanguage(language);
const str = renderToStaticMarkup( const str = renderToStaticMarkup(
<Site <Site
@ -456,13 +456,15 @@ function execute(port) {
// generate the main.css file by concatenating user provided css to the end // generate the main.css file by concatenating user provided css to the end
app.get(/main\.css$/, (req, res) => { app.get(/main\.css$/, (req, res) => {
const mainCssPath = const mainCssPath = join(
__dirname + __dirname,
'/../static/' + '..',
req.path.toString().replace(siteConfig.baseUrl, '/'); 'static',
req.path.toString().replace(siteConfig.baseUrl, '/')
);
let cssContent = fs.readFileSync(mainCssPath, {encoding: 'utf8'}); let cssContent = fs.readFileSync(mainCssPath, {encoding: 'utf8'});
let files = glob.sync(CWD + '/static/**/*.css'); let files = glob.sync(join(CWD, 'static', '**', '*.css'));
files.forEach(file => { files.forEach(file => {
if (isSeparateCss(file)) { if (isSeparateCss(file)) {
@ -510,15 +512,15 @@ function execute(port) {
// serve static assets from these locations // serve static assets from these locations
app.use( app.use(
siteConfig.baseUrl + 'docs/assets/', join(siteConfig.baseUrl, 'docs', 'assets'),
express.static(CWD + '/../' + readMetadata.getDocsPath() + '/assets') express.static(join(CWD, '..', readMetadata.getDocsPath(), 'assets'))
); );
app.use( app.use(
siteConfig.baseUrl + 'blog/assets/', join(siteConfig.baseUrl, 'blog', 'assets'),
express.static(CWD + '/blog/assets') express.static(join(CWD, 'blog', 'assets'))
); );
app.use(siteConfig.baseUrl, express.static(CWD + '/static')); app.use(siteConfig.baseUrl, express.static(join(CWD, 'static')));
app.use(siteConfig.baseUrl, express.static(__dirname + '/../static')); app.use(siteConfig.baseUrl, express.static(join(__dirname, '..', 'static')));
// "redirect" requests to pages ending with "/" or no extension so that, // "redirect" requests to pages ending with "/" or no extension so that,
// for example, request to "blog" returns same result as "blog/index.html" // for example, request to "blog" returns same result as "blog/index.html"