|
@@ -1,19 +1,633 @@
|
|
|
Contributing to JupyterLab
|
|
|
--------------------------
|
|
|
|
|
|
-This page provides general information about contributing to the project.
|
|
|
+If you're reading this section, you're probably interested in
|
|
|
+contributing to JupyterLab. Welcome and thanks for your interest in
|
|
|
+contributing!
|
|
|
+
|
|
|
+Please take a look at the Contributor documentation, familiarize
|
|
|
+yourself with using JupyterLab, and introduce yourself to the community
|
|
|
+(on the mailing list or discourse) and share what area of the project
|
|
|
+you are interested in working on. Please also see the Jupyter `Community
|
|
|
+Guides <https://jupyter.readthedocs.io/en/latest/community/content-community.html>`__.
|
|
|
+
|
|
|
+We have labeled some issues as `good first
|
|
|
+issue <https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`__
|
|
|
+or `help
|
|
|
+wanted <https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22>`__
|
|
|
+that we believe are good examples of small, self-contained changes. We
|
|
|
+encourage those that are new to the code base to implement and/or ask
|
|
|
+questions about these issues.
|
|
|
+
|
|
|
+If you believe you’ve found a security vulnerability in JupyterLab or
|
|
|
+any Jupyter project, please report it to security@ipython.org. If you
|
|
|
+prefer to encrypt your security reports, you can use `this PGP public
|
|
|
+key <https://raw.githubusercontent.com/jupyter/notebook/master/docs/source/ipython_security.asc>`__.
|
|
|
|
|
|
.. contents:: Table of contents
|
|
|
:local:
|
|
|
:depth: 1
|
|
|
|
|
|
+General Guidlelines for Contributing
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+For general documentation about contributing to Jupyter projects, see
|
|
|
+the `Project Jupyter Contributor
|
|
|
+Documentation <https://jupyter.readthedocs.io/en/latest/contributor/content-contributor.html>`__
|
|
|
+and `Code of
|
|
|
+Conduct <https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md>`__.
|
|
|
+
|
|
|
+All source code is written in
|
|
|
+`TypeScript <http://www.typescriptlang.org/Handbook>`__. See the `Style
|
|
|
+Guide <https://github.com/jupyterlab/jupyterlab/wiki/TypeScript-Style-Guide>`__.
|
|
|
+
|
|
|
+All source code is formatted using `prettier <https://prettier.io>`__.
|
|
|
+When code is modified and committed, all staged files will be
|
|
|
+automatically formatted using pre-commit git hooks (with help from the
|
|
|
+`lint-staged <https://github.com/okonet/lint-staged>`__ and
|
|
|
+`husky <https://github.com/typicode/husky>`__ libraries). The benefit of
|
|
|
+using a code formatter like prettier is that it removes the topic of
|
|
|
+code style from the conversation when reviewing pull requests, thereby
|
|
|
+speeding up the review process.
|
|
|
+
|
|
|
+You may also use the prettier npm script (e.g. ``npm run prettier`` or
|
|
|
+``yarn prettier`` or ``jlpm prettier``) to format the entire code base.
|
|
|
+We recommend installing a prettier extension for your code editor and
|
|
|
+configuring it to format your code with a keyboard shortcut or
|
|
|
+automatically on save.
|
|
|
+
|
|
|
+Submitting a Pull Request Contribution
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+Generally, an issue should be opened describing a piece of proposed work
|
|
|
+and the issues it solves before a pull request is opened.
|
|
|
+
|
|
|
+Issue Management
|
|
|
+''''''''''''''''
|
|
|
+
|
|
|
+Opening an issue lets community members participate in the design
|
|
|
+discussion, makes others aware of work being done, and sets the stage
|
|
|
+for a fruitful community interaction. A pull request should reference
|
|
|
+the issue it is addressing. Once the pull request is merged, the issue
|
|
|
+related to it will also be closed. If there is additional discussion
|
|
|
+around implemementation the issue may be re-opened. Once 30 days have
|
|
|
+passed with no additional discussion, the `lock
|
|
|
+bot <https://github.com/apps/lock>`__ will lock the issue. If additional
|
|
|
+discussion is desired, or if the pull request doesn't fully address the
|
|
|
+locked issue, please open a new issue referencing the locked issue.
|
|
|
+
|
|
|
+Tag Issues with Labels
|
|
|
+''''''''''''''''''''''
|
|
|
+
|
|
|
+Users without the commit rights to the JupyterLab repository can tag
|
|
|
+issues with labels using the ``@meeseeksdev`` bot. For example: To apply
|
|
|
+the label ``foo`` and ``bar baz`` to an issue, comment
|
|
|
+``@meeseeksdev tag foo "bar baz"`` on the issue.
|
|
|
+
|
|
|
+Setting Up a Development Environment
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+You can launch a binder with the latest JupyterLab master to test
|
|
|
+something (this may take a few minutes to load):
|
|
|
+
|
|
|
+.. image:: https://mybinder.org/badge_logo.svg
|
|
|
+ :target: https://mybinder.org/v2/gh/jupyterlab/jupyterlab/master?urlpath=lab-dev/
|
|
|
+
|
|
|
+Installing Node.js and jlpm
|
|
|
+'''''''''''''''''''''''''''
|
|
|
+
|
|
|
+Building JupyterLab from its GitHub source code requires Node.js. The
|
|
|
+development version requires Node.js version 10+, as defined in the
|
|
|
+``engines`` specification in
|
|
|
+`dev_mode/package.json <https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/package.json>`__.
|
|
|
+
|
|
|
+If you use ``conda``, you can get it with:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ conda install -c conda-forge 'nodejs'
|
|
|
+
|
|
|
+If you use `Homebrew <http://brew.sh>`__ on Mac OS X:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ brew install node
|
|
|
+
|
|
|
+You can also use the installer from the `Node.js <https://nodejs.org>`__
|
|
|
+website.
|
|
|
+
|
|
|
+To check which version of Node.js is installed:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ node -v
|
|
|
+
|
|
|
+Installing JupyterLab
|
|
|
+~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+JupyterLab requires Jupyter Notebook version 4.3 or later.
|
|
|
+
|
|
|
+If you use ``conda``, you can install notebook using:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ conda install -c conda-forge notebook
|
|
|
+
|
|
|
+You may also want to install ``nb_conda_kernels`` to have a kernel
|
|
|
+option for different `conda
|
|
|
+environments <https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html>`__
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ conda install -c conda-forge nb_conda_kernels
|
|
|
+
|
|
|
+If you use ``pip``, you can install notebook using:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ pip install notebook
|
|
|
+
|
|
|
+Fork the JupyterLab
|
|
|
+`repository <https://github.com/jupyterlab/jupyterlab>`__.
|
|
|
+
|
|
|
+Once you have installed the dependencies mentioned above, use the
|
|
|
+following steps:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ git clone https://github.com/<your-github-username>/jupyterlab.git
|
|
|
+ cd jupyterlab
|
|
|
+ pip install -e .
|
|
|
+ jlpm install
|
|
|
+ jlpm run build # Build the dev mode assets (optional)
|
|
|
+ jlpm run build:core # Build the core mode assets (optional)
|
|
|
+ jupyter lab build # Build the app dir assets (optional)
|
|
|
+
|
|
|
+Notes:
|
|
|
+
|
|
|
+- A few of the scripts will run "python". If your target python is
|
|
|
+ called something else (such as "python3") then parts of the build
|
|
|
+ will fail. You may wish to build in a conda environment, or make an
|
|
|
+ alias.
|
|
|
+- Some of the packages used in the development environment require
|
|
|
+ Python 3.0 or higher. If you encounter an ImportError during the
|
|
|
+ installation, make sure Python 3.0+ is installed. Also, try using the
|
|
|
+ Python 3.0+ version of ``pip`` or ``pip3 install -e .`` command to
|
|
|
+ install JupyterLab from the forked repository.
|
|
|
+- The ``jlpm`` command is a JupyterLab-provided, locked version of the
|
|
|
+ `yarn <https://yarnpkg.com/en>`__ package manager. If you have
|
|
|
+ ``yarn`` installed already, you can use the ``yarn`` command when
|
|
|
+ developing, and it will use the local version of ``yarn`` in
|
|
|
+ ``jupyterlab/yarn.js`` when run in the repository or a built
|
|
|
+ application directory.
|
|
|
+- If you decide to use the ``jlpm`` command and encounter the
|
|
|
+ ``jlpm: command not found`` error, try adding the user-level bin
|
|
|
+ directory to your ``PATH`` environment variable. You already
|
|
|
+ installed ``jlpm`` along with JupyterLab in the previous command, but
|
|
|
+ ``jlpm`` might not be accessible due to ``PATH`` environment variable
|
|
|
+ related issues. If you are using a Unix derivative (FreeBSD, GNU /
|
|
|
+ Linux, OS X), you can achieve this by using
|
|
|
+ ``export PATH="$HOME/.local/bin:$PATH"`` command.
|
|
|
+- At times, it may be necessary to clean your local repo with the
|
|
|
+ command ``npm run clean:slate``. This will clean the repository, and
|
|
|
+ re-install and rebuild.
|
|
|
+- If ``pip`` gives a ``VersionConflict`` error, it usually means that
|
|
|
+ the installed version of ``jupyterlab_server`` is out of date. Run
|
|
|
+ ``pip install --upgrade jupyterlab_server`` to get the latest
|
|
|
+ version.
|
|
|
+- To install JupyterLab in isolation for a single conda/virtual
|
|
|
+ environment, you can add the ``--sys-prefix`` flag to the extension
|
|
|
+ activation above; this will tie the installation to the
|
|
|
+ ``sys.prefix`` location of your environment, without writing anything
|
|
|
+ in your user-wide settings area (which are visible to all your envs):
|
|
|
+- You can run ``jlpm run build:dev:prod`` to build more accurate
|
|
|
+ sourcemaps that show the original Typescript code when debugging.
|
|
|
+ However, it takes a bit longer to build the sources, so is used only
|
|
|
+ to build for production by default.
|
|
|
+
|
|
|
+If you are using a version of Jupyter Notebook earlier than 5.3, then
|
|
|
+you must also run the following command to enable the JupyterLab server
|
|
|
+extension:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jupyter serverextension enable --py --sys-prefix jupyterlab
|
|
|
+
|
|
|
+For installation instructions to write documentation, please see
|
|
|
+`Writing Documentation <#writing-documentation>`__
|
|
|
+
|
|
|
+Run JupyterLab
|
|
|
+''''''''''''''
|
|
|
+
|
|
|
+Start JupyterLab in development mode:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jupyter lab --dev-mode
|
|
|
+
|
|
|
+Development mode ensures that you are running the JavaScript assets that
|
|
|
+are built in the dev-installed Python package. Note that when running in
|
|
|
+dev mode, extensions will not be activated by default.
|
|
|
+
|
|
|
+When running in dev mode, a red stripe will appear at the top of the
|
|
|
+page; this is to indicate running an unreleased version.
|
|
|
+
|
|
|
+Build and Run the Tests
|
|
|
+'''''''''''''''''''''''
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run build:test
|
|
|
+ jlpm test
|
|
|
+
|
|
|
+You can run tests for an individual package by changing to the
|
|
|
+appropriate package folder:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ cd packages/notebook
|
|
|
+ jlpm run build:test
|
|
|
+ jlpm test
|
|
|
+
|
|
|
+We use ``jest`` for all tests, so standard ``jest`` workflows apply.
|
|
|
+Tests can be debugged in either VSCode or Chrome. It can help to add an
|
|
|
+``it.only`` to a specific test when debugging. All of the ``test*``
|
|
|
+scripts in each package accept ``jest`` `cli
|
|
|
+options <https://jestjs.io/docs/en/cli.html>`__.
|
|
|
+
|
|
|
+VSCode Debugging
|
|
|
+^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+To debug in VSCode, open a package folder in VSCode. We provide a launch
|
|
|
+configuration in each package folder. In a terminal, run
|
|
|
+``jlpm test:debug:watch``. In VSCode, select "Attach to Jest" from the
|
|
|
+"Run" sidebar to begin debugging. See `VSCode docs on
|
|
|
+debugging <https://code.visualstudio.com/docs/editor/debugging>`__ for
|
|
|
+more details.
|
|
|
+
|
|
|
+Chrome Debugging
|
|
|
+^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+To debug in Chrome, run ``jlpm test:debug:watch`` in the terminal. Open
|
|
|
+Chrome and go to ``chrome://inspect/``. Select the remote device and
|
|
|
+begin debugging.
|
|
|
+
|
|
|
+Testing Utilities
|
|
|
+^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+There are some helper functions in ``testutils`` (which is a public npm
|
|
|
+package called ``@jupyterlab/testutils``) that are used by many of the
|
|
|
+tests.
|
|
|
+
|
|
|
+For tests that rely on ``@jupyterlab/services`` (starting kernels,
|
|
|
+interacting with files, etc.), there are two options. If a simple
|
|
|
+interaction is needed, the ``Mock`` namespace exposed by ``testutils``
|
|
|
+has a number of mock implmentations (see ``testutils/src/mock.ts``). If
|
|
|
+a full server interaction is required, use the ``JupyterServer`` class.
|
|
|
+
|
|
|
+We have a helper function called ``testEmission`` to help with writing
|
|
|
+tests that use ``Lumino`` signals, as well as a ``framePromise``
|
|
|
+function to get a ``Promise`` for a ``requestAnimationFrame``. We
|
|
|
+sometimes have to set a sentinel value inside a ``Promise`` and then
|
|
|
+check that the sentinel was set if we need a promise to run without
|
|
|
+blocking.
|
|
|
+
|
|
|
+Performance Testing
|
|
|
+~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+If you are making a change that might affect how long it takes to load
|
|
|
+JupyterLab in the browser, we recommend doing some performance testing
|
|
|
+using `Lighthouse <https://github.com/GoogleChrome/lighthouse>`__. It
|
|
|
+let's you easily compute a number of metrics, like page load time, for
|
|
|
+the site.
|
|
|
+
|
|
|
+To use it, first build JupyterLab in dev mode:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run build:dev
|
|
|
+
|
|
|
+Then, start JupyterLab using the dev build:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jupyter lab --dev --NotebookApp.token='' --no-browser
|
|
|
+
|
|
|
+Now run Lighthouse against this local server and show the results:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run lighthouse --view
|
|
|
+
|
|
|
+.. image:: /images/lighthouse.png
|
|
|
+
|
|
|
+Using throttling
|
|
|
+''''''''''''''''
|
|
|
+
|
|
|
+Lighthouse recommends using the system level
|
|
|
+`comcast <https://github.com/tylertreat/comcast>`__ tool to throttle
|
|
|
+your network connection and emulate different scenarios. To use it,
|
|
|
+first install that tool using ``go``:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ go get github.com/tylertreat/comcast
|
|
|
+
|
|
|
+Then, before you run Lighthouse, enable the throttling (this requires
|
|
|
+sudo):
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ run lighthouse:throttling:start
|
|
|
+
|
|
|
+This enables the "WIFI (good)" preset of comcast, which should emulate
|
|
|
+loading JupyterLab over a local network.
|
|
|
+
|
|
|
+Then run the lighthouse tests:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run lighthouse [...]
|
|
|
+
|
|
|
+Then disable the throttling after you are done:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run lighthouse:throttling:stop
|
|
|
+
|
|
|
+Comparing results
|
|
|
+'''''''''''''''''
|
|
|
+
|
|
|
+Performance results are usually only useful in comparison to other
|
|
|
+results. For that reason, we have included a comparison script that can
|
|
|
+take two lighthouse results and show the changes between them.
|
|
|
+
|
|
|
+Let's say we want to compare the results of the production build of
|
|
|
+JupyterLab with the normal build. The production build minifies all the
|
|
|
+JavaScript, so should load a bit faster.
|
|
|
+
|
|
|
+First, we build JupyterLab normally, start it up, profile it and save
|
|
|
+the results:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm build:dev
|
|
|
+ jupyter lab --dev --NotebookApp.token='' --no-browser
|
|
|
+
|
|
|
+ # in new window
|
|
|
+ jlpm run lighthouse --output json --output-path normal.json
|
|
|
+
|
|
|
+Then rebuild with the production build and retest:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run build:dev:prod
|
|
|
+ jupyter lab --dev --NotebookApp.token='' --no-browser
|
|
|
+
|
|
|
+ # in new window
|
|
|
+ jlpm run lighthouse --output json --output-path prod.json
|
|
|
+
|
|
|
+Now we can use compare the two outputs:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run lighthouse:compare normal.json prod.json
|
|
|
+
|
|
|
+This gives us a report of the relative differences between the audits in
|
|
|
+the two reports:
|
|
|
+
|
|
|
+.. admonition:: Resulting Output
|
|
|
+
|
|
|
+ ``normal.json`` -> ``prod.json``
|
|
|
+
|
|
|
+ | **First Contentful Paint**
|
|
|
+ | - -62% Δ
|
|
|
+ | - 1.9 s -> 0.7 s
|
|
|
+ | - First Contentful Paint marks the time at which the first text or
|
|
|
+ image is painted. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint>`__.
|
|
|
+
|
|
|
+ | **First Meaningful Paint**
|
|
|
+ | - -50% Δ
|
|
|
+ | - 2.5 s -> 1.3 s
|
|
|
+ | - First Meaningful Paint measures when the primary content of a
|
|
|
+ page is visible. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint>`__.
|
|
|
+
|
|
|
+ | **Speed Index**
|
|
|
+ | - -48% Δ
|
|
|
+ | - 2.6 s -> 1.3 s
|
|
|
+ | - Speed Index shows how quickly the contents of a page are visibly
|
|
|
+ populated. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/speed-index>`__.
|
|
|
+
|
|
|
+ | **Estimated Input Latency**
|
|
|
+ | - 0% Δ
|
|
|
+ | - 20 ms -> 20 ms
|
|
|
+ | - Estimated Input Latency is an estimate of how long your app takes
|
|
|
+ to respond to user input, in milliseconds, during the busiest 5s
|
|
|
+ window of page load. If your latency is higher than 50 ms, users
|
|
|
+ may perceive your app as laggy. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency>`__.
|
|
|
+
|
|
|
+ | **Max Potential First Input Delay**
|
|
|
+ | - 9% Δ
|
|
|
+ | - 200 ms -> 210 ms
|
|
|
+ | - The maximum potential First Input Delay that your users could
|
|
|
+ experience is the duration, in milliseconds, of the longest task.
|
|
|
+ `Learn
|
|
|
+ more <https://developers.google.com/web/updates/2018/05/first-input-delay>`__.
|
|
|
+
|
|
|
+ | **First CPU Idle**
|
|
|
+ | - -50% Δ
|
|
|
+ | - 2.5 s -> 1.3 s
|
|
|
+ | - First CPU Idle marks the first time at which the page's main
|
|
|
+ thread is quiet enough to handle input. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/first-interactive>`__.
|
|
|
+
|
|
|
+ | **Time to Interactive**
|
|
|
+ | - -52% Δ
|
|
|
+ | - 2.5 s -> 1.2 s
|
|
|
+ | - Time to interactive is the amount of time it takes for the page
|
|
|
+ to become fully interactive. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive>`__.
|
|
|
+
|
|
|
+ | **Avoid multiple page redirects**
|
|
|
+ | - -2% Δ
|
|
|
+ | - Potential savings of 10 ms -> Potential savings of 10 ms
|
|
|
+ | - Redirects introduce additional delays before the page can be
|
|
|
+ loaded. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/redirects>`__.
|
|
|
+
|
|
|
+ | **Minimize main-thread work**
|
|
|
+ | - -54% Δ
|
|
|
+ | - 2.1 s -> 1.0 s
|
|
|
+ | - Consider reducing the time spent parsing, compiling and executing
|
|
|
+ JS. You may find delivering smaller JS payloads helps with this.
|
|
|
+
|
|
|
+ | **JavaScript execution time**
|
|
|
+ | - -49% Δ
|
|
|
+ | - 1.1 s -> 0.6 s
|
|
|
+ | - Consider reducing the time spent parsing, compiling, and
|
|
|
+ executing JS. You may find delivering smaller JS payloads helps
|
|
|
+ with this. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/bootup>`__.
|
|
|
+
|
|
|
+ | **Preload key requests**
|
|
|
+ | - -100% Δ
|
|
|
+ | - Potential savings of 240 ms ->
|
|
|
+ | - Consider using <link rel=preload> to prioritize fetching
|
|
|
+ resources that are currently requested later in page load. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/preload>`__.
|
|
|
+
|
|
|
+ | **Uses efficient cache policy on static assets**
|
|
|
+ | - 0% Δ
|
|
|
+ | - 1 resource found -> 1 resource found
|
|
|
+ | - A long cache lifetime can speed up repeat visits to your page.
|
|
|
+ `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/cache-policy>`__.
|
|
|
+
|
|
|
+ | **Avoid enormous network payloads**
|
|
|
+ | - -86% Δ
|
|
|
+ | - Total size was 30,131 KB -> Total size was 4,294 KB
|
|
|
+ | - Large network payloads cost users real money and are highly
|
|
|
+ correlated with long load times. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/network-payloads>`__.
|
|
|
+
|
|
|
+ | **Minify JavaScript**
|
|
|
+ | - -100% Δ
|
|
|
+ | - Potential savings of 23,041 KB ->
|
|
|
+ | - Minifying JavaScript files can reduce payload sizes and script
|
|
|
+ parse time. `Learn
|
|
|
+ more <https://developers.google.com/speed/docs/insights/MinifyResources>`__.
|
|
|
+
|
|
|
+ | **Enable text compression**
|
|
|
+ | - -86% Δ
|
|
|
+ | - Potential savings of 23,088 KB -> Potential savings of 3,112 KB
|
|
|
+ | - Text-based resources should be served with compression (gzip,
|
|
|
+ deflate or brotli) to minimize total network bytes. `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/text-compression>`__.
|
|
|
+
|
|
|
+ | **Avoid an excessive DOM size**
|
|
|
+ | - 0% Δ
|
|
|
+ | - 1,268 elements -> 1,268 elements
|
|
|
+ | - Browser engineers recommend pages contain fewer than ~1,500 DOM
|
|
|
+ elements. The sweet spot is a tree depth < 32 elements and fewer
|
|
|
+ than 60 children/parent element. A large DOM can increase memory
|
|
|
+ usage, cause longer `style
|
|
|
+ calculations <https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations>`__,
|
|
|
+ and produce costly `layout
|
|
|
+ reflows <https://developers.google.com/speed/articles/reflow>`__.
|
|
|
+ `Learn
|
|
|
+ more <https://developers.google.com/web/tools/lighthouse/audits/dom-size>`__.
|
|
|
+
|
|
|
+Build and run the stand-alone examples
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+To install and build the examples in the ``examples`` directory:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run build:examples
|
|
|
+
|
|
|
+To run a specific example, change to the examples directory (i.e.
|
|
|
+``examples/filebrowser``) and enter:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ python main.py
|
|
|
+
|
|
|
+Debugging in the Browser
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+All methods of building JupyterLab produce source maps. The source maps
|
|
|
+should be available in the source files view of your browser's
|
|
|
+development tools under the ``webpack://`` header.
|
|
|
+
|
|
|
+When running JupyterLab normally, expand the ``~`` header to see the
|
|
|
+source maps for individual packages.
|
|
|
+
|
|
|
+When running in ``--dev-mode``, the core packages are available under
|
|
|
+``packages/``, while the third party libraries are available under
|
|
|
+``~``. Note: it is recommended to use ``jupyter lab --watch --dev-mode``
|
|
|
+while debugging.
|
|
|
+
|
|
|
+When running a test, the packages will be available at the top level
|
|
|
+(e.g. ``application/src``), and the current set of test files available
|
|
|
+under ``/src``. Note: it is recommended to use ``jlpm run watch`` in the
|
|
|
+test folder while debugging test options. See
|
|
|
+`above <#build-and-run-the-tests>`__ for more info.
|
|
|
+
|
|
|
+--------------
|
|
|
+
|
|
|
+High level Architecture
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+The JupyterLab application is made up of two major parts:
|
|
|
+
|
|
|
+- an npm package
|
|
|
+- a Jupyter server extension (Python package)
|
|
|
+
|
|
|
+Each part is named ``jupyterlab``. The :ref:`developer tutorial
|
|
|
+documentation <developer-guide>`
|
|
|
+provides additional architecture information.
|
|
|
+
|
|
|
+The NPM Packages
|
|
|
+~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+The repository consists of many npm packages that are managed using the
|
|
|
+lerna build tool. The npm package source files are in the ``packages/``
|
|
|
+subdirectory.
|
|
|
+
|
|
|
+Build the NPM Packages from Source
|
|
|
+''''''''''''''''''''''''''''''''''
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ git clone https://github.com/jupyterlab/jupyterlab.git
|
|
|
+ cd jupyterlab
|
|
|
+ pip install -e .
|
|
|
+ jlpm
|
|
|
+ jlpm run build:packages
|
|
|
+
|
|
|
+**Rebuild**
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run clean
|
|
|
+ jlpm run build:packages
|
|
|
+
|
|
|
Writing Documentation
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
-This section provides information about writing documentation for JupyterLab.
|
|
|
-See our `Contributor
|
|
|
-Guide <https://github.com/jupyterlab/jupyterlab/blob/master/CONTRIBUTING.md>`_ for
|
|
|
-details on installation and testing.
|
|
|
+Documentation is written in Markdown and reStructuredText. In
|
|
|
+particular, the documentation on our Read the Docs page is written in
|
|
|
+reStructuredText. To ensure that the Read the Docs page builds, you'll
|
|
|
+need to install the documentation dependencies with ``pip``:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ pip install -r docs/requirements.txt
|
|
|
+
|
|
|
+
|
|
|
+To test the docs run:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ py.test --check-links -k .md . || py.test --check-links -k .md --lf .
|
|
|
+
|
|
|
+The Read the Docs pages can be built using ``make``:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ cd docs
|
|
|
+ make html
|
|
|
+
|
|
|
+Or with ``jlpm``:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run docs
|
|
|
|
|
|
Writing Style
|
|
|
'''''''''''''
|
|
@@ -35,68 +649,181 @@ Writing Style
|
|
|
permission, whereas "enable" connotes empowerment.
|
|
|
|
|
|
User Interface Naming Conventions
|
|
|
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+'''''''''''''''''''''''''''''''''
|
|
|
|
|
|
Documents, Files, and Activities
|
|
|
-''''''''''''''''''''''''''''''''
|
|
|
-
|
|
|
-Files are referrred to as either files or documents, depending on the context.
|
|
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
-Documents are more human centered. If human viewing, interpretation, interaction
|
|
|
-is an important part of the experience, it is a document in that context. For
|
|
|
-example, notebooks and markdown files will often be referring to as documents
|
|
|
-unless referring to the file-ness aspect of it (e.g., the notebook filename).
|
|
|
+Files are referrred to as either files or documents, depending on the
|
|
|
+context.
|
|
|
|
|
|
-Files are used in a less human-focused context. For example, we refer to files
|
|
|
-in relation to a file system or file name.
|
|
|
+Documents are more human centered. If human viewing, interpretation,
|
|
|
+interaction is an important part of the experience, it is a document in
|
|
|
+that context. For example, notebooks and markdown files will often be
|
|
|
+referring to as documents unless referring to the file-ness aspect of it
|
|
|
+(e.g., the notebook filename).
|
|
|
|
|
|
-Activities can be either a document or another UI panel that is not file backed,
|
|
|
-such as terminals, consoles or the inspector. An open document or file is an
|
|
|
-activity in that it is represented by a panel that you can interact with.
|
|
|
+Files are used in a less human-focused context. For example, we refer to
|
|
|
+files in relation to a file system or file name.
|
|
|
|
|
|
+Activities can be either a document or another UI panel that is not file
|
|
|
+backed, such as terminals, consoles or the inspector. An open document
|
|
|
+or file is an activity in that it is represented by a panel that you can
|
|
|
+interact with.
|
|
|
|
|
|
Element Names
|
|
|
-'''''''''''''
|
|
|
-
|
|
|
-- The generic content area of a tabbed UI is a panel, but prefer to refer to the
|
|
|
- more specific name, such as “File browser.” Tab bars have tabs which toggle
|
|
|
- panels.
|
|
|
-- The menu bar contains menu items, which have their own submenus.
|
|
|
-- The main work area can be referred to as the work area when the name is unambiguous.
|
|
|
-- When describing elements in the UI, colloquial names are preferred
|
|
|
- (e.g., “File browser” instead of “Files panel”).
|
|
|
-
|
|
|
-The majority of names are written in lower case. These names include:
|
|
|
-
|
|
|
-- tab
|
|
|
-- panel
|
|
|
-- menu bar
|
|
|
-- sidebar
|
|
|
-- file
|
|
|
-- document
|
|
|
-- activity
|
|
|
-- tab bar
|
|
|
-- main work area
|
|
|
-- file browser
|
|
|
-- command palette
|
|
|
-- cell inspector
|
|
|
-- code console
|
|
|
-
|
|
|
-The following sections of the user interface should be in title case, directly
|
|
|
-quoting a word in the UI:
|
|
|
-
|
|
|
-- File menu
|
|
|
-- Files tab
|
|
|
-- Running panel
|
|
|
-- Tabs panel
|
|
|
-- Single-Document Mode
|
|
|
-
|
|
|
-The capitalized words match the label of the UI element the user is clicking on
|
|
|
-because there does not exist a good colloquial name for the tool, such as “file
|
|
|
-browser” or “command palette”.
|
|
|
+^^^^^^^^^^^^^
|
|
|
+
|
|
|
+- The generic content area of a tabbed UI is a panel, but prefer to
|
|
|
+ refer to the more specific name, such as “File browser.” Tab bars
|
|
|
+ have tabs which toggle panels.
|
|
|
+- The menu bar contains menu items, which have their own submenus.
|
|
|
+- The main work area can be referred to as the work area when the name
|
|
|
+ is unambiguous.
|
|
|
+- When describing elements in the UI, colloquial names are preferred
|
|
|
+ (e.g., “File browser” instead of “Files panel”).
|
|
|
+
|
|
|
+The majority of names are written in lower case. These names include:
|
|
|
+
|
|
|
+- tab
|
|
|
+- panel
|
|
|
+- menu bar
|
|
|
+- sidebar
|
|
|
+- file
|
|
|
+- document
|
|
|
+- activity
|
|
|
+- tab bar
|
|
|
+- main work area
|
|
|
+- file browser
|
|
|
+- command palette
|
|
|
+- cell inspector
|
|
|
+- code console
|
|
|
+
|
|
|
+The following sections of the user interface should be in title case,
|
|
|
+directly quoting a word in the UI:
|
|
|
+
|
|
|
+- File menu
|
|
|
+- Files tab
|
|
|
+- Running panel
|
|
|
+- Tabs panel
|
|
|
+- Single-Document Mode
|
|
|
+
|
|
|
+The capitalized words match the label of the UI element the user is
|
|
|
+clicking on because there does not exist a good colloquial name for the
|
|
|
+tool, such as “file browser” or “command palette”.
|
|
|
|
|
|
See :ref:`interface` for descriptions of elements in the UI.
|
|
|
|
|
|
+The Jupyter Server Extension
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+The Jupyter server extension source files are in the jupyterlab/
|
|
|
+subdirectory. To use this extension, make sure the Jupyter Notebook
|
|
|
+server version 4.3 or later is installed.
|
|
|
+
|
|
|
+Build the JupyterLab server extension
|
|
|
+'''''''''''''''''''''''''''''''''''''
|
|
|
+
|
|
|
+When you make a change to JupyterLab npm package source files, run:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jlpm run build
|
|
|
+
|
|
|
+to build the changes, and then refresh your browser to see the changes.
|
|
|
+
|
|
|
+To have the system build after each source file change, run:
|
|
|
+
|
|
|
+.. code:: bash
|
|
|
+
|
|
|
+ jupyter lab --dev-mode --watch
|
|
|
+
|
|
|
+Build Utilities
|
|
|
+~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+There is a range of build utilities for maintaining the repository. To
|
|
|
+get a suggested version for a library use
|
|
|
+``jlpm run get:dependency foo``. To update the version of a library
|
|
|
+across the repo use ``jlpm run update:dependency foo ^latest``. To
|
|
|
+remove an unwanted dependency use ``jlpm run remove:dependency foo``.
|
|
|
+
|
|
|
+The key utility is ``jlpm run integrity``, which ensures the integrity
|
|
|
+of the packages in the repo. It will:
|
|
|
+
|
|
|
+- Ensure the core package version dependencies match everywhere.
|
|
|
+- Ensure imported packages match dependencies.
|
|
|
+- Ensure a consistent version of all packages.
|
|
|
+- Manage the meta package.
|
|
|
+
|
|
|
+The ``packages/metapackage`` package is used to build all of the
|
|
|
+TypeScript in the repository at once, instead of 50+ individual builds.
|
|
|
+
|
|
|
+The integrity script also allows you to automatically add a dependency
|
|
|
+for a package by importing from it in the TypeScript file, and then
|
|
|
+running: ``jlpm run integrity`` from the repo root.
|
|
|
+
|
|
|
+We also have scripts for creating and removing packages in
|
|
|
+``packages/``, ``jlpm run create:package`` and
|
|
|
+``jlpm run remove:package``. When creating a package, if it is meant to
|
|
|
+be included in the core bundle, add the
|
|
|
+``jupyterlab: { coreDependency: true }`` metadata to the
|
|
|
+``package.json``. Packages with ``extension`` or ``mimeExtension``
|
|
|
+metadata are considered to be a core dependency unless they are
|
|
|
+explicitly marked otherwise.
|
|
|
+
|
|
|
+Testing Changes to External Packages
|
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
+
|
|
|
+Linking/Unlinking Packages to JupyterLab
|
|
|
+''''''''''''''''''''''''''''''''''''''''
|
|
|
+
|
|
|
+If you want to make changes to one of JupyterLab's external packages
|
|
|
+(for example, `Lumino <https://github.com/jupyterlab/lumino>`__ and test
|
|
|
+them out against your copy of JupyterLab, you can easily do so using the
|
|
|
+``link`` command:
|
|
|
+
|
|
|
+1. Make your changes and then build the external package
|
|
|
+2. Register a link to the modified external package
|
|
|
+
|
|
|
+ - navigate to the external package dir and run ``jlpm link``
|
|
|
+
|
|
|
+3. Link JupyterLab to modded package
|
|
|
+
|
|
|
+ - navigate to top level of your JupyterLab repo, then run
|
|
|
+ ``jlpm link "<package-of-interest>"``
|
|
|
+
|
|
|
+You can then (re)build JupyterLab (eg ``jlpm run build``) and your
|
|
|
+changes should be picked up by the build.
|
|
|
+
|
|
|
+To restore JupyterLab to its original state, you use the ``unlink``
|
|
|
+command:
|
|
|
+
|
|
|
+1. Unlink JupyterLab and modded package
|
|
|
+
|
|
|
+ - navigate to top level of your JupyterLab repo, then run
|
|
|
+ ``jlpm unlink "<package-of-interest>"``
|
|
|
+
|
|
|
+2. Reinstall original version of the external package in JupyterLab
|
|
|
+
|
|
|
+ - run ``jlpm install --check-files``
|
|
|
+
|
|
|
+You can then (re)build JupyterLab and everything should be back to
|
|
|
+default.
|
|
|
+
|
|
|
+Possible Linking Pitfalls
|
|
|
+'''''''''''''''''''''''''
|
|
|
+
|
|
|
+If you're working on an external project with more than one package,
|
|
|
+you'll probably have to link in your copies of every package in the
|
|
|
+project, including those you made no changes to. Failing to do so may
|
|
|
+cause issues relating to duplication of shared state.
|
|
|
+
|
|
|
+Specifically, when working with Lumino, you'll probably have to link
|
|
|
+your copy of the ``"@lumino/messaging"`` package (in addition to
|
|
|
+whatever packages you actually made changes to). This is due to
|
|
|
+potential duplication of objects contained in the ``MessageLoop``
|
|
|
+namespace provided by the ``messaging`` package.
|
|
|
+
|
|
|
Keyboard Shortcuts
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
@@ -117,50 +844,66 @@ Our documentation should contain screenshots and animations that
|
|
|
illustrate and demonstrate the software. Here are some guidelines for
|
|
|
preparing them:
|
|
|
|
|
|
-- Make sure the screenshot does not contain copyrighted material (preferable),
|
|
|
- or the license is allowed in our documentation and clearly stated.
|
|
|
-
|
|
|
-- If taking a png screenshot, use the Firefox or Chrome developer tools to do the following:
|
|
|
-
|
|
|
- - set the browser viewport to 1280x720 pixels
|
|
|
- - set the device pixel ratio to 1:1 (i.e., non-hidpi, non-retina)
|
|
|
- - screenshot the entire *viewport* using the browser developer tools. Screenshots should
|
|
|
- not include any browser elements such as the browser address bar, browser title bar, etc.,
|
|
|
- and should not contain any desktop background.
|
|
|
-
|
|
|
-- If creating a movie, adjust the settings as above (1280x720 viewport resolution, non-hidpi)
|
|
|
- and use a screen capture utility of your choice to capture just the browser viewport.
|
|
|
-
|
|
|
-- For PNGs, reduce their size using ``pngquant --speed 1 <filename>``. The
|
|
|
- resulting filename will have ``-fs8`` appended, so make sure to rename it and
|
|
|
- use the resulting file. Commit the optimized png file to the main repository.
|
|
|
- Each png file should be no more than a few hundred kilobytes.
|
|
|
-
|
|
|
-- For movies, upload them to the IPython/Jupyter YouTube channel and add them
|
|
|
- to the `jupyterlab-media <https://github.com/jupyterlab/jupyterlab-media>`__
|
|
|
+- Make sure the screenshot does not contain copyrighted material
|
|
|
+ (preferable), or the license is allowed in our documentation and
|
|
|
+ clearly stated.
|
|
|
+- If taking a png screenshot, use the Firefox or Chrome developer tools
|
|
|
+ to do the following:
|
|
|
+
|
|
|
+ - set the browser viewport to 1280x720 pixels
|
|
|
+ - set the device pixel ratio to 1:1 (i.e., non-hidpi, non-retina)
|
|
|
+ - screenshot the entire *viewport* using the browser developer
|
|
|
+ tools. Screenshots should not include any browser elements such as
|
|
|
+ the browser address bar, browser title bar, etc., and should not
|
|
|
+ contain any desktop background.
|
|
|
+
|
|
|
+- If creating a movie, adjust the settings as above (1280x720 viewport
|
|
|
+ resolution, non-hidpi) and use a screen capture utility of your
|
|
|
+ choice to capture just the browser viewport.
|
|
|
+- For PNGs, reduce their size using ``pngquant --speed 1 <filename>``.
|
|
|
+ The resulting filename will have ``-fs8`` appended, so make sure to
|
|
|
+ rename it and use the resulting file. Commit the optimized png file
|
|
|
+ to the main repository. Each png file should be no more than a few
|
|
|
+ hundred kilobytes.
|
|
|
+- For movies, upload them to the IPython/Jupyter YouTube channel and
|
|
|
+ add them to the
|
|
|
+ `jupyterlab-media <https://github.com/jupyterlab/jupyterlab-media>`__
|
|
|
repository. To embed a movie in the documentation, use the
|
|
|
- ``www.youtube-nocookie.com`` website, which can be found by clicking on the
|
|
|
- 'privacy-enhanced' embedding option in the Share dialog on YouTube. Add the
|
|
|
- following parameters the end of the URL ``?rel=0&showinfo=0``. This
|
|
|
- disables the video title and related video suggestions.
|
|
|
-
|
|
|
-- Screenshots or animations should be preceded by a sentence
|
|
|
- describing the content, such as "To open a file, double-click on its
|
|
|
- name in the File Browser:".
|
|
|
-
|
|
|
-- We have custom CSS that will add box shadows, and proper sizing of screenshots and
|
|
|
- embedded YouTube videos. See examples in the documentation for how to embed these
|
|
|
- assets.
|
|
|
-
|
|
|
-To help us organize screenshots and animations, please name the files with a prefix
|
|
|
-that matches the names of the source file in which they are used:
|
|
|
+ ``www.youtube-nocookie.com`` website, which can be found by clicking
|
|
|
+ on the 'privacy-enhanced' embedding option in the Share dialog on
|
|
|
+ YouTube. Add the following parameters the end of the URL
|
|
|
+ ``?rel=0&showinfo=0``. This disables the video title and related
|
|
|
+ video suggestions.
|
|
|
+- Screenshots or animations should be preceded by a sentence describing
|
|
|
+ the content, such as "To open a file, double-click on its name in the
|
|
|
+ File Browser:".
|
|
|
+- We have custom CSS that will add box shadows, and proper sizing of
|
|
|
+ screenshots and embedded YouTube videos. See examples in the
|
|
|
+ documentation for how to embed these assets.
|
|
|
+
|
|
|
+To help us organize screenshots and animations, please name the files
|
|
|
+with a prefix that matches the names of the source file in which they
|
|
|
+are used:
|
|
|
|
|
|
::
|
|
|
|
|
|
- sourcefile.rst
|
|
|
- sourcefile_filebrowser.png
|
|
|
- sourcefile_editmenu.png
|
|
|
-
|
|
|
-This will help us to keep track of the images as documentation content evolves.
|
|
|
-
|
|
|
+ sourcefile.rst
|
|
|
+ sourcefile_filebrowser.png
|
|
|
+ sourcefile_editmenu.png
|
|
|
+
|
|
|
+This will help us to keep track of the images as documentation content
|
|
|
+evolves.
|
|
|
+
|
|
|
+Notes
|
|
|
+~~~~~
|
|
|
+
|
|
|
+- By default, the application will load from the JupyterLab staging
|
|
|
+ directory (default is ``<sys-prefix>/share/jupyter/lab/build``. If
|
|
|
+ you wish to run the core application in
|
|
|
+ ``<git root>/jupyterlab/build``, run ``jupyter lab --core-mode``.
|
|
|
+ This is the core application that will be shipped.
|
|
|
+- If working with extensions, see the :ref:`extension documentation <developer_extensions>`.
|
|
|
+- The npm modules are fully compatible with Node/Babel/ES6/ES5. Simply
|
|
|
+ omit the type declarations when using a language other than
|
|
|
+ TypeScript.
|
|
|
|