Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): easier plugin theme components swizzling #1436

Merged
merged 6 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 4 additions & 16 deletions packages/docusaurus-plugin-content-blog/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,24 +156,12 @@ class DocusaurusPluginContentBlog {
);
}

getThemePath() {
return path.resolve(__dirname, './theme');
}

configureWebpack(config, isServer, {getBabelLoader, getCacheLoader}) {
return {
resolve: {
alias: {
'@theme/BlogListPage': path.resolve(
__dirname,
'./theme/BlogListPage',
),
'@theme/BlogPostItem': path.resolve(
__dirname,
'./theme/BlogPostItem',
),
'@theme/BlogPostPage': path.resolve(
__dirname,
'./theme/BlogPostPage',
),
},
},
module: {
rules: [
{
Expand Down
15 changes: 4 additions & 11 deletions packages/docusaurus-plugin-content-docs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,12 @@ class DocusaurusPluginContentDocs {
});
}

getThemePath() {
return path.resolve(__dirname, './theme');
}

configureWebpack(config, isServer, {getBabelLoader, getCacheLoader}) {
return {
resolve: {
alias: {
'@theme/DocItem': path.resolve(__dirname, './theme/DocItem'),
'@theme/DocPage': path.resolve(__dirname, './theme/DocPage'),
'@theme/DocPaginator': path.resolve(
__dirname,
'./theme/DocPaginator',
),
'@theme/DocSidebar': path.resolve(__dirname, './theme/DocSidebar'),
},
},
module: {
rules: [
{
Expand Down
14 changes: 2 additions & 12 deletions packages/docusaurus-theme-classic/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,8 @@ class DocusaurusThemeDefault {
return 'docusaurus-theme-classic';
}

configureWebpack() {
return {
resolve: {
alias: {
'@theme/Footer': path.resolve(__dirname, './theme/Footer'),
'@theme/Layout': path.resolve(__dirname, './theme/Layout'),
'@theme/Navbar': path.resolve(__dirname, './theme/Navbar'),
'@theme/NotFound': path.resolve(__dirname, './theme/NotFound'),
'@theme/Search': path.resolve(__dirname, './theme/Search'),
},
},
};
getThemePath() {
return path.resolve(__dirname, './theme');
}
}

Expand Down
10 changes: 5 additions & 5 deletions packages/docusaurus/bin/docusaurus.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const envinfo = require('envinfo');
const semver = require('semver');
const path = require('path');
const program = require('commander');
const {build, eject, init, deploy, start} = require('../lib');
const {build, swizzle, init, deploy, start} = require('../lib');
const requiredVersion = require('../package.json').engines.node;

if (!semver.satisfies(process.version, requiredVersion)) {
Expand Down Expand Up @@ -55,10 +55,10 @@ program
});

program
.command('eject [siteDir]')
.description('copy the default theme into website folder for customization.')
.action((siteDir = '.') => {
wrapCommand(eject)(path.resolve(siteDir));
.command('swizzle <themeName> [componentName] [siteDir]')
.description('Copy the theme files into website folder for customization.')
.action((themeName, componentName, siteDir = '.') => {
wrapCommand(swizzle)(path.resolve(siteDir), themeName, componentName);
});

program
Expand Down
23 changes: 0 additions & 23 deletions packages/docusaurus/lib/commands/eject.js

This file was deleted.

36 changes: 36 additions & 0 deletions packages/docusaurus/lib/commands/swizzle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

const fs = require('fs-extra');
const chalk = require('chalk');
const path = require('path');
const importFresh = require('import-fresh');

module.exports = async function swizzle(siteDir, themeName, componentName) {
const Plugin = importFresh(themeName);
const context = {siteDir};
const PluginInstance = new Plugin(context);
let fromPath = PluginInstance.getThemePath();

if (fromPath) {
let toPath = path.resolve(siteDir, 'theme');
if (componentName) {
fromPath = path.join(fromPath, componentName);
toPath = path.join(toPath, componentName);
}
await fs.copy(fromPath, toPath);

const relativeDir = path.relative(process.cwd(), toPath);
const fromMsg = chalk.blue(
componentName ? `${themeName}/${componentName}` : themeName,
);
const toMsg = chalk.cyan(relativeDir);
console.log(
`\n${chalk.green('Success!')} Copied ${fromMsg} to ${toMsg}.\n`,
);
}
};
4 changes: 2 additions & 2 deletions packages/docusaurus/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
const build = require('./commands/build');
const init = require('./commands/init');
const start = require('./commands/start');
const eject = require('./commands/eject');
const swizzle = require('./commands/swizzle');
const deploy = require('./commands/deploy');

module.exports = {
build,
eject,
swizzle,
init,
start,
deploy,
Expand Down
48 changes: 36 additions & 12 deletions packages/docusaurus/lib/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,42 @@ module.exports = async function load(siteDir, cliOptions = {}) {
const outDir = path.resolve(siteDir, 'build');
const {baseUrl} = siteConfig;

// Resolve custom theme override aliases.
const themeAliases = await loadTheme(siteDir);
// Make a fake plugin to resolve user's theme overrides.
if (themeAliases != null) {
plugins.push({
configureWebpack: () => ({
resolve: {
alias: themeAliases,
},
}),
});
}
// Default theme components that are essential and must exist in a Docusaurus app
// These can be overriden in plugins/ through component swizzling.
// However, we alias it here first as a fallback.
const themeFallback = path.resolve(__dirname, '../client/theme-fallback');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we shift these 3 chunks into loadTheme and rename existing loadTheme to loadThemeInner or something? Since we're already doing a lot of splitting this file up into its separate stages, I think we should continue keeping this file clean by shifting the very specific stuff into its own file.

let themeAliases = await loadTheme(themeFallback);

// create theme alias from plugins
await Promise.all(
plugins.map(async plugin => {
if (!plugin.getThemePath) {
return;
}
const aliases = await loadTheme(plugin.getThemePath());
themeAliases = {
...themeAliases,
...aliases,
};
}),
);

// user's own theme alias override. Highest priority
const themePath = path.resolve(siteDir, 'theme');
const aliases = await loadTheme(themePath);
themeAliases = {
...themeAliases,
...aliases,
};

// Make a fake plugin to resolve alias theme.
plugins.push({
configureWebpack: () => ({
resolve: {
alias: themeAliases,
},
}),
});

// Routing
const {
Expand Down
3 changes: 1 addition & 2 deletions packages/docusaurus/lib/server/load/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ const fs = require('fs-extra');
const path = require('path');
const {fileToPath, posixPath, normalizeUrl} = require('@docusaurus/utils');

module.exports = async function loadTheme(siteDir) {
const themePath = path.resolve(siteDir, 'theme');
module.exports = async function loadTheme(themePath) {
if (!fs.existsSync(themePath)) {
return null;
}
Expand Down
6 changes: 0 additions & 6 deletions packages/docusaurus/lib/webpack/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ module.exports = function createBaseConfig(props, isServer) {
} = props;

const isProd = process.env.NODE_ENV === 'production';
const themeFallback = path.resolve(__dirname, '../client/theme-fallback');
return {
mode: isProd ? 'production' : 'development',
output: {
Expand All @@ -44,11 +43,6 @@ module.exports = function createBaseConfig(props, isServer) {
alias: {
// https://stackoverflow.com/a/55433680/6072730
ejs: 'ejs/ejs.min.js',
// These alias can be overriden in plugins. However, these components are essential
// (e.g: react-loadable requires Loading component) so we alias it here first as fallback.
'@theme/Layout': path.join(themeFallback, 'Layout'),
'@theme/Loading': path.join(themeFallback, 'Loading'),
'@theme/NotFound': path.join(themeFallback, 'NotFound'),
'@site': siteDir,
'@generated': generatedFilesDir,
'@docusaurus': path.resolve(__dirname, '../client/exports'),
Expand Down
2 changes: 1 addition & 1 deletion website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"start": "docusaurus start",
"build": "docusaurus build",
"eject": "docusaurus eject",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy"
},
"dependencies": {
Expand Down