diff --git a/lib/server/generate.js b/lib/server/generate.js
index cd0531a03734..f28f03001186 100644
--- a/lib/server/generate.js
+++ b/lib/server/generate.js
@@ -23,11 +23,11 @@ function execute() {
const env = require('./env.js');
const siteConfig = require(CWD + '/siteConfig.js');
const translate = require('./translate.js');
-
const feed = require('./feed.js');
const sitemap = require('./sitemap.js');
-
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
function writeFileAndCreateFolder(file, content) {
@@ -230,20 +230,23 @@ function execute() {
.sort()
.reverse()
.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') {
return;
}
// convert filename to use slashes
const filePath = path
- .basename(file)
+ .basename(normalizedFile)
.replace('-', '/')
.replace('-', '/')
.replace('-', '/')
.replace(/\.md$/, '.html');
const result = readMetadata.extractMetadata(
- fs.readFileSync(file, {encoding: 'utf8'})
+ fs.readFileSync(normalizedFile, {encoding: 'utf8'})
);
const rawContent = result.rawContent;
const metadata = Object.assign(
@@ -313,10 +316,12 @@ function execute() {
// copy all static files from docusaurus
files = glob.sync(join(__dirname, '..', 'static', '**'));
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,
- // TODO: use x-platform path functions
- file.split('/static/')[1] || ''
+ targetFile.split(sep + 'static' + sep)[1] || ''
);
// parse css files to replace colors according to siteConfig
if (file.match(/\.css$/)) {
@@ -369,10 +374,13 @@ function execute() {
// copy all static files from user
files = glob.sync(join(CWD, 'static', '**'), {dot: true});
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
- if (file.match(/\.css$/) && !isSeparateCss(file)) {
+ if (normalizedFile.match(/\.css$/) && !isSeparateCss(normalizedFile)) {
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;
Object.keys(siteConfig.colors).forEach(key => {
@@ -393,11 +401,11 @@ function execute() {
}
fs.writeFileSync(mainCss, cssContent);
- } else if (!fs.lstatSync(file).isDirectory()) {
- let parts = file.split('/static/');
+ } else if (!fs.lstatSync(normalizedFile).isDirectory()) {
+ let parts = normalizedFile.split(sep + 'static' + sep);
let targetFile = join(buildDir, parts[1]);
mkdirp.sync(path.dirname(targetFile));
- fs.copySync(file, targetFile);
+ fs.copySync(normalizedFile, targetFile);
}
});
@@ -405,28 +413,35 @@ function execute() {
let pagesArr = [];
files = glob.sync(join(CWD, 'pages', '**'));
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
- if (file.match(/\.js$/)) {
- const pageID = path.basename(file, '.js');
+ if (normalizedFile.match(/\.js$/)) {
+ const pageID = path.basename(normalizedFile, '.js');
// 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]);
tempFile = tempFile.replace(
- path.basename(file),
- 'temp' + path.basename(file)
+ path.basename(normalizedFile),
+ 'temp' + path.basename(normalizedFile)
);
mkdirp.sync(path.dirname(tempFile));
- fs.copySync(file, tempFile);
+ fs.copySync(normalizedFile, tempFile);
const ReactComp = require(tempFile);
let targetFile = join(buildDir, parts[1]);
targetFile = targetFile.replace(/\.js$/, '.html');
- const regexLang = /\/pages\/(.*)\//;
- const match = regexLang.exec(file);
- const langParts = match[1].split('/');
+ const regexLang = new RegExp(
+ escapeStringRegexp(sep + 'pages' + sep) +
+ '(.*)' +
+ escapeStringRegexp(sep)
+ );
+ const match = regexLang.exec(normalizedFile);
+ const langParts = match[1].split(sep);
if (langParts.indexOf('en') !== -1) {
// copy and compile a page for each enabled language from the English file
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
if (
language !== 'en' &&
- // TODO: use path functions
- fs.existsSync(file.replace('/en/', '/' + language + '/'))
+ fs.existsSync(
+ normalizedFile.replace(sep + 'en' + sep, sep + language + sep)
+ )
) {
continue;
}
@@ -450,7 +466,7 @@ function execute() {
);
writeFileAndCreateFolder(
// TODO: use path functions
- targetFile.replace('/en/', '/' + language + '/'),
+ targetFile.replace(sep + 'en' + sep, sep + language + sep),
str
);
}
@@ -463,7 +479,10 @@ function execute() {
);
- writeFileAndCreateFolder(targetFile.replace('/en/', '/'), str);
+ writeFileAndCreateFolder(
+ targetFile.replace(sep + 'en' + sep, sep),
+ str
+ );
} else {
// allow for rendering of other files not in pages/en folder
let language = env.translation.enabled ? 'en' : '';
@@ -473,30 +492,30 @@ function execute() {
);
- writeFileAndCreateFolder(targetFile.replace('/en/', '/'), str);
+ writeFileAndCreateFolder(targetFile.replace(sep + en + sep, sep), str);
}
fs.removeSync(tempFile);
- } else if (siteConfig.wrapPagesHTML && file.match(/\.html$/)) {
- const pageID = path.basename(file, '.html');
- const parts = file.split('pages');
+ } else if (siteConfig.wrapPagesHTML && normalizedFile.match(/\.html$/)) {
+ const pageID = path.basename(normalizedFile, '.html');
+ const parts = normalizedFile.split('pages');
const targetFile = join(buildDir, parts[1]);
const str = renderToStaticMarkup(
);
writeFileAndCreateFolder(targetFile, str);
- } else if (!fs.lstatSync(file).isDirectory()) {
+ } else if (!fs.lstatSync(normalizedFile).isDirectory()) {
// copy other non .js files
- let parts = file.split('pages');
+ let parts = normalizedFile.split('pages');
let targetFile = join(buildDir, parts[1]);
mkdirp.sync(path.dirname(targetFile));
- fs.copySync(file, targetFile);
+ fs.copySync(normalizedFile, targetFile);
}
});
diff --git a/lib/server/server.js b/lib/server/server.js
index a151e3834217..884e8aecf08a 100644
--- a/lib/server/server.js
+++ b/lib/server/server.js
@@ -31,6 +31,9 @@ function execute(port) {
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
// to be restarted
function removeModuleAndChildrenFromCache(moduleName) {
@@ -68,17 +71,17 @@ function execute(port) {
}
function reloadMetadataBlog() {
- if (fs.existsSync(__dirname + '/../core/MetadataBlog.js')) {
- removeModuleAndChildrenFromCache('../core/MetadataBlog.js');
- fs.removeSync(__dirname + '/../core/MetadataBlog.js');
+ if (fs.existsSync(join(__dirname, '..', 'core', 'MetadataBlog.js'))) {
+ removeModuleAndChildrenFromCache(join('..', 'core', 'MetadataBlog.js'));
+ fs.removeSync(join(__dirname, '..', 'core', 'MetadataBlog.js'));
}
readMetadata.generateMetadataBlog();
- MetadataBlog = require('../core/MetadataBlog.js');
+ MetadataBlog = require(join('..', 'core', 'MetadataBlog.js'));
}
function reloadSiteConfig() {
- removeModuleAndChildrenFromCache(CWD + '/siteConfig.js');
- siteConfig = require(CWD + '/siteConfig.js');
+ removeModuleAndChildrenFromCache(join(CWD, 'siteConfig.js'));
+ siteConfig = require(join(CWD, '/siteConfig.js'));
if (siteConfig.highlight && siteConfig.highlight.hljs) {
siteConfig.highlight.hljs(require('highlight.js'));
@@ -167,18 +170,15 @@ function execute(port) {
let file;
if (metadata.original_id) {
if (env.translation.enabled && metadata.language !== 'en') {
- file =
- CWD + '/translated_docs/' + metadata.language + '/' + metadata.source;
+ file = join(CWD, 'translated_docs', metadata.language, metadata.source);
} else {
- file = CWD + '/versioned_docs/' + metadata.source;
+ file = join(CWD, 'versioned_docs' + metadata.source);
}
} else {
if (!env.translation.enabled || metadata.language === 'en') {
- file =
- CWD + '/../' + readMetadata.getDocsPath() + '/' + metadata.source;
+ file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
} else {
- file =
- CWD + '/translated_docs/' + metadata.language + '/' + metadata.source;
+ file = join(CWD, 'translated_docs', metadata.language, metadata.source);
}
}
@@ -274,8 +274,8 @@ function execute(port) {
// handle all requests for blog pages and posts
app.get(/blog\/.*html$/, (req, res) => {
// generate all of the blog pages
- removeModuleAndChildrenFromCache('../core/BlogPageLayout.js');
- const BlogPageLayout = require('../core/BlogPageLayout.js');
+ removeModuleAndChildrenFromCache(join('..', 'core', 'BlogPageLayout.js'));
+ const BlogPageLayout = require(join('..', 'core', 'BlogPageLayout.js'));
const blogPages = {};
// make blog pages with 10 posts per page
const perPage = 10;
@@ -316,7 +316,7 @@ function execute(port) {
let file = parts[1];
file = file.replace(/\.html$/, '.md');
file = file.replace(new RegExp('/', 'g'), '-');
- file = CWD + '/blog/' + file;
+ file = join(CWD, 'blog', file);
const result = readMetadata.extractMetadata(
fs.readFileSync(file, {encoding: 'utf8'})
@@ -333,8 +333,8 @@ function execute(port) {
metadata.id = metadata.title;
let language = 'en';
- removeModuleAndChildrenFromCache('../core/BlogPostLayout.js');
- const BlogPostLayout = require('../core/BlogPostLayout.js');
+ removeModuleAndChildrenFromCache(join('..', 'core', 'BlogPostLayout.js'));
+ const BlogPostLayout = require(join('..', 'core', 'BlogPostLayout.js'));
const blogPostComp = (
{
// look for user provided html file first
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
- htmlFile = CWD + '/pages/' + htmlFile;
+ htmlFile = join(CWD, 'pages', htmlFile);
if (
fs.existsSync(htmlFile) ||
fs.existsSync(
(htmlFile = htmlFile.replace(
path.basename(htmlFile),
- 'en/' + path.basename(htmlFile)
+ join('en', path.basename(htmlFile))
))
)
) {
if (siteConfig.wrapPagesHTML) {
- removeModuleAndChildrenFromCache('../core/Site.js');
- const Site = require('../core/Site.js');
+ removeModuleAndChildrenFromCache(join('..', 'core', 'Site.js'));
+ const Site = require(join('..', 'core', 'Site.js'));
const str = renderToStaticMarkup(
{
- const mainCssPath =
- __dirname +
- '/../static/' +
- req.path.toString().replace(siteConfig.baseUrl, '/');
+ const mainCssPath = join(
+ __dirname,
+ '..',
+ 'static',
+ req.path.toString().replace(siteConfig.baseUrl, '/')
+ );
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 => {
if (isSeparateCss(file)) {
@@ -510,15 +512,15 @@ function execute(port) {
// serve static assets from these locations
app.use(
- siteConfig.baseUrl + 'docs/assets/',
- express.static(CWD + '/../' + readMetadata.getDocsPath() + '/assets')
+ join(siteConfig.baseUrl, 'docs', 'assets'),
+ express.static(join(CWD, '..', readMetadata.getDocsPath(), 'assets'))
);
app.use(
- siteConfig.baseUrl + 'blog/assets/',
- express.static(CWD + '/blog/assets')
+ join(siteConfig.baseUrl, 'blog', 'assets'),
+ express.static(join(CWD, 'blog', 'assets'))
);
- app.use(siteConfig.baseUrl, express.static(CWD + '/static'));
- app.use(siteConfig.baseUrl, express.static(__dirname + '/../static'));
+ app.use(siteConfig.baseUrl, express.static(join(CWD, 'static')));
+ app.use(siteConfig.baseUrl, express.static(join(__dirname, '..', 'static')));
// "redirect" requests to pages ending with "/" or no extension so that,
// for example, request to "blog" returns same result as "blog/index.html"