Browse Source

More rewording/reorganization of extension dev docs

Jason Grout 4 years ago
parent
commit
dc4b46589e
1 changed files with 62 additions and 54 deletions
  1. 62 54
      docs/source/extension/extension_dev.rst

+ 62 - 54
docs/source/extension/extension_dev.rst

@@ -44,7 +44,7 @@ Here is some autogenerated API documentation for JupyterLab and Lumino packages:
 Overview of Extensions
 ----------------------
 
-A JupyterLab extension is a package that contains JupyterLab plugins. A plugin is the basic unit of extensibility in JupyterLab. An extension is a package that contains one or more JupyterLab plugins. There are several types of extensions:
+A JupyterLab plugin is the basic unit of extensibility in JupyterLab. An extension is a package that contains one or more JupyterLab plugins. There are several types of extensions:
 
 - A *source extension* is a JavaScript (npm) package that exports one or more plugins. Installing a source extension requires a user to rebuild JupyterLab. This rebuilding step requires Node.js and may take a lot of time and memory, so some users may not be able to install a source extension. However, the total size of the JupyterLab code delivered to a user's browser may be reduced compared to using prebuilt extensions. See :ref:`deduplication` for the technical reasons for rebuilding JupyterLab when a source extension is installed.
 - A *prebuilt extension* (new in JupyterLab 3.0) distributes a bundle of JavaScript code prebuilt from a source extension that can be loaded into JupyterLab without rebuilding JupyterLab. In this case, the extension developer uses tools provided by JupyterLab to compile a source extension into a JavaScript bundle that includes the non-JupyterLab JavaScript dependencies, then distributes the resulting bundle in, for example, a Python pip or conda package. Installing a prebuilt extensions does not require Node.js.
@@ -61,17 +61,15 @@ Plugins
 
 A JupyterLab plugin is the basic unit of extensibility in JupyterLab. JupyterLab supports several types of plugins:
 
--  **Application plugins:** Application plugins are the fundamental building block of JupyterLab functionality. Application plugins interact with JupyterLab and other plugins by requiring services provided by other plugins, and optionally providing their own service to the system.
--  **Mime renderer plugins:** Mime renderer plugins are simplified, restricted ways to extend JupyterLab to render custom mime data in notebooks and files. These plugins are automatically converted to equivalent application plugins by JupyterLab when they are loaded.
--  **Theme plugins:** Theme plugins provide a way to customize the appearance of JupyterLab by changing themeable values (i.e., CSS variable values) and providing additional fonts and graphics to JupyterLab.
- 
+-  **Application plugins:** Application plugins are the fundamental building block of JupyterLab functionality. Application plugins interact with JupyterLab and other plugins by requiring services provided by other plugins, and optionally providing their own service to the system. Application plugins in core JupyterLab include the main menu system, the file browser, and the notebook, console, and file editor components.
+-  **Mime renderer plugins:** Mime renderer plugins are simplified, restricted ways to extend JupyterLab to render custom mime data in notebooks and files. These plugins are automatically converted to equivalent application plugins by JupyterLab when they are loaded. Examples of mime renderer plugins that come in core JupyterLab are the pdf viewer, the JSON viewer, and the Vega viewer.
+-  **Theme plugins:** Theme plugins provide a way to customize the appearance of JupyterLab by changing themeable values (i.e., CSS variable values) and providing additional fonts and graphics to JupyterLab. JupyterLab comes with light and dark theme plugins.
+
 
 Application Plugins
 ^^^^^^^^^^^^^^^^^^^
 
-An application plugin is a JavaScript object with a number of metadata fields. The ``id`` and ``activate`` fields are required and the other fields may be omitted. For more information about how to use the ``requires``, ``optional``, or ``provides`` fields, see :ref:`services`.
-
-A typical application plugin might look like this in TypeScript:
+An application plugin is a JavaScript object with a number of metadata fields. A typical application plugin might look like this in TypeScript:
 
 .. code-block:: typescript
 
@@ -84,6 +82,8 @@ A typical application plugin might look like this in TypeScript:
      activate: activateFunction
    };
 
+The ``id`` and ``activate`` fields are required and the other fields may be omitted. For more information about how to use the ``requires``, ``optional``, or ``provides`` fields, see :ref:`services`.
+
 - ``id`` is a required unique string. The convention is to use the NPM extension package name, a colon, then a string identifying the plugin inside the extension.
 - ``autostart`` indicates whether your plugin should be activated at application startup. Typically this should be ``true``. If it is ``false`` or omitted, your plugin will be activated when any other plugin requests the token your plugin is providing.
 - ``requires`` and ``optional`` are lists of :ref:`tokens <tokens>` corresponding to services other plugins provide. These services will be given as arguments to the ``activate`` function when the plugin is activated. If a ``requires`` service is not registered with JupyterLab, an error will be thrown and the plugin will not be activated.
@@ -95,7 +95,7 @@ A typical application plugin might look like this in TypeScript:
 Application Object
 """"""""""""""""""
 
-A Jupyter front-end application object is given to each plugin ``activate`` function as its first argument. The application object has a number of properties and methods for interacting with the application, including:
+A Jupyter front-end application object is given to a plugin's ``activate`` function as its first argument. The application object has a number of properties and methods for interacting with the application, including:
 
 -  ``commands`` - an extensible registry used to add and execute commands in the application.
 -  ``docRegistry`` - an extensible registry containing the document types that the application is able to read and render.
@@ -131,47 +131,31 @@ Publishing Tokens
 
 Since consumers will need to import a token used by a provider, the token should be exported in a published JavaScript package. Tokens will need to be deduplicated in JupyterLab—see :ref:`deduplication` for more details.
 
-A pattern in core JupyterLab is to create and export tokens from a self-contained ``tokens`` JavaScript module in a package. This enables consumers to import a token directly from the package's ``tokens`` module (e.g., ``import { MyToken } from 'provider/tokens';``), thus enabling a tree-shaking bundling optimization to possibly bundle only the tokens and not other code from the package.
 
-Another pattern in core JupyterLab is to create and export a token from a third package that both the provider and consumer extensions import, rather than defining the token in the provider's package. This enables a user to swap out the provider extension for a different extension that provides the same token with an alternative service implementation. For example, the core JupyterLab ``filebrowser`` package exports a token representing the file browser service (enabling interactions with the file browser). The ``filebrowser-extension`` package contains a plugin that implements the file browser in JupyterLab and provides the file browser service to JupyterLab (identified with the token imported from the ``filebrowser`` package). Extensions in JupyterLab that want to interact with the filebrowser thus do not need to have a JavaScript dependency on the ``filebrowser-extension`` package, but only need to import the token from the ``filebrowser`` package. This pattern enables users to seamlessly change the file browser in JupyterLab by writing their own extension that imports the same token from the ``filebrowser`` package and provides it to the system with their own alternative file browser service.
+A pattern in core JupyterLab is to create and export a token from a third package that both the provider and consumer extensions import, rather than defining the token in the provider's package. This enables a user to swap out the provider extension for a different extension that provides the same token with an alternative service implementation. For example, the core JupyterLab ``filebrowser`` package exports a token representing the file browser service (enabling interactions with the file browser). The ``filebrowser-extension`` package contains a plugin that implements the file browser in JupyterLab and provides the file browser service to JupyterLab (identified with the token imported from the ``filebrowser`` package). Extensions in JupyterLab that want to interact with the filebrowser thus do not need to have a JavaScript dependency on the ``filebrowser-extension`` package, but only need to import the token from the ``filebrowser`` package. This pattern enables users to seamlessly change the file browser in JupyterLab by writing their own extension that imports the same token from the ``filebrowser`` package and provides it to the system with their own alternative file browser service.
 
 
+.. 
+   We comment out the following, until we can import from a submodule of a package. See https://github.com/jupyterlab/jupyterlab/pull/9475.
 
-.. _rendermime:
+   A pattern in core JupyterLab is to create and export tokens from a self-contained ``tokens`` JavaScript module in a package. This enables consumers to import a token directly from the package's ``tokens`` module (e.g., ``import { MyToken } from 'provider/tokens';``), thus enabling a tree-shaking bundling optimization to possibly bundle only the tokens and not other code from the package.
 
-Mime Renderer Plugins
-^^^^^^^^^^^^^^^^^^^^^
 
-Mime Renderer plugins are a convenience for creating an plugin
-that can render mime data and potentially render files of a given type.
-We provide an extension cookiecutter for mime renderer plugins in TypeScript
-`here <https://github.com/jupyterlab/mimerender-cookiecutter-ts>`__.
 
-Mime renderer plugins are more declarative than standard plugins.
-The extension is treated the same from the command line perspective
-(``jupyter labextension install`` ), but it does not directly create
-JupyterLab plugins. Instead it exports an interface given in the
-`rendermime-interfaces <https://jupyterlab.github.io/jupyterlab/interfaces/_rendermime_interfaces_src_index_.irendermime.iextension.html>`__
-package.
+.. _rendermime:
 
-The JupyterLab repo has an example mime renderer extension for
-`pdf <https://github.com/jupyterlab/jupyterlab/tree/master/packages/pdf-extension>`__
-files. It provides a mime renderer for pdf data and registers itself as
-a document renderer for pdf file types.
+Mime Renderer Plugins
+^^^^^^^^^^^^^^^^^^^^^
 
-The JupyterLab organization also has a mime renderer extension tutorial
-which adds mp4 video rendering to the application
-`here <https://github.com/jupyterlab/jupyterlab-mp4>`__.
+Mime Renderer plugins are a convenience for creating a plugin
+that can render mime data in a notebook and files of the given mime type. Mime renderer plugins are more declarative and more restricted than standard plugins.
+A mime renderer plugin is an object with the fields listed in the 
+`rendermime-interfaces IExtension <https://jupyterlab.github.io/jupyterlab/interfaces/_rendermime_interfaces_src_index_.irendermime.iextension.html>`__
+object.
 
-The ``rendermime-interfaces`` package is intended to be the only
-JupyterLab package needed to create a mime renderer extension (using the
-interfaces in TypeScript or as a form of documentation if using plain
-JavaScript).
+JupyterLab has a `pdf mime renderer extension <https://github.com/jupyterlab/jupyterlab/tree/master/packages/pdf-extension>`__, for example. In core JupyterLab, this is used to view pdf files and view pdf data mime data in a notebook.
 
-The only other difference from a standard extension is that it has a
-``jupyterlab`` key in its ``package.json`` with ``"mimeExtension"``
-metadata. The value can be ``true`` to use the main module of the
-package, or a string path to a specific module (e.g. ``"lib/foo"``).
+We have a `mime renderer tutorial <https://github.com/jupyterlab/jupyterlab-mp4>`__  walking through creating a mime renderer extension which adds mp4 video rendering to JupyterLab. We also have a `cookiecutter for mime renderer extensions <https://github.com/jupyterlab/mimerender-cookiecutter-ts>`__  in TypeScript.
 
 The mime renderer can update its data by calling ``.setData()`` on the
 model it is given to render. This can be used for example to add a
@@ -181,19 +165,16 @@ notebook model and added to the notebook document. When using
 calling ``.setData()`` with updated data for the rendered MIME type. The
 document can then be saved by the user in the usual manner.
 
-
 Theme plugins
 ^^^^^^^^^^^^^
 
 A theme is an application plugin that requires the ``ThemeManager`` service and can
 be loaded and unloaded dynamically. The package must include all static
-assets that are referenced by ``url()`` in its CSS files. Local URLs can
+assets that are referenced by ``@import`` in its main CSS files. Local URLs can
 be used to reference files relative to the location of the referring sibling CSS files. For example ``url('images/foo.png')`` or
-``url('../foo/bar.css')``\ can be used to refer local files in the
+``url('../foo/bar.css')`` can be used to refer local files in the
 theme. Absolute URLs (starting with a ``/``) or external URLs (e.g.
-``https:``) can be used to refer to external assets. The path to the
-theme asset entry point is specified ``package.json`` under the ``"jupyterlab"``
-key as ``"themePath"``. See the `JupyterLab Light
+``https:``) can be used to refer to external assets. See the `JupyterLab Light
 Theme <https://github.com/jupyterlab/jupyterlab/tree/master/packages/theme-light-extension>`__
 for an example. Ensure that the theme files are included in the
 ``"files"`` metadata in ``package.json``.  Note that if you want to use SCSS, SASS, or LESS files,
@@ -205,14 +186,28 @@ See the `TypeScript theme cookiecutter <https://github.com/jupyterlab/theme-cook
 Source Extensions
 -----------------
 
-A source extension is a JavaScript (npm) package that exports one or more plugins. A source extension has metadata in the ``jupyterlab`` field of its ``package.json`` file. The JSON schema for the metadata is `distributed <https://github.com/jupyterlab/jupyterlab/blob/master/builder/metadata_schema.json>`__ in the ``@jupyterlab/builder`` package.
+A source extension is a JavaScript (npm) package that exports one or more plugins. All JupyterLab extensions are developed as source extensions (for example, prebuilt extensions are built from source extensions).
 
-We recommend including the keyword ``jupyterlab-extension`` in ``package.json`` to enable the extension manager to search for the extension in the npm repository::
+A source extension has metadata in the ``jupyterlab`` field of its ``package.json`` file. The `JSON schema <https://github.com/jupyterlab/jupyterlab/blob/master/builder/metadata_schema.json>`__ for the metadata is distributed in the ``@jupyterlab/builder`` package.
+
+If you would like publish your source extension to npm and want users to be able to install your source extension, we recommend including the npm keyword ``jupyterlab-extension`` in ``package.json``. This enables JupyterLab's extension manager to find your extension and display it for users in its graphical interface::
 
        "keywords": [
          "jupyterlab-extension"
        ],
 
+We will talk about each ``jupyterlab`` metadata field in ``package.json`` for source extensions below.
+
+* ``extension``: :ref:`main_entry_point`
+* ``mimeExtension``: :ref:`mimeExtension`
+* ``themePath``: :ref:`themePath`
+* ``schemaDir``: :ref:`schemaDir`
+* ``disabledExtensions``: :ref:`disabledExtensions`
+* ``sharedPackages``: :ref:`deduplication`
+* ``discovery``: :ref:`ext-author-companion-packages`
+
+.. _main_entry_point:
+
 Main entry point
 ^^^^^^^^^^^^^^^^
 
@@ -222,6 +217,24 @@ The ``jupyterlab.extension`` field signifies that this package is a JupyterLab e
           "extension": true
         }
 
+.. _mimeExtension:
+
+Mime Extension entry point
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``jupyterlab.mimeExtension`` field signifies that the package exports a mime renderer plugin. Like the ``jupyterlab.extension`` field, the value can be a boolean (indicating the mime renderer plugin or list of plugins is the default export from the ``main`` field), or a string, which is the relative path to the module exporting these values.
+
+.. _themePath:
+
+Theme path
+^^^^^^^^^^
+The path to the
+theme asset entry point is specified ``package.json`` under the ``"jupyterlab"``
+key as ``"themePath"``.
+
+
+.. _schemaDir:
+
 Plugin Settings
 ^^^^^^^^^^^^^^^
 
@@ -254,6 +267,8 @@ for another example of an extension that uses settings.
 
 A system administrator or user can override default values of extension settings with the :ref:`overrides.json <overridesjson>` file.
 
+.. _disabledExtensions:
+
 Disabling other extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -274,13 +289,11 @@ Deduplication in JupyterLab happens in two ways. For source extensions, JupyterL
 
 To ensure that a consumer gets the same token instance that the provider provided to the sytem, the consumer should list the package it imported the tokens from as unbundled package in its ``package.json`` ``jupyterlab.sharedPackages`` config—this will generate a JavaScript error if the package (and thus the token) is not present in the system at runtime. Optional token packages should be listed as singletons that are bundled (otherwise, if they are not present in the system, it will cause a js error when you try to import them).
 
-
 By default, an extension's dependencies will be shared and deduplicated with other extension's direct dependencies, and JupyterLab will bundle a copy of the dependency. The ``sharedPackages`` key enables you to control how dependencies are bundled with your extension when building JupyterLab (or when building your extension when creating a prebuilt extension). ``sharedPackages`` is an object where the keys are JavaScript package names and values are sharing configuration. Set the value to ``false`` to not share a dependency with other packages. Set the value to an object to control how it is shared. 
 
 Usually the only fields needed here are ``bundled: false`` to not bundle a dependency (but rely on another extension to bundle the dependency). Do this if you import a token from the dependency, 
 
 
-
 .. _ext-author-companion-packages:
 
 Companion packages
@@ -372,11 +385,6 @@ CSS Imports
 JupyterLab will prefer to put the styleModule key, then the style key, if they exist.
 
 
-Theme path
-^^^^^^^^^^
-
-
-
 Prebuilt Extensions
 -------------------