Как закрыть компиляцию, но по-прежнему предоставлять интерфейс API для не скомпилированных «расширений» - PullRequest
0 голосов
/ 19 октября 2019

Я хотел бы скомпилировать 'sdk', который предоставляет API.

Как может скомпилированный файл предоставить "интерфейс", который могут использоваться некомпилированными расширениями для подключения к скомпилированному SDK?

Пример:

Клиенты API могут включать sdk с

<script src='nn-skd'> (nn is the name of the sdk)

Вот весь sdk

/**
 * @nocollapse
 * @const
 * @namespace
 */
var NN = {}

/**
 * @interface
 * @export
 */
NN.INode = function() {}
/**
 * @export
 * @return {number} 
 */
NN.INode.prototype.getMagic = function() {}

document.addEventListener("click",()=>{
  const node = /** @type NN.INode */ (window['specialNodeAddedByAPIClientOutsideOfTheSdk'])
  console.log(node.getMagic())
})

Я хотел бы, чтобы здесь был клиенткоторые могут помещать классы, которые "реализуют" INode в окно ['specialNodeAddedByAPIClientOutsideOfTheSdk'], и sdk может использовать этот класс.

Как, например, следующий не скомпилированный файл:

NN.Node = class {
  getMagic() {
    return 4;
  }
}
window['specialNodeAddedByAPIClientOutsideOfTheSdk'] = new NN.Node();

Но этоне будет работать, потому что скомпилированный файл nn-sdk Google Closure никогда не будет вызывать NN.Node # getMagic. Он просто не знает об этом. Скомпилированный файл выглядит как

(function() {
    var a = {},
        b = a.a,
        c = ["NN", "INode"],
        d = this;
    c[0] in d || !d.execScript || d.execScript("var " + c[0]);
    for (var e; c.length && (e = c.shift());) c.length || void 0 === b ? d[e] && d[e] !== Object.prototype[e] ? d = d[e] : d = d[e] = {} : d[e] = b;
    a.a.prototype.b = function() {};
    a.a.prototype.getMagic = a.a.prototype.b;
    document.addEventListener("click", function() {
        console.log(void 0)
    });
}).call(window)

, где console.log () просто «void 0».

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

Update1:

Нашли возможное решение

console.log(node['getMagic']() || node.getMagic())

Это гарантируетчто если узел искажен и находится внутри sdk, то будет вызван node.getMagic (), а если он находится вне sdk, то будет вызван узел 'getMagic'.

Это то, что я должен делать?

Обновление 2 и 3.

Приведенный выше подход работает, пока я не попытаюсь расширить и переопределить метод с помощью

NN.Node = class extends NN.INode {

и затем

getMagic() {
super.getMagic()
}

в этом случае невозможно разрешить правильный getMagic.

...