load_plugins.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. 'use strict';
  2. const { join } = require('path');
  3. const { exists, readFile, listDir } = require('hexo-fs');
  4. const Promise = require('bluebird');
  5. const { magenta } = require('chalk');
  6. module.exports = ctx => {
  7. if (!ctx.env.init || ctx.env.safe) return;
  8. return loadModules(ctx).then(() => loadScripts(ctx));
  9. };
  10. function loadModuleList(ctx) {
  11. const packagePath = join(ctx.base_dir, 'package.json');
  12. // Make sure package.json exists
  13. return exists(packagePath).then(exist => {
  14. if (!exist) return [];
  15. // Read package.json and find dependencies
  16. return readFile(packagePath).then(content => {
  17. const json = JSON.parse(content);
  18. const deps = Object.keys(json.dependencies || {});
  19. const devDeps = Object.keys(json.devDependencies || {});
  20. return deps.concat(devDeps);
  21. });
  22. }).filter(name => {
  23. // Ignore plugins whose name is not started with "hexo-"
  24. if (!/^hexo-|^@[^/]+\/hexo-/.test(name)) return false;
  25. // Ignore plugin whose name is started with "hexo-theme"
  26. if (/^hexo-theme-|^@[^/]+\/hexo-theme-/.test(name)) return false;
  27. // Ignore typescript definition file that is started with "@types/"
  28. if (name.startsWith('@types/')) return false;
  29. // Make sure the plugin exists
  30. const path = ctx.resolvePlugin(name);
  31. return exists(path);
  32. });
  33. }
  34. function loadModules(ctx) {
  35. return loadModuleList(ctx).map(name => {
  36. const path = ctx.resolvePlugin(name);
  37. // Load plugins
  38. return ctx.loadPlugin(path).then(() => {
  39. ctx.log.debug('Plugin loaded: %s', magenta(name));
  40. }).catch(err => {
  41. ctx.log.error({err}, 'Plugin load failed: %s', magenta(name));
  42. });
  43. });
  44. }
  45. function loadScripts(ctx) {
  46. const baseDirLength = ctx.base_dir.length;
  47. function displayPath(path) {
  48. return magenta(path.substring(baseDirLength));
  49. }
  50. return Promise.filter([
  51. ctx.theme_script_dir,
  52. ctx.script_dir
  53. ], scriptDir => { // Ignore the directory if it does not exist
  54. return scriptDir ? exists(scriptDir) : false;
  55. }).map(scriptDir => listDir(scriptDir).map(name => {
  56. const path = join(scriptDir, name);
  57. return ctx.loadPlugin(path).then(() => {
  58. ctx.log.debug('Script loaded: %s', displayPath(path));
  59. }).catch(err => {
  60. ctx.log.error({err}, 'Script load failed: %s', displayPath(path));
  61. });
  62. }));
  63. }