Skip to content

Commit

Permalink
feat: load hexo plugin in the theme's package.json (#4771)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenjoezhang committed Sep 23, 2021
1 parent a2ec6b2 commit 6f702fc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 36 deletions.
8 changes: 3 additions & 5 deletions lib/hexo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,14 @@ class Hexo extends EventEmitter {
return this.database.model(name, schema);
}

resolvePlugin(name) {
const baseDir = this.base_dir;

resolvePlugin(name, basedir) {
try {
// Try to resolve the plugin with the resolve.sync.
return sync(name, { basedir: baseDir });
return sync(name, { basedir });
} catch (err) {
// There was an error (likely the plugin wasn't found), so return a possibly
// non-existing path that a later part of the resolution process will check.
return join(baseDir, 'node_modules', name);
return join(basedir, 'node_modules', name);
}
}

Expand Down
30 changes: 17 additions & 13 deletions lib/hexo/load_plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ module.exports = ctx => {
return loadModules(ctx).then(() => loadScripts(ctx));
};

function loadModuleList(ctx) {
const packagePath = join(ctx.base_dir, 'package.json');
function loadModuleList(ctx, basedir) {
const packagePath = join(basedir, 'package.json');

// Make sure package.json exists
return exists(packagePath).then(exist => {
Expand All @@ -24,7 +24,7 @@ function loadModuleList(ctx) {
const deps = Object.keys(json.dependencies || {});
const devDeps = Object.keys(json.devDependencies || {});

return deps.concat(devDeps);
return basedir === ctx.base_dir ? deps.concat(devDeps) : deps;
});
}).filter(name => {
// Ignore plugins whose name is not started with "hexo-"
Expand All @@ -37,22 +37,26 @@ function loadModuleList(ctx) {
if (name.startsWith('@types/')) return false;

// Make sure the plugin exists
const path = ctx.resolvePlugin(name);
const path = ctx.resolvePlugin(name, basedir);
return exists(path);
}).then(modules => {
return Object.fromEntries(modules.map(name => [name, ctx.resolvePlugin(name, basedir)]));
});
}

function loadModules(ctx) {
return loadModuleList(ctx).map(name => {
const path = ctx.resolvePlugin(name);

// Load plugins
return ctx.loadPlugin(path).then(() => {
ctx.log.debug('Plugin loaded: %s', magenta(name));
}).catch(err => {
ctx.log.error({err}, 'Plugin load failed: %s', magenta(name));
return Promise.map([ctx.base_dir, ctx.theme_dir], basedir => loadModuleList(ctx, basedir))
.then(([hexoModuleList, themeModuleList]) => {
return Object.entries(Object.assign(themeModuleList, hexoModuleList));
})
.map(([name, path]) => {
// Load plugins
return ctx.loadPlugin(path).then(() => {
ctx.log.debug('Plugin loaded: %s', magenta(name));
}).catch(err => {
ctx.log.error({err}, 'Plugin load failed: %s', magenta(name));
});
});
});
}

function loadScripts(ctx) {
Expand Down
45 changes: 27 additions & 18 deletions test/scripts/hexo/load_plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,31 @@ describe('Load plugins', () => {
delete hexo._script_test;
}

function createPackageFile(...args) {
function createPackageFile(name, path) {
const pkg = {
name: 'hexo-site',
version: '0.0.0',
private: true,
dependencies: {}
dependencies: {
[name]: '*'
}
};

for (const arg of args) {
pkg.dependencies[arg] = '*';
}

return fs.writeFile(join(hexo.base_dir, 'package.json'), JSON.stringify(pkg, null, ' '));
path = path || join(hexo.base_dir, 'package.json');
return fs.writeFile(path, JSON.stringify(pkg, null, ' '));
}

function createPackageFileWithDevDeps(...args) {
function createPackageFileWithDevDeps(name) {
const pkg = {
name: 'hexo-site',
version: '0.0.0',
private: true,
dependencies: {},
devDependencies: {}
devDependencies: {
[name]: '*'
}
};

for (let i = 0, len = args.length; i < len; i++) {
pkg.devDependencies[args[i]] = '*';
}

return fs.writeFile(join(hexo.base_dir, 'package.json'), JSON.stringify(pkg, null, ' '));
}

Expand All @@ -67,6 +64,10 @@ describe('Load plugins', () => {

after(() => fs.rmdir(hexo.base_dir));

afterEach(async () => {
await createPackageFile('hexo-another-plugin');
});

it('load plugins', () => {
const name = 'hexo-plugin-test';
const path = join(hexo.plugin_dir, name, 'index.js');
Expand Down Expand Up @@ -106,9 +107,19 @@ describe('Load plugins', () => {
});
});

it('ignore plugin whose name is "hexo-theme-[hexo.config.theme]"', async () => {
hexo.config.theme = 'test_theme';
it('load plugins in the theme\'s package.json', async () => {
const name = 'hexo-plugin-test';
const path = join(hexo.plugin_dir, name, 'index.js');
return Promise.all([
createPackageFile(name, join(hexo.theme_dir, 'package.json')),
fs.writeFile(path, script)
]).then(() => loadPlugins(hexo)).then(() => {
validate(path);
return fs.unlink(path);
});
});

it('ignore plugin whose name is started with "hexo-theme-"', async () => {
const script = 'hexo._script_test = true';
const name = 'hexo-theme-test_theme';
const path = join(hexo.plugin_dir, name, 'index.js');
Expand All @@ -124,9 +135,7 @@ describe('Load plugins', () => {
return fs.unlink(path);
});

it('ignore plugin whose name endswith "hexo-theme-[hexo.config.theme]"', async () => {
hexo.config.theme = 'test_theme';

it('ignore scoped plugin whose name is started with "hexo-theme-"', async () => {
const script = 'hexo._script_test = true';
const name = '@hexojs/hexo-theme-test_theme';
const path = join(hexo.plugin_dir, name, 'index.js');
Expand Down

0 comments on commit 6f702fc

Please sign in to comment.