Как я могу экспортировать из пакета Meteor в пространство имен приложений?

Я знаю как писать Метеорные пакеты, но я не могу показаться чтобы выяснить, как весь экспорт экспортируется в пространство имен приложений, как описано в этой презентации.

Этот конкретный пакет специфичен для приложения, которое я создаю, и оно экспортирует только один метод, который можно рассматривать как декоратор в приложении singleton. Я пробовал api.export('MyApp.myMethod'), но это дает ошибку native: Bad exported symbol: MyApp.myMethod.

Если я просто api.export('myMethod'), то в коде приложения мне нужно вызвать myMethod(), а не namespaced.

Есть ли у Meteor механизм, похожий на Node var http = require('http');? Или как пакеты могут экспортировать символы в заданное пространство имен?

Ответ 1

Метод api.export поддерживается только для переменных верхнего уровня. Он не работает для вложенных переменных, поскольку "оказалось, что использование глубокого экспорта было очень запутанным ", и что бы вы ожидали, что MyApp.myMethod появится как в глобальном пространстве имен, если вы также экспортировали MyApp.myOtherMethod?

Вы должны просто экспортировать MyPackage, а затем вызвать MyPackage.myMethod(). Общий подход - сделать что-то вроде

MyPackage = { 
    myMethod: someSecretMethodName,
    myOtherMethod: otherMethodName
}

А затем вызовите api.export("MyPackage"). Это означает, что экспортируемые имена переменных необязательно должны быть такими, какие вы им назвали. Это много используется в основных метеорных пакетах; вы также можете увидеть пример для MongoInternals в mongo_driver.js.

Ответ 2

Все свойства, которые вы регистрируете в пространстве имен приложений, становятся доступными для пакетов, которые зависят от (использования) вашего приложения-пакета. Поэтому, когда вы хотите зарегистрировать пространство имен пакетов в пространстве имен приложений, вы объявляете зависимость от пакета приложений в своем пакете и регистрируете все методы/объекты, которые хотите экспортировать в пространстве имен приложений. Пример:

file: packages/myapp/namespace.js

MyApp = {};

file: packages/myapp/package.js

Package.on_use(function (api, where) {
  api.add_files([
    "namespace.js"
  ], ['client', 'server']);
  api.export("MyApp", ['client', 'server']);
});

file: packages/myapp-module1/logic.js

packageSpecificMethod = function(){}
moduleOne = {};
//you can export an module-specific namespace by registering it in the app-namespace
MyApp.module1 = moduleOne;
//or you can (if you dont want package-namespaces) register you private methods in the app-namespace directly
MyApp.exportedMethod = packageSpecificMethod;

file: packages/myapp-module1/package.js

Package.on_use(function (api, where) {
  api.use([
    'myapp'
  ], ['client', 'server']);
  api.add_files([
    "logic.js"
  ], ['client', 'server']);
});

Ответ 3

В вашем пакете вы должны определить все методы и символы в пространстве имен, которое вы хотите, и затем экспортировать это пространство имен. Итак, если в вашем пакете у вас есть:

MyApp = {
   myMethod: ...
};

Затем вы экспортируете его с помощью api.export('MyApp').

К сожалению, нет способа, аналогичного описанному в Node, который вы упомянули, поскольку все пакеты загружаются по всему миру при запуске.