listComponents(loader, manifestOptions, callback) {
    this.readCache(loader, manifestOptions)
      .catch((err) => {
        if (!loader.options.discover) {
          return Promise.reject(err);
        }
        return new Promise((resolve, reject) => {
          dynamicLoader.listComponents(loader, manifestOptions, (err2, modules) => {
            if (err2) {
              reject(err2);
              return;
            }
            resolve(modules);
          });
        })
          .then((modules) => {
            const manifestContents = {
              version: 1,
              modules,
            };
            return this
              .writeCache(loader, manifestOptions, manifestContents)
              .then(() => manifestContents);
          });
      })
      .then((manifestContents) => {
        registerModules(loader, manifestContents.modules, (err) => {
          if (err) {
            callback(err);
            return;
          }
          callback(null, manifestContents.modules);
        });
      })
      .catch((err) => {
        callback(err);
      });
  }
@param {import("../ComponentLoader").ComponentLoader} loader
@param {Object} manifestOptions
@param {Function} callback