contributing.rst 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. Contributing to JupyterLab
  2. --------------------------
  3. If you're reading this section, you're probably interested in contributing to
  4. JupyterLab. Welcome and thanks for your interest in contributing!
  5. Please take a look at the Contributor documentation, familiarize yourself with
  6. using JupyterLab, and introduce yourself to the community (on the mailing list
  7. or discourse) and share what area of the project you are interested in working
  8. on. Please also see the Jupyter `Community Guides <https://jupyter.readthedocs.io/en/latest/community/content-community.html>`_.
  9. 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>`_
  10. or `help wanted <https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22>`_
  11. that we believe are good examples of small, self-contained changes. We encourage those that are new to the code base
  12. to implement and/or ask questions about these issues.
  13. If you believe you’ve found a security vulnerability in JupyterLab or any
  14. Jupyter project, please report it to
  15. `security@ipython.org <mailto:security@ipython.org>`_. If you prefer to encrypt your
  16. security reports, you can use `this PGP public
  17. key <https://raw.githubusercontent.com/jupyter/notebook/master/docs/source/ipython_security.asc>`_.
  18. .. contents:: Table of contents
  19. :local:
  20. :depth: 1
  21. General Guidlelines for Contributing
  22. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  23. For general documentation about contributing to Jupyter projects, see the
  24. `Project Jupyter Contributor Documentation <https://jupyter.readthedocs.io/en/latest/contributor/content-contributor.html>`_
  25. and `Code of Conduct <https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md>`_.
  26. All source code is written in
  27. `TypeScript <http://www.typescriptlang.org/Handbook>`_. See the `Style
  28. Guide <https://github.com/jupyterlab/jupyterlab/wiki/TypeScript-Style-Guide>`_.
  29. All source code is formatted using `prettier <https://prettier.io>`_.
  30. When code is modified and committed, all staged files will be automatically
  31. formatted using pre-commit git hooks (with help from the
  32. `lint-staged <https://github.com/okonet/lint-staged>`_ and
  33. `husky <https://github.com/typicode/husky>`_ libraries). The benefit of using a
  34. code formatter like prettier is that it removes the topic of code style from the conversation
  35. when reviewing pull requests, thereby speeding up the review process.
  36. You may also use the prettier npm script (e.g. ``npm run prettier`` or ``yarn prettier`` or
  37. ``jlpm prettier``) to format the entire code base. We recommend installing a prettier extension for your code editor
  38. and configuring it to format your code with a keyboard shortcut or automatically on save.
  39. Submitting a Pull Request Contribution
  40. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  41. Generally, an issue should be opened describing a piece of proposed work and the
  42. issues it solves before a pull request is opened.
  43. Issue Management
  44. ~~~~~~~~~~~~~~~~
  45. Opening an issue lets community members participate in the design discussion,
  46. makes others aware of work being done, and sets the stage for a fruitful community
  47. interaction. A pull request should reference the issue it is addressing. Once the
  48. pull request is merged, the issue related to it will also be closed. If there is
  49. additional discussion around implemementation the issue may be re-opened. Once 30 days
  50. have passed with no additional discussion, the `lock bot <https://github.com/apps/lock>`_ will lock the issue. If
  51. additional discussion is desired, or if the pull request doesn't fully address the
  52. locked issue, please open a new issue referencing the locked issue.
  53. Tag Issues with Labels
  54. ''''''''''''''''''''''
  55. Users without the commit rights to the JupyterLab repository can tag issues with
  56. labels using the ``@meeseeksdev`` bot. For example: To apply the label ``foo`` and
  57. ``bar baz`` to an issue, comment ``@meeseeksdev tag foo "bar baz"`` on the issue.
  58. Setting Up a Development Environment
  59. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  60. You can launch a binder with the latest JupyterLab master to test something (this may take a few minutes to load):
  61. .. image:: https://mybinder.org/badge_logo.svg
  62. :target: https://mybinder.org/v2/gh/jupyterlab/jupyterlab/master?urlpath=lab-dev/
  63. Installing Node.js and jlpm
  64. '''''''''''''''''''''''''''
  65. Building JupyterLab from its GitHub source code requires Node.js. The development version requires Node.js version 10+,
  66. as defined in the ``engines`` specification in `dev_mode/package.json <dev_mode/package.json>`_.
  67. If you use ``conda``, you can get it with:
  68. .. code-block:: bash
  69. conda install -c conda-forge 'nodejs'
  70. If you use `Homebrew <http://brew.sh>`_ on Mac OS X:
  71. .. code-block:: bash
  72. brew install node
  73. You can also use the installer from the `Node.js <https://nodejs.org>`_ website.
  74. To check which version of Node.js is installed:
  75. .. code-block:: bash
  76. node -v
  77. Installing JupyterLab
  78. ~~~~~~~~~~~~~~~~~~~~~
  79. JupyterLab requires Jupyter Notebook version 4.3 or later.
  80. If you use ``conda``, you can install notebook using:
  81. .. code-block:: bash
  82. conda install -c conda-forge notebook
  83. You may also want to install ``nb_conda_kernels`` to have a kernel option for different
  84. `conda environments <https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html>`_
  85. .. code-block:: bash
  86. conda install -c conda-forge nb_conda_kernels
  87. If you use ``pip``, you can install notebook using:
  88. .. code-block:: bash
  89. pip install notebook
  90. Fork the JupyterLab `repository <https://github.com/jupyterlab/jupyterlab>`_.
  91. Once you have installed the dependencies mentioned above, use the following
  92. steps:
  93. .. code-block:: bash
  94. git clone https://github.com/<your-github-username>/jupyterlab.git
  95. cd jupyterlab
  96. pip install -e .
  97. jlpm install
  98. jlpm run build # Build the dev mode assets (optional)
  99. jlpm run build:core # Build the core mode assets (optional)
  100. jupyter lab build # Build the app dir assets (optional)
  101. Notes:
  102. - 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.
  103. - 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.
  104. - The ``jlpm`` command is a JupyterLab-provided, locked version of the `yarn <https://yarnpkg.com/en>`_ package manager. If you have ``yarn`` installed
  105. already, you can use the ``yarn`` command when developing, and it will use the
  106. local version of ``yarn`` in ``jupyterlab/yarn.js`` when run in the repository or
  107. a built application directory.
  108. - 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.
  109. - 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
  110. rebuild.
  111. - If ``pip`` gives a ``VersionConflict`` error, it usually means that the installed
  112. version of ``jupyterlab_server`` is out of date. Run ``pip install --upgrade jupyterlab_server`` to get the latest version.
  113. - 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):
  114. - You can run ``jlpm run build:dev:prod`` to build more accurate sourcemaps that show the original
  115. Typescript code when debugging. However, it takes a bit longer to build the sources, so is used only to build for production
  116. by default.
  117. If you are using a version of Jupyter Notebook earlier than 5.3, then
  118. you must also run the following command to enable the JupyterLab
  119. server extension:
  120. .. code-block:: bash
  121. jupyter serverextension enable --py --sys-prefix jupyterlab
  122. For installation instructions to write documentation, please see `Writing Documentation`_
  123. Run JupyterLab
  124. ''''''''''''''
  125. Start JupyterLab in development mode:
  126. .. code-block:: bash
  127. jupyter lab --dev-mode
  128. Development mode ensures that you are running the JavaScript assets that are
  129. built in the dev-installed Python package. Note that when running in dev mode,
  130. extensions will not be activated by default.
  131. When running in dev mode, a red stripe will appear at the top of the page;
  132. this is to indicate running an unreleased version.
  133. Build and Run the Tests
  134. '''''''''''''''''''''''
  135. .. code-block:: bash
  136. jlpm run build:test
  137. jlpm test
  138. You can run tests for an individual package by changing to the appropriate
  139. package folder:
  140. .. code-block:: bash
  141. cd packages/notebook
  142. jlpm run build:test
  143. jlpm test
  144. We use ``jest`` for all tests, so standard ``jest`` workflows apply. Tests can be debugged in either
  145. VSCode or Chrome. It can help to add an ``it.only`` to a specific test when debugging. All of the
  146. ``test*`` scripts in each package accept ``jest`` `cli options <https://jestjs.io/docs/en/cli.html>`_.
  147. VSCode Debugging
  148. ^^^^^^^^^^^^^^^^
  149. To debug in VSCode, open a package folder in VSCode. We provide a launch configuration in each package folder.
  150. In a terminal, run ``jlpm test:debug:watch``. In VSCode, select "Attach to Jest" from the
  151. "Run" sidebar to begin debugging. See `VSCode docs on debugging <https://code.visualstudio.com/docs/editor/debugging>`_
  152. for more details.
  153. Chrome Debugging
  154. ^^^^^^^^^^^^^^^^
  155. To debug in Chrome, run ``jlpm test:debug:watch`` in the terminal.
  156. Open Chrome and go to ``chrome://inspect/``. Select the remote device and begin debugging.
  157. Testing Utilities
  158. ^^^^^^^^^^^^^^^^^
  159. There are some helper functions in ``testutils`` (which is a public npm package called ``@jupyterlab/testutils``) that are used by many of the tests.
  160. For tests that rely on ``@jupyterlab/services`` (starting kernels, interacting with files, etc.), there are two
  161. options. If a simple interaction is needed, the ``Mock`` namespace exposed by ``testutils`` has a number of
  162. mock implmentations (see ``testutils/src/mock.ts``). If a full server interaction is required,
  163. use the ``JupyterServer`` class.
  164. We have a helper function called ``testEmission`` to help with
  165. writing tests that use ``Lumino`` signals, as well as a ``framePromise`` function
  166. to get a ``Promise`` for a ``requestAnimationFrame``. We sometimes have to set
  167. a sentinel value inside a ``Promise`` and then check that the sentinel was set if
  168. we need a promise to run without blocking.
  169. Performance Testing
  170. ~~~~~~~~~~~~~~~~~~~
  171. If you are making a change that might affect how long it takes to load JupyterLab in the browser,
  172. we recommend doing some performance testing using `Lighthouse <https://github.com/GoogleChrome/lighthouse>`_.
  173. It let's you easily compute a number of metrics, like page load time, for the site.
  174. To use it, first build JupyterLab in dev mode:
  175. .. code-block:: bash
  176. jlpm run build:dev
  177. Then, start JupyterLab using the dev build:
  178. .. code-block:: bash
  179. jupyter lab --dev --NotebookApp.token='' --no-browser
  180. Now run Lighthouse against this local server and show the results:
  181. .. code-block:: bash
  182. jlpm run lighthouse --view
  183. .. image:: /images/lighthouse.png
  184. Using throttling
  185. ''''''''''''''''
  186. Lighthouse recommends using the system level `comcast <https://github.com/tylertreat/comcast>`_ tool to throttle your network connection
  187. and emulate different scenarios. To use it, first install that tool using ``go``:
  188. .. code-block:: bash
  189. go get github.com/tylertreat/comcast
  190. Then, before you run Lighthouse, enable the throttling (this requires sudo):
  191. .. code-block:: bash
  192. run lighthouse:throttling:start
  193. This enables the "WIFI (good)" preset of comcast, which should emulate
  194. loading JupyterLab over a local network.
  195. Then run the lighthouse tests:
  196. .. code-block:: bash
  197. jlpm run lighthouse [...]
  198. Then disable the throttling after you are done:
  199. .. code-block:: bash
  200. jlpm run lighthouse:throttling:stop
  201. Comparing results
  202. '''''''''''''''''
  203. Performance results are usually only useful in comparison to other results.
  204. For that reason, we have included a comparison script that can take two
  205. lighthouse results and show the changes between them.
  206. 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.
  207. First, we build JupyterLab normally, start it up, profile it and save the results:
  208. .. code-block:: bash
  209. jlpm build:dev
  210. jupyter lab --dev --NotebookApp.token='' --no-browser
  211. # in new window
  212. jlpm run lighthouse --output json --output-path normal.json
  213. Then rebuild with the production build and retest:
  214. .. code-block:: bash
  215. jlpm run build:dev:prod
  216. jupyter lab --dev --NotebookApp.token='' --no-browser
  217. # in new window
  218. jlpm run lighthouse --output json --output-path prod.json
  219. Now we can use compare the two outputs:
  220. .. code-block:: bash
  221. jlpm run lighthouse:compare normal.json prod.json
  222. This gives us a report of the relative differences between the audits in the two reports:
  223. .. admonition:: Resulting Output
  224. | `normal.json` -> `prod.json`
  225. | **First Contentful Paint**
  226. | - -62% Δ
  227. | - 1.9 s -> 0.7 s
  228. | - 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>`_.
  229. | **First Meaningful Paint**
  230. | - -50% Δ
  231. | - 2.5 s -> 1.3 s
  232. | - 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>`_.
  233. | **Speed Index**
  234. | - -48% Δ
  235. | - 2.6 s -> 1.3 s
  236. | - 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>`_.
  237. | **Estimated Input Latency**
  238. | - 0% Δ
  239. | - 20 ms -> 20 ms
  240. | - 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>`_.
  241. | **Max Potential First Input Delay**
  242. | - 9% Δ
  243. | - 200 ms -> 210 ms
  244. | - 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>`_.
  245. | **First CPU Idle**
  246. | - -50% Δ
  247. | - 2.5 s -> 1.3 s
  248. | - 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>`_.
  249. | **Time to Interactive**
  250. | - -52% Δ
  251. | - 2.5 s -> 1.2 s
  252. | - 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>`_.
  253. | **Avoid multiple page redirects**
  254. | - -2% Δ
  255. | - Potential savings of 10 ms -> Potential savings of 10 ms
  256. | - Redirects introduce additional delays before the page can be loaded. `Learn more <https://developers.google.com/web/tools/lighthouse/audits/redirects>`_.
  257. | **Minimize main-thread work**
  258. | - -54% Δ
  259. | - 2.1 s -> 1.0 s
  260. | - Consider reducing the time spent parsing, compiling and executing JS. You may find delivering smaller JS payloads helps with this.
  261. | **JavaScript execution time**
  262. | - -49% Δ
  263. | - 1.1 s -> 0.6 s
  264. | - 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>`_.
  265. | **Preload key requests**
  266. | - -100% Δ
  267. | - Potential savings of 240 ms ->
  268. | - 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>`_.
  269. | **Uses efficient cache policy on static assets**
  270. | - 0% Δ
  271. | - 1 resource found -> 1 resource found
  272. | - A long cache lifetime can speed up repeat visits to your page. `Learn more <https://developers.google.com/web/tools/lighthouse/audits/cache-policy>`_.
  273. | **Avoid enormous network payloads**
  274. | - -86% Δ
  275. | - Total size was 30,131 KB -> Total size was 4,294 KB
  276. | - 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>`_.
  277. | **Minify JavaScript**
  278. | - -100% Δ
  279. | - Potential savings of 23,041 KB ->
  280. | - Minifying JavaScript files can reduce payload sizes and script parse time. `Learn more <https://developers.google.com/speed/docs/insights/MinifyResources>`_.
  281. | **Enable text compression**
  282. | - -86% Δ
  283. | - Potential savings of 23,088 KB -> Potential savings of 3,112 KB
  284. | - 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>`_.
  285. | **Avoid an excessive DOM size**
  286. | - 0% Δ
  287. | - 1,268 elements -> 1,268 elements
  288. | - 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>`_.
  289. Build and run the stand-alone examples
  290. ''''''''''''''''''''''''''''''''''''''
  291. To install and build the examples in the ``examples`` directory:
  292. .. code-block:: bash
  293. jlpm run build:examples
  294. To run a specific example, change to the examples directory (i.e.
  295. ``examples/filebrowser``) and enter:
  296. .. code-block:: bash
  297. python main.py
  298. Debugging in the Browser
  299. ~~~~~~~~~~~~~~~~~~~~~~~~
  300. All methods of building JupyterLab produce source maps. The source maps
  301. should be available in the source files view of your browser's development
  302. tools under the ``webpack://`` header.
  303. When running JupyterLab normally, expand the ``~`` header to see the source maps for individual packages.
  304. When running in ``--dev-mode``, the core packages are available under
  305. ``packages/``, while the third party libraries are available under ``~``.
  306. Note: it is recommended to use ``jupyter lab --watch --dev-mode`` while
  307. debugging.
  308. When running a test, the packages will be available at the top level
  309. (e.g. ``application/src``), and the current set of test files available under
  310. ``/src``. Note: it is recommended to use ``jlpm run watch`` in the test folder
  311. while debugging test options. See `above <#build-and-run-the-tests>`_ for more info.
  312. ----------
  313. High level Architecture
  314. ~~~~~~~~~~~~~~~~~~~~~~~
  315. The JupyterLab application is made up of two major parts:
  316. - an npm package
  317. - a Jupyter server extension (Python package)
  318. Each part is named ``jupyterlab``. The `developer tutorial documentation <https://jupyterlab.readthedocs.io/en/latest/index.html>`_
  319. provides additional architecture information.
  320. The NPM Packages
  321. ~~~~~~~~~~~~~~~~
  322. The repository consists of many npm packages that are managed using the lerna
  323. build tool. The npm package source files are in the ``packages/`` subdirectory.
  324. Build the NPM Packages from Source
  325. ''''''''''''''''''''''''''''''''''
  326. .. code-block:: bash
  327. git clone https://github.com/jupyterlab/jupyterlab.git
  328. cd jupyterlab
  329. pip install -e .
  330. jlpm
  331. jlpm run build:packages
  332. **Rebuild**
  333. .. code-block:: bash
  334. jlpm run clean
  335. jlpm run build:packages
  336. Writing Documentation
  337. ~~~~~~~~~~~~~~~~~~~~~
  338. Documentation is written in Markdown and reStructuredText. In particular, the documentation on our
  339. Read the Docs page is written in reStructuredText. To ensure that the Read the Docs page builds, you'll need to install
  340. the documentation dependencies with ``conda``. These dependencies are located in ``docs/environment.yml``.
  341. You can install the dependencies for building the documentation by creating a new conda environment:
  342. .. code-block:: bash
  343. conda env create -f docs/environment.yml
  344. Alternatively, you can install the documentation dependencies in an existing environment using the following command:
  345. .. code-block:: bash
  346. conda env update -n <ENVIRONMENT> -f docs/environment.yml
  347. The Developer Documentation includes a `guide <https://jupyterlab.readthedocs.io/en/latest/developer/contributing.html>`_ to writing documentation including writing style, naming conventions, keyboard shortcuts, and screenshots.
  348. To test the docs run:
  349. .. code-block:: bash
  350. py.test --check-links -k .md . || py.test --check-links -k .md --lf .
  351. The Read the Docs pages can be built using ``make``:
  352. .. code-block:: bash
  353. cd docs
  354. make html
  355. Or with ``jlpm``:
  356. .. code-block:: bash
  357. jlpm run docs
  358. Writing Style
  359. '''''''''''''
  360. - The documentation should be written in the second person, referring
  361. to the reader as "you" and not using the first person plural "we."
  362. The author of the documentation is not sitting next to the user, so
  363. using "we" can lead to frustration when things don't work as
  364. expected.
  365. - Avoid words that trivialize using JupyterLab such as "simply" or
  366. "just." Tasks that developers find simple or easy may not be for
  367. users.
  368. - Write in the active tense, so "drag the notebook cells..." rather
  369. than "notebook cells can be dragged..."
  370. - The beginning of each section should begin with a short (1-2
  371. sentence) high-level description of the topic, feature or component.
  372. - Use "enable" rather than "allow" to indicate what JupyterLab makes
  373. possible for users. Using "allow" connotes that we are giving them
  374. permission, whereas "enable" connotes empowerment.
  375. The Jupyter Server Extension
  376. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  377. The Jupyter server extension source files are in the `jupyterlab/`
  378. subdirectory. To use this extension, make sure the Jupyter Notebook server
  379. version 4.3 or later is installed.
  380. Build the JupyterLab server extension
  381. '''''''''''''''''''''''''''''''''''''
  382. When you make a change to JupyterLab npm package source files, run:
  383. .. code-block:: bash
  384. jlpm run build
  385. to build the changes, and then refresh your browser to see the changes.
  386. To have the system build after each source file change, run:
  387. .. code-block:: bash
  388. jupyter lab --dev-mode --watch
  389. Build Utilities
  390. ~~~~~~~~~~~~~~~
  391. There is a range of build utilities for maintaining the repository.
  392. To get a suggested version for a library use ``jlpm run get:dependency foo``.
  393. To update the version of a library across the repo use ``jlpm run update:dependency foo ^latest``.
  394. To remove an unwanted dependency use ``jlpm run remove:dependency foo``.
  395. The key utility is ``jlpm run integrity``, which ensures the integrity of
  396. the packages in the repo. It will:
  397. - Ensure the core package version dependencies match everywhere.
  398. - Ensure imported packages match dependencies.
  399. - Ensure a consistent version of all packages.
  400. - Manage the meta package.
  401. The ``packages/metapackage`` package is used to build all of the TypeScript
  402. in the repository at once, instead of 50+ individual builds.
  403. The integrity script also allows you to automatically add a dependency for
  404. a package by importing from it in the TypeScript file, and then running:
  405. ``jlpm run integrity`` from the repo root.
  406. We also have scripts for creating and removing packages in ``packages/``,
  407. ``jlpm run create:package`` and ``jlpm run remove:package``. When creating a package,
  408. if it is meant to be included in the core bundle, add the ``jupyterlab: { coreDependency: true }``
  409. metadata to the ``package.json``. Packages with ``extension`` or ``mimeExtension`` metadata
  410. are considered to be a core dependency unless they are explicitly marked otherwise.
  411. Testing Changes to External Packages
  412. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  413. Linking/Unlinking Packages to JupyterLab
  414. ''''''''''''''''''''''''''''''''''''''''
  415. 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:
  416. 1. Make your changes and then build the external package
  417. 2. Register a link to the modified external package
  418. - navigate to the external package dir and run ``jlpm link``
  419. 3. Link JupyterLab to modded package
  420. - navigate to top level of your JupyterLab repo, then run ``jlpm link "<package-of-interest>"``
  421. You can then (re)build JupyterLab (eg ``jlpm run build``) and your changes should be picked up by the build.
  422. To restore JupyterLab to its original state, you use the ``unlink`` command:
  423. 1. Unlink JupyterLab and modded package
  424. - navigate to top level of your JupyterLab repo, then run ``jlpm unlink "<package-of-interest>"``
  425. 2. Reinstall original version of the external package in JupyterLab
  426. - run ``jlpm install --check-files``
  427. You can then (re)build JupyterLab and everything should be back to default.
  428. Possible Linking Pitfalls
  429. '''''''''''''''''''''''''
  430. 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.
  431. 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.
  432. User Interface Naming Conventions
  433. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  434. Documents, Files, and Activities
  435. ''''''''''''''''''''''''''''''''
  436. Files are referrred to as either files or documents, depending on the context.
  437. Documents are more human centered. If human viewing, interpretation, interaction
  438. is an important part of the experience, it is a document in that context. For
  439. example, notebooks and markdown files will often be referring to as documents
  440. unless referring to the file-ness aspect of it (e.g., the notebook filename).
  441. Files are used in a less human-focused context. For example, we refer to files
  442. in relation to a file system or file name.
  443. Activities can be either a document or another UI panel that is not file backed,
  444. such as terminals, consoles or the inspector. An open document or file is an
  445. activity in that it is represented by a panel that you can interact with.
  446. Element Names
  447. '''''''''''''
  448. - The generic content area of a tabbed UI is a panel, but prefer to refer to the
  449. more specific name, such as “File browser.” Tab bars have tabs which toggle
  450. panels.
  451. - The menu bar contains menu items, which have their own submenus.
  452. - The main work area can be referred to as the work area when the name is unambiguous.
  453. - When describing elements in the UI, colloquial names are preferred
  454. (e.g., “File browser” instead of “Files panel”).
  455. The majority of names are written in lower case. These names include:
  456. - tab
  457. - panel
  458. - menu bar
  459. - sidebar
  460. - file
  461. - document
  462. - activity
  463. - tab bar
  464. - main work area
  465. - file browser
  466. - command palette
  467. - cell inspector
  468. - code console
  469. The following sections of the user interface should be in title case, directly
  470. quoting a word in the UI:
  471. - File menu
  472. - Files tab
  473. - Running panel
  474. - Tabs panel
  475. - Single-Document Mode
  476. The capitalized words match the label of the UI element the user is clicking on
  477. because there does not exist a good colloquial name for the tool, such as “file
  478. browser” or “command palette”.
  479. See :ref:`interface` for descriptions of elements in the UI.
  480. Keyboard Shortcuts
  481. ~~~~~~~~~~~~~~~~~~
  482. Typeset keyboard shortcuts as follows:
  483. - Monospace typeface, with spaces between individual keys:
  484. ``Shift Enter``.
  485. - For modifiers, use the platform independent word describing key:
  486. ``Shift``.
  487. - For the ``Accel`` key use the phrase: ``Command/Ctrl``.
  488. - Don’t use platform specific icons for modifier keys, as they are
  489. difficult to display in a platform specific way on Sphinx/RTD.
  490. Screenshots and Animations
  491. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  492. Our documentation should contain screenshots and animations that
  493. illustrate and demonstrate the software. Here are some guidelines for
  494. preparing them:
  495. - Make sure the screenshot does not contain copyrighted material (preferable),
  496. or the license is allowed in our documentation and clearly stated.
  497. - If taking a png screenshot, use the Firefox or Chrome developer tools to do the following:
  498. - set the browser viewport to 1280x720 pixels
  499. - set the device pixel ratio to 1:1 (i.e., non-hidpi, non-retina)
  500. - screenshot the entire *viewport* using the browser developer tools. Screenshots should
  501. not include any browser elements such as the browser address bar, browser title bar, etc.,
  502. and should not contain any desktop background.
  503. - If creating a movie, adjust the settings as above (1280x720 viewport resolution, non-hidpi)
  504. and use a screen capture utility of your choice to capture just the browser viewport.
  505. - For PNGs, reduce their size using ``pngquant --speed 1 <filename>``. The
  506. resulting filename will have ``-fs8`` appended, so make sure to rename it and
  507. use the resulting file. Commit the optimized png file to the main repository.
  508. Each png file should be no more than a few hundred kilobytes.
  509. - For movies, upload them to the IPython/Jupyter YouTube channel and add them
  510. to the `jupyterlab-media <https://github.com/jupyterlab/jupyterlab-media>`__
  511. repository. To embed a movie in the documentation, use the
  512. ``www.youtube-nocookie.com`` website, which can be found by clicking on the
  513. 'privacy-enhanced' embedding option in the Share dialog on YouTube. Add the
  514. following parameters the end of the URL ``?rel=0&amp;showinfo=0``. This
  515. disables the video title and related video suggestions.
  516. - Screenshots or animations should be preceded by a sentence
  517. describing the content, such as "To open a file, double-click on its
  518. name in the File Browser:".
  519. - We have custom CSS that will add box shadows, and proper sizing of screenshots and
  520. embedded YouTube videos. See examples in the documentation for how to embed these
  521. assets.
  522. To help us organize screenshots and animations, please name the files with a prefix
  523. that matches the names of the source file in which they are used:
  524. ::
  525. sourcefile.rst
  526. sourcefile_filebrowser.png
  527. sourcefile_editmenu.png
  528. This will help us to keep track of the images as documentation content evolves.
  529. Notes
  530. ~~~~~
  531. - By default, the application will load from the JupyterLab staging directory (default is ``<sys-prefix>/share/jupyter/lab/build``. If you wish to run
  532. the core application in ``<git root>/jupyterlab/build``,
  533. run ``jupyter lab --core-mode``. This is the core application that will
  534. be shipped.
  535. - If working with extensions, see the extension documentation on
  536. https://jupyterlab.readthedocs.io/en/latest/index.html.
  537. - The npm modules are fully compatible with Node/Babel/ES6/ES5. Simply
  538. omit the type declarations when using a language other than TypeScript.
  539. - For more information, read the `documentation <http://jupyterlab.readthedocs.io/en/latest/>`_.