Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question regarding JupyterLab Widgets #2

Open
TK-21st opened this issue May 21, 2020 · 4 comments
Open

Question regarding JupyterLab Widgets #2

TK-21st opened this issue May 21, 2020 · 4 comments

Comments

@TK-21st
Copy link

TK-21st commented May 21, 2020

Thank you so much for this work! We've been looking for a quick way to develop/debug JLab extensions for quite some time now, and this seems to be of great help!

I have a question regarding JupyterLab widgets, particularly those that subclass @lumino/widgets. Simply put, if we use the

As a barebone example, I was trying to see if it'd be possible to dynamically load the tutorial widget/extension (https://github.com/jupyterlab/jupyterlab_apod).

So in this case, the index.js of the APOD Widget/Extension compiles into something like

define(["require", "exports", "@jupyterlab/application", "@jupyterlab/apputils", "@lumino/widgets"], function (require, exports, application_1, apputils_1, widgets_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    ;
    class APODWidget extends widgets_1.Widget {
    ...
    }

    function active(app, palette, restorer) {
    }

    /**
     * Initialization data for the jupyterlab_apod extension.
     */
    const extension = {
        id: 'my-apod-extension',
        autoStart: true,
        requires: [apputils_1.ICommandPalette, application_1.ILayoutRestorer],
        activate: activate
    };
    exports.default = extension;

And I tried to create a JS file which looks like

return function()
{
  return {
    id: 'dynext-test-extension',
    autoStart: true,
    requires: ["jupyter.extensions.jupyterWidgetRegistry"],
    activate: function(app, widgets) {
      require.config({
        // take the widget from `unpkg.com`
        baseUrl: "/Users/tingkailiu/Projects/FFBO/JLab2/dynext-test-extension/lib"
      });

      let widget = "index";
      // note that we are using require js here to load the AMD module
      // requirejs is automatically loaded with jupyterlab-dynext.
      // * (star) selects the latest version from unpkg, and then loads the `/dist/index.js` file
      // the final URL will be something like https://unpkg.com/bqplot@^0.5.2/dist/index.js
      require([widget], function(plugin) {
        widgets.registerWidget({
            name: widget,
            version: plugin.version,
            exports: plugin
        });
      });
    }
  };
}

But it seems like jupyter.extensions.jupyterWidgetRegistry is not found and it's because I'm not using jupyterlab-manager since I'm trying to load a lab widget instead of a ipywidget.

Could you suggest a way for dynamically loading and developing jupyterlab widget/extension?

@wolfv
Copy link
Member

wolfv commented May 22, 2020

thanks! yes, I believe we need to expose more JavaScript modules to the dynamically loaded extension. I can try to use your example to see if we can get something to work.

@TK-21st
Copy link
Author

TK-21st commented May 22, 2020

Hi wolfv! I managed to put something together here https://github.com/TK-21st/jupyterlab-apod-dynext. What I'm doing is instead of loading extension dynamically, I'm injecting the Widget Module dynamically to an extension that's bundled into JLab the usual way.

I think making both work together would be the ideal solution. For now, I think I spend more time debugging/developing the Widget than the Extension so it works for me.

@wolfv
Copy link
Member

wolfv commented May 24, 2020

awesome! Do you think we can combine these two solutions into one repo?

@TK-21st
Copy link
Author

TK-21st commented May 24, 2020

That'd be great!

Having said that, I'm actually not 100% clear how the workflow should look like combining the two.
There seem to be 3 packages involved in a common workflow

  1. dynext: this needs to be installed to JLab as a normal extension so that requirejs can be injected on start up
  2. custom-extension: this is the part that I'm unsure about. How should a user automate the process of developing and injecting custom extension into browser? Suppose I want to create a new extension, how do I tell JLab to use dynext to load this extension in browser? I guess you could use filebrower to open the index.ts file and do some magic there but I feel like this step could be more automated.
  3. custom-widget: this widget (JupyterLab Widget, not Ipywidget) can be dynamically loaded into the custom-extension with my current solution (require a locally served widget)

And it'd also be really nice to have an NPM script which automatically bundles the custom-extension/widget into JLab as per normal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants