Setting up a Development Envrionment
This sections shows how to set up a development environment for Juxl. The setup allows you to develop Juxl and immediatly see the changes in a running JupyterLab instance. The setup process is composed into four steps:
Setup Anaconda
Setup Juxl
Setup Juxl development environment
Edit Juxl to see changes
Setup Anaconda
Install Anaconda
Create a new Anaconda environment
Install Anaconda
To install anaconda see: https://docs.anaconda.com/anaconda/install/index.html
To make sure anaconda is installed run:
root@device:~$ conda --help
usage: conda [-h] [-V] command ...
conda is a tool for managing and deploying applications, environments and packages.
Options:
positional arguments:
command
clean Remove unused packages and caches.
compare Compare packages between conda environments.
config Modify configuration values in .condarc. This is modeled after the git config command. Writes to the user .condarc file (/home/yanik/.condarc) by default.
create Create a new conda environment from a list of specified packages.
help Displays a list of available conda commands and their help strings.
info Display information about current conda install.
init Initialize conda for shell interaction. [Experimental]
install Installs a list of packages into a specified conda environment.
list List linked packages in a conda environment.
package Low-level conda package utility. (EXPERIMENTAL)
remove Remove a list of packages from a specified conda environment.
uninstall Alias for conda remove.
run Run an executable in a conda environment. [Experimental]
search Search for packages and display associated information. The input is a MatchSpec, a query language for conda packages. See examples below.
update Updates conda packages to the latest compatible version.
upgrade Alias for conda update.
optional arguments:
-h, --help Show this help message and exit.
-V, --version Show the conda version number and exit.
conda commands available from other packages:
env
Create a new Anaconda Environment:
The next step is setting up a Anaconda environment for Juxl.
We will name the environment juxl.
We will also install jupyterlab, nodejs, jupyter-packaging.
To create the envrionment run:
root@device:~$ conda create -n juxl --override-channels --strict-channel-priority -c conda-forge -c nodefaults jupyterlab=3.1.6 nodejs jupyter-packaging
For all further code we assume the juxl conda environment is activated.
It can be activated by running:
root@device:~$ conda activate juxl
(juxl) root@device:~$
Setup Juxl
To setup Juxl, we need to execute the following steps:
Clone Juxl
Install Dependencies
Build Juxl
Test Juxl
Locally install Juxl
each step is explained in the following sections:
Clone Juxl Repository
We use git to clone the Juxl repository in our home directory.
root@device:~$ git clone git@git.rwth-aachen.de:learntech-lufgi9/bama/juxl/juxl.git
Install Dependencies
Juxl has many npm dependencies that are needed for it to run and to be build.
to install the dependencies, cd into the repository and run jlpm.
(juxl) root@device:~$ cd juxl
(juxl) root@device:~/juxl$ jlpm
yarn install v1.21.1
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 5.50s.
Build Juxl
Since Juxl is written in TypeScript, it needs to be compiled to JavaScript.
To do so run jlpm build:
(juxl) root@device:~/juxl$ jlpm build
yarn run v1.21.1
$ lerna run build
lerna notice cli v4.0.0
lerna info versioning independent
lerna info Executing command in 7 packages: "jlpm run build"
lerna info run Ran npm script 'build' in '@juxl/performance' in 2.2s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/juxl' in 2.5s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/log-console' in 4.0s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/vocabulary' in 4.0s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/performance-extension' in 4.1s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/logging' in 4.2s:
$ tsc
lerna info run Ran npm script 'build' in '@juxl/juxl-extension' in 4.1s:
$ tsc
lerna success run Ran npm script 'build' in 7 packages in 14.8s:
lerna success - @juxl/juxl-extension
lerna success - @juxl/juxl
lerna success - @juxl/log-console
lerna success - @juxl/logging
lerna success - @juxl/performance-extension
lerna success - @juxl/performance
lerna success - @juxl/vocabulary
Done in 15.25s.
This script build all Juxl packages, namely
@juxl/juxl-extension,
@juxl/juxl,
@juxl/log-console,
@juxl/logging,
@juxl/performance-extension,
@juxl/performance, and
@juxl/vocabulary.
Test Juxl
The Juxl Repository contains Unit-Test for Juxl.
We can run the test by executing jlpm test
(juxl) root@device:~/juxl$ jlpm test
yarn run v1.21.1
$ jlpm test:all
$ lerna run test --concurrency 1 --stream
lerna notice cli v4.0.0
lerna info versioning independent
lerna info Executing command in 3 packages: "jlpm run test"
@juxl/juxl: $ jest --config test/test.config.js
@juxl/juxl: PASS test/tests/jlStatement.spec.ts (7.293 s)
@juxl/juxl: PASS test/tests/basicJuxl.spec.ts (7.406 s)
@juxl/juxl: PASS test/tests/xApiConnection/bufferedXApiConnection.spec.ts (7.474 s)
@juxl/juxl: PASS test/tests/mergeXApiContexts.spec.ts (7.44 s)
@juxl/juxl: PASS test/tests/lrsJuxl.spec.ts (7.444 s)
@juxl/juxl: PASS test/tests/countingJuxl.spec.ts (7.406 s)
@juxl/juxl: PASS test/tests/xApiConnection/xApiConnection.spec.ts (7.425 s)
@juxl/juxl: =============================== Coverage summary ===============================
@juxl/juxl: Statements : 88.03% ( 103/117 )
@juxl/juxl: Branches : 94.05% ( 79/84 )
@juxl/juxl: Functions : 80.56% ( 29/36 )
@juxl/juxl: Lines : 87.93% ( 102/116 )
@juxl/juxl: ================================================================================
@juxl/juxl: Test Suites: 7 passed, 7 total
@juxl/juxl: Tests: 24 passed, 24 total
@juxl/juxl: Snapshots: 0 total
@juxl/juxl: Time: 8.64 s
@juxl/juxl: Ran all test suites.
@juxl/juxl-extension: $ jest --config test/test.config.js
@juxl/juxl-extension: PASS test/tests/jest/jest.spec.ts (5.088 s)
@juxl/juxl-extension: PASS test/tests/jest/jest_coverage.spec.ts (5.769 s)
@juxl/juxl-extension: PASS test/tests/xAPI.spec.ts (6.254 s)
@juxl/juxl-extension: PASS test/tests/connectAbleJuxl.spec.ts (6.47 s)
@juxl/juxl-extension: PASS test/tests/agentSettings.spec.ts (6.494 s)
@juxl/juxl-extension: PASS test/tests/lrsSettings.spec.ts (6.544 s)
@juxl/juxl-extension: =============================== Coverage summary ===============================
@juxl/juxl-extension: Statements : 20.87% ( 129/618 )
@juxl/juxl-extension: Branches : 24% ( 48/200 )
@juxl/juxl-extension: Functions : 20.44% ( 28/137 )
@juxl/juxl-extension: Lines : 20.63% ( 125/606 )
@juxl/juxl-extension: ================================================================================
@juxl/juxl-extension: Test Suites: 6 passed, 6 total
@juxl/juxl-extension: Tests: 54 passed, 54 total
@juxl/juxl-extension: Snapshots: 0 total
@juxl/juxl-extension: Time: 19.427 s
@juxl/juxl-extension: Ran all test suites.
@juxl/performance-extension: $ jest --config test/test.config.js
@juxl/performance-extension: PASS test/tests/transformMatrix.spec.ts
@juxl/performance-extension: transformMatrix
@juxl/performance-extension: ✓ static matrix 1 (3 ms)
@juxl/performance-extension: ✓ static string matrix
@juxl/performance-extension: ✓ should throw on undefined matrix (4 ms)
@juxl/performance-extension: =============================== Coverage summary ===============================
@juxl/performance-extension: Statements : 4.4% ( 14/318 )
@juxl/performance-extension: Branches : 0% ( 0/28 )
@juxl/performance-extension: Functions : 2.33% ( 2/86 )
@juxl/performance-extension: Lines : 4.52% ( 14/310 )
@juxl/performance-extension: ================================================================================
@juxl/performance-extension: Test Suites: 1 passed, 1 total
@juxl/performance-extension: Tests: 3 passed, 3 total
@juxl/performance-extension: Snapshots: 0 total
@juxl/performance-extension: Time: 14.074 s
@juxl/performance-extension: Ran all test suites.
lerna success run Ran npm script 'test' in 3 packages in 47.2s:
lerna success - @juxl/juxl-extension
lerna success - @juxl/juxl
lerna success - @juxl/performance-extension
Done in 48.59s.
Locally Install a Package:
We can install each of the Juxl packages @juxl/juxl-extension,
@juxl/juxl,
@juxl/log-console,
@juxl/logging,
@juxl/performance-extension,
@juxl/performance, and
@juxl/vocabulary locally.
This sections how to install the @juxl/juxl-extension locally.
To do so change the current diretory to the requested package and run jupyter labextension install ..
(juxl) root@device:~/juxl$ cd packages/juxl-extension
(juxl) root@device:~/juxl/packages/juxl-extension$ jupyter labextension install .
Building jupyterlab assets (development)
We can test if the package is installed sucessfully by listing the JupyterLab Extensions and looking for the @juxl/juxl-extension extension.
(juxl) root@device:~/juxl$ jupyter labextension list
jupyter labextension list
JupyterLab v3.1.6
Other labextensions (built into JupyterLab)
app dir: /home/user/.conda/envs/juxl/share/jupyter/lab
@juxl/juxl-extension v3.0.2 enabled OK*
local extensions:
@juxl/juxl-extension: /home/user/juxl/packages/juxl-extension
We see the @juxl/juxl-extension extension listed under local extensions.
Setup Juxl Development Envrionment
Finally we setup the development environment, that allows us to make changes to a package, which is then visible in a running JupyterLab instance. To do so, we need to automatically compile Juxl, if changes to the code are made and automatically compile JupyterLab if an extension changes. This section is split in the two parts:
Setup automatic compilation of Juxl
Setup automatic compilation of JupyterLab
Setup Automatic Compilation of Juxl
We can interactively compile a package with jlpm watch.
This will watch for changes to the code and compile the code once changes are made.
Since the command will run indefinitely, it occupies the terminal.
We later reference this terminal with #TERMINAL 1.
Caution
Do not forgett to activate the anaconda environment!
#TERMINAL 1
(juxl) root@device:~/juxl$ cd packages/juxl-extension
(juxl) root@device:~/juxl/packages/juxl-extension jlpm watch
yarn run v1.21.1
$ tsc -w
[11:04:07 AM] Starting compilation in watch mode...
[11:04:10 AM] Found 0 errors. Watching for file changes.
Setup Automatic Compilation of JupyterLab
We can run JupyterLab with the --watch flag, which makes JupyterLab watching the locally installed Extensions and compile itself once changes are made.
This will occupie the terminal.
We later reference this terminal with #TERMINAL 2.
#TERMINAL 2
(juxl) root@device:~$ jupyter lab --watch
[I 2021-12-10 11:09:46.883 ServerApp] jupyterlab | extension was successfully linked.
[I 2021-12-10 11:09:47.028 ServerApp] nbclassic | extension was successfully linked.
[I 2021-12-10 11:09:47.050 ServerApp] nbclassic | extension was successfully loaded.
[I 2021-12-10 11:09:47.051 LabApp] JupyterLab extension loaded from /home/user/.conda/envs/jl2/lib/python3.9/site-packages/jupyterlab
[I 2021-12-10 11:09:47.051 LabApp] JupyterLab application directory is /home/user/.conda/envs/jl2/share/jupyter/lab
[I 2021-12-10 11:09:47.051 LabApp] Starting JupyterLab watch mode...
[I 2021-12-10 11:09:51.010 LabApp] > node /home/user/.conda/envs/jl2/lib/python3.9/site-packages/jupyterlab/staging/yarn.js run watch
yarn run v1.21.1
warning ../../../../../../../package.json: No license field
$ webpack --watch
If changes are made to the installed package, they will be visible in JupyterLab after a few moments.
Edit Juxl to see changes
To get an better understanding of the process, we will edit the @juxl/juxl-extension package and see the changes to the running JupyterLab instance.
To do so, we will:
Edit the Extension
See Changes in TERMINAL 1
See Changes in TERMINAL 2
See Changes to the JupyterLab Website
Edit the Extension
To edit the @juxl/juxl-extension extension, we will add a console log.
I.e. we will add the line console.log("TEST") to the extension.
This will log “TEST” to the JavaScript Console in our browser.
root@device:~/juxl/packages/juxl-extension echo 'console.log("TEST")' >> src/index.ts
See Changes in TERMINAL 1
You should see, that jlpm compiles the package:
New entries: File change detected... are added.
# TERMINAL 1
root@device:~/juxl/packages/juxl-extension jlpm watch
yarn run v1.21.1
$ tsc -w
[11:08:51 AM] Starting compilation in watch mode...
[11:08:54 AM] Found 0 errors. Watching for file changes.
[11:12:51 AM] File change detected. Starting incremental compilation...
[11:12:52 AM] Found 0 errors. Watching for file changes.
See Changes in TERMINAL 2
Furthermore, you should see changes to TERMINAL 2.
A new line :code:` webpack 5.50.0 compiled …` is added to the output.
#TERMINAL 2
root@device:~$ jupyter lab --watch
[I 2021-12-10 11:09:46.883 ServerApp] jupyterlab | extension was successfully linked.
[I 2021-12-10 11:09:47.028 ServerApp] nbclassic | extension was successfully linked.
[I 2021-12-10 11:09:47.050 ServerApp] nbclassic | extension was successfully loaded.
[I 2021-12-10 11:09:47.051 LabApp] JupyterLab extension loaded from /home/user/.conda/envs/jl2/lib/python3.9/site-packages/jupyterlab
[I 2021-12-10 11:09:47.051 LabApp] JupyterLab application directory is /home/user/.conda/envs/jl2/share/jupyter/lab
[I 2021-12-10 11:09:47.051 LabApp] Starting JupyterLab watch mode...
[I 2021-12-10 11:09:51.010 LabApp] > node /home/user/.conda/envs/jl2/lib/python3.9/site-packages/jupyterlab/staging/yarn.js run watch
yarn run v1.21.1
warning ../../../../../../../package.json: No license field
$ webpack --watch
webpack 5.50.0 compiled with 63 warnings in 1343 ms
See Changes to the JupyterLab Website
If we now reload the page and open the JavaScript Console, we see the logged string.
Caution
Do not forgett to refresh the Website after each change.