kodie
8/10/2016 - 4:50 PM

There are a variety of ways to do that; I'd recommend using "classes" (prototypal inheritance) as I think it enhances readability. This samp

There are a variety of ways to do that; I'd recommend using "classes" (prototypal inheritance) as I think it enhances readability. This sample assumes you are using a version of Meteor new enough to use the ecmascript package (you can do it without ecmascript, it's just not as readable). I'm going to write the example for Meteor 1.3+.

/**
 * First, add `api.use('ecmascript');` to your package.js files.
 * packages/project:modules-core/package.js:
 **/
Package.describe({
  name: 'project:modules-core',
  summary: 'Core package for Modules.',
  version: '1.0.0'
});

Package.onUse(function (api) {
  api.versionsFrom('METEOR@0.9.1.1');

  api.use('ecmascript');

  api.mainModule('lib/core.js');
});

/**
 * packages/project:facebook/package.js:
 **/
Package.describe({
  name: 'project:facebook',
  summary: 'Facebook Module.',
  version: '1.0.0'
});

Package.onUse(function (api) {
  api.versionsFrom('METEOR@0.9.1.1');

  api.use('project:modules-core', ['client', 'server']);

  api.imply('project:modules-core', ['client', 'server']);

  api.addFiles('lib/facebook.js', ['client', 'server']);
});

/**
 * Next, convert HBModule to a class.
 * packages/project:modules-core/lib/core.js:
 **/
export class HBModule {
  constructor(moduleName = '', registrationName = '') {
    this.moduleName = moduleName;
    register('registrationName');
  }

  getShareCount(url) {
    return -1;
  }
}

function register(name) {
  HBModule[name] = name;
}

/**
 * Then import the HBModule and use it as the base for the Facebook class.
 * packages/project:facebook/lib/facebook.js:
 **/
import { HBModule, register } from 'meteor/project:modules-core';
class Facebook extends HBModule {
  constructor() {
    /**
     * set this.moduleName to 'Facebook'
     * and register with the name 'facebook', as per your original code
     **/
    super('Facebook', 'facebook');
  }

  getShareCount(url) {
    return 22;
  }
}

/**
 * Here's a class without getShareCount, so it will use HBModule#getShareCount:
 **/
import { HBModule, register } from 'meteor/project:modules-core';
class SomeOtherClass extends HBModule {
  constructor() {
    // set this.moduleName to 'Facebook'
    super('SomeOtherClass', 'someOtherClass');
  }
}
// console.log(new SomeOtherClass().getShareCount()) will output -1 since it calls HBModule#getShareCount

/**
 * And here's a class that implements getShareCount but also calls HBModule#getShareCount:
 **/
import { HBModule, register } from 'meteor/project:modules-core';
class SomeOtherClass2 extends HBModule {
  constructor() {
    // set this.moduleName to 'Facebook'
    super('SomeOtherClass2', 'someOtherClass2');
  }

  getShareCount(url) {
    const hbModuleShareCount = super.getShareCount(url);
    return hbModuleShareCount + 22;
  }
}
// console.log(new SomeOtherClass2().getShareCount()) will output 21