ipywidget 可以从 URL 而不是本地磁盘获取它的 JavaScript 吗?

Can an ipywidget source its JavaScript from a URL, rather than local disk?

我正在构建一个 ipywidget 以在私人存储库中与一些同事共享。我想让它从服务器获取源 JavaScript,而不是要求我的同事在本地构建 JS 包,我想知道这是否可能。

这是我的设置。我创建了一个目录 (test-extension) 并启用它以使用 Jupyter 进行开发:

jupyter nbextension install test-extension --sys-prefix --symlink
jupyter nbextension enable test-extension/main --sys-prefix

Custom Widget Tutorial 之后,我可以用一些 Python:

创建自定义小部件
from traitlets import Unicode, Bool, validate, TraitError
from ipywidgets import DOMWidget, register

@register
class Email(DOMWidget):
    _view_name = Unicode('EmailView').tag(sync=True)
    _view_module = Unicode('email_widget').tag(sync=True)
    _view_module_version = Unicode('0.1.0').tag(sync=True)

    value = Unicode('example@example.com', help="The email value.").tag(sync=True)

和一些 JavaScript,在 test-extension/main.js:

define('email_widget', ["@jupyter-widgets/base"], function(widgets) {
    var EmailView = widgets.DOMWidgetView.extend({

        // Render the view.
        render: function() {
            this.email_input = document.createElement('input');
            this.email_input.type = 'email';
            this.email_input.value = this.model.get('value');
            this.el.appendChild(this.email_input);
        },
    });

    return {
        EmailView: EmailView
    };
});

在我的真实应用中,这个main.js文件是由webpack生成的,大小为10-20MB。我宁愿不要求我的同事在有任何变化时重建小部件 JS。但是因为它太大了,我不想把它提交给 GitHub。这是一个私人仓库,所以我不想在 PyPI 上发布它。一种想法是将 JS 托管在内部服务器上,并让小部件从那里获取它。

ipywidgets 可以吗?小部件可以从 URL 而不是从本地磁盘获取其 _view_module 的 JS 吗? ipywidgets 使用 RequireJS 作为模块加载器,因此涉及它的解决方案也可以。还是有我忽略的更好的解决方案?

我不是ipywidgets专家,但我对JS很有经验。请允许我做一个有根据的猜测。

我的理论是python widget 的一部分只是和js 部分松耦合,或者更准确地说,依赖解析是惰性的。因此,即使您异步加载代码的 js 部分,它也不会破坏任何东西。

所以我提出的解决方案非常简单,只需两个步骤:

  1. 把你笨重的 main.js 放在远程服务器上,假设 URL 是 http://my-server.com/test-extension/main.js
  2. 你仍然需要在你的 repo 中保留一个 main.js,但它只是一个从远程服务器获取真实 main.js 的小型加载器。这是加载程序代码:
var url = "http://my-server.com/test-extension/main.js";
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;

其他一切都保持不变。请尝试一下,看看我的理论是否正确。很想知道结果!