mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-09 23:27:28 +02:00
perf(v2): smaller bundlesize by embedding metadata to content (#2088)
* wip embed metadata to content * embed metadata in blog as well * refactor * update test * yarn lock * avoid overwriting file everytime we run new nodejs process * nits
This commit is contained in:
parent
32c9d07b90
commit
7f8aca2ddc
16 changed files with 236 additions and 200 deletions
|
@ -10,7 +10,7 @@ import globby from 'globby';
|
|||
import path from 'path';
|
||||
import {Feed} from 'feed';
|
||||
import {PluginOptions, BlogPost, DateLink} from './types';
|
||||
import {parse, normalizeUrl} from '@docusaurus/utils';
|
||||
import {parse, normalizeUrl, aliasedSitePath} from '@docusaurus/utils';
|
||||
import {LoadContext} from '@docusaurus/types';
|
||||
|
||||
export function truncate(fileString: string, truncateMarker: RegExp | string) {
|
||||
|
@ -100,10 +100,8 @@ export async function generateBlogPosts(
|
|||
|
||||
await Promise.all(
|
||||
blogFiles.map(async (relativeSource: string) => {
|
||||
// Cannot use path.join() as it resolves '../' and removes the '@site'.
|
||||
// Let webpack loader resolve it.
|
||||
const source = path.join(blogDir, relativeSource);
|
||||
const aliasedSource = `@site/${path.relative(siteDir, source)}`;
|
||||
const aliasedSource = aliasedSitePath(source, siteDir);
|
||||
const blogFileName = path.basename(relativeSource);
|
||||
|
||||
const fileString = await fs.readFile(source, 'utf-8');
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
PluginOptions,
|
||||
BlogTags,
|
||||
BlogContent,
|
||||
BlogItemsToModules,
|
||||
BlogItemsToMetadata,
|
||||
TagsModule,
|
||||
BlogPaginated,
|
||||
FeedType,
|
||||
|
@ -215,7 +215,7 @@ export default function pluginContentBlog(
|
|||
} = options;
|
||||
|
||||
const aliasedSource = (source: string) =>
|
||||
`@docusaurus-plugin-content-blog/${path.relative(dataDir, source)}`;
|
||||
`~blog/${path.relative(dataDir, source)}`;
|
||||
const {addRoute, createData} = actions;
|
||||
const {
|
||||
blogPosts,
|
||||
|
@ -224,41 +224,31 @@ export default function pluginContentBlog(
|
|||
blogTagsListPath,
|
||||
} = blogContents;
|
||||
|
||||
const blogItemsToModules: BlogItemsToModules = {};
|
||||
const blogItemsToMetadata: BlogItemsToMetadata = {};
|
||||
|
||||
// Create routes for blog entries.
|
||||
const blogItems = await Promise.all(
|
||||
await Promise.all(
|
||||
blogPosts.map(async blogPost => {
|
||||
const {id, metadata} = blogPost;
|
||||
const {permalink} = metadata;
|
||||
const metadataPath = await createData(
|
||||
`${docuHash(permalink)}.json`,
|
||||
await createData(
|
||||
// Note that this created data path must be in sync with markdownLoader.ts metadataPath
|
||||
`${docuHash(metadata.source)}.json`,
|
||||
JSON.stringify(metadata, null, 2),
|
||||
);
|
||||
const temp = {
|
||||
metadata,
|
||||
metadataPath,
|
||||
};
|
||||
|
||||
blogItemsToModules[id] = temp;
|
||||
return temp;
|
||||
addRoute({
|
||||
path: metadata.permalink,
|
||||
component: blogPostComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
content: metadata.source,
|
||||
},
|
||||
});
|
||||
|
||||
blogItemsToMetadata[id] = metadata;
|
||||
}),
|
||||
);
|
||||
|
||||
blogItems.map(blogItem => {
|
||||
const {metadata, metadataPath} = blogItem;
|
||||
const {source, permalink} = metadata;
|
||||
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component: blogPostComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
content: source,
|
||||
metadata: aliasedSource(metadataPath),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Create routes for blog's paginated list entries.
|
||||
await Promise.all(
|
||||
blogListPaginated.map(async listPage => {
|
||||
|
@ -275,20 +265,16 @@ export default function pluginContentBlog(
|
|||
exact: true,
|
||||
modules: {
|
||||
items: items.map(postID => {
|
||||
const {
|
||||
metadata: postMetadata,
|
||||
metadataPath,
|
||||
} = blogItemsToModules[postID];
|
||||
const metadata = blogItemsToMetadata[postID];
|
||||
// To tell routes.js this is an import and not a nested object to recurse.
|
||||
return {
|
||||
content: {
|
||||
__import: true,
|
||||
path: postMetadata.source,
|
||||
path: metadata.source,
|
||||
query: {
|
||||
truncated: true,
|
||||
},
|
||||
},
|
||||
metadata: aliasedSource(metadataPath),
|
||||
};
|
||||
}),
|
||||
metadata: aliasedSource(pageMetadataPath),
|
||||
|
@ -327,19 +313,15 @@ export default function pluginContentBlog(
|
|||
exact: true,
|
||||
modules: {
|
||||
items: items.map(postID => {
|
||||
const {
|
||||
metadata: postMetadata,
|
||||
metadataPath,
|
||||
} = blogItemsToModules[postID];
|
||||
const metadata = blogItemsToMetadata[postID];
|
||||
return {
|
||||
content: {
|
||||
__import: true,
|
||||
path: postMetadata.source,
|
||||
path: metadata.source,
|
||||
query: {
|
||||
truncated: true,
|
||||
},
|
||||
},
|
||||
metadata: aliasedSource(metadataPath),
|
||||
};
|
||||
}),
|
||||
metadata: aliasedSource(tagsMetadataPath),
|
||||
|
@ -375,7 +357,7 @@ export default function pluginContentBlog(
|
|||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@docusaurus-plugin-content-blog': dataDir,
|
||||
'~blog': dataDir,
|
||||
},
|
||||
},
|
||||
module: {
|
||||
|
@ -396,6 +378,8 @@ export default function pluginContentBlog(
|
|||
{
|
||||
loader: path.resolve(__dirname, './markdownLoader.js'),
|
||||
options: {
|
||||
dataDir,
|
||||
siteDir: context.siteDir,
|
||||
truncateMarker,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
const {parseQuery, getOptions} = require('loader-utils');
|
||||
import {loader} from 'webpack';
|
||||
import {truncate} from './blogUtils';
|
||||
import path from 'path';
|
||||
import {readFile} from 'fs-extra';
|
||||
import {aliasedSitePath, docuHash} from '@docusaurus/utils';
|
||||
|
||||
export = function(fileString: string) {
|
||||
const callback = this.async();
|
||||
|
||||
const {truncateMarker}: {truncateMarker: RegExp | string} = getOptions(this);
|
||||
const {truncateMarker, siteDir, dataDir} = getOptions(this);
|
||||
|
||||
let finalContent = fileString;
|
||||
|
||||
|
@ -21,5 +24,19 @@ export = function(fileString: string) {
|
|||
if (truncated) {
|
||||
finalContent = truncate(fileString, truncateMarker);
|
||||
}
|
||||
return callback && callback(null, finalContent);
|
||||
|
||||
// Read metadata & then embed it to this markdown content
|
||||
// Note that metadataPath must be the same/ in-sync as the path from createData
|
||||
const aliasedSource = aliasedSitePath(this.resourcePath, siteDir);
|
||||
const metadataPath = path.join(dataDir, `${docuHash(aliasedSource)}.json`);
|
||||
|
||||
// Add metadataPath as dependency of this loader result so that we can recompile if metadata is changed
|
||||
this.addDependency(metadataPath);
|
||||
|
||||
readFile(metadataPath, 'utf8', function(err, metadata) {
|
||||
if (err) return callback && callback(err);
|
||||
|
||||
const metadataStr = `export const metadata = ${metadata};`;
|
||||
callback && callback(null, finalContent + '\n' + metadataStr);
|
||||
});
|
||||
} as loader.Loader;
|
||||
|
|
|
@ -91,13 +91,8 @@ export interface Tag {
|
|||
permalink: string;
|
||||
}
|
||||
|
||||
export interface BlogItemsToModules {
|
||||
[key: string]: MetaDataWithPath;
|
||||
}
|
||||
|
||||
export interface MetaDataWithPath {
|
||||
metadata: MetaData;
|
||||
metadataPath: string;
|
||||
export interface BlogItemsToMetadata {
|
||||
[key: string]: MetaData;
|
||||
}
|
||||
|
||||
export interface TagsModule {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue