Skip to content
This repository has been archived by the owner on Apr 6, 2021. It is now read-only.

Work Toward Extension chain #22

Merged
merged 9 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ jobs:
run: |
source "$CONDA/etc/profile.d/conda.sh"
conda activate jupyterlab-module-federation
pip install jupyterlab==2.1.5
python run.py

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ stats.json
node_modules
core_package/build
md_package/build
log.json
4 changes: 3 additions & 1 deletion build-ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ commander
const webpack = require.resolve('webpack-cli');

let cmdText = `${webpack} --config webpack.config.ext.js`;
run(cmdText, { env: { ...process.env, OUTPUT_PATH: output, PACKAGE_PATH: packagePath, NODE_ENV: node_env } });
const env = { OUTPUT_PATH: output, PACKAGE_PATH: packagePath, NODE_ENV: node_env };
console.log(env);
run(cmdText, { env: { ...process.env, ...env } });
}
);

Expand Down
2 changes: 0 additions & 2 deletions core_package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
"@jupyterlab/logconsole-extension": "~3.0.0-alpha.4",
"@jupyterlab/mainmenu": "~3.0.0-alpha.4",
"@jupyterlab/mainmenu-extension": "~3.0.0-alpha.4",
"@jupyterlab/markdownviewer": "~3.0.0-alpha.4",
"@jupyterlab/mathjax2": "~3.0.0-alpha.4",
"@jupyterlab/mathjax2-extension": "~3.0.0-alpha.4",
"@jupyterlab/metapackage": "~3.0.0-alpha.4",
Expand Down Expand Up @@ -145,7 +144,6 @@
"@jupyterlab/launcher",
"@jupyterlab/logconsole",
"@jupyterlab/mainmenu",
"@jupyterlab/markdownviewer",
"@jupyterlab/notebook",
"@jupyterlab/rendermime",
"@jupyterlab/rendermime-interfaces",
Expand Down
29 changes: 21 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

from jupyterlab_server import LabServerApp, LabConfig
from jupyterlab_server.server import FileFindHandler, APIHandler

from notebook.utils import url_path_join as ujoin, url_escape
import json
import os
from traitlets import Unicode

from tornado.web import StaticFileHandler

HERE = os.path.dirname(__file__)
HERE = os.path.abspath(os.path.dirname(__file__))

# Turn off the Jupyter configuration system so configuration files on disk do
# not affect this app. This helps this app to truly be standalone.
Expand All @@ -24,10 +25,24 @@ class SettingHandler(APIHandler):

def get(self, schema_name=""):
path = os.path.join(HERE, 'node_modules/@jupyterlab/markdownviewer-extension/schema/plugin.json')

with open(path) as fid:
data = fid.read()
return self.finish(data)
schema = fid.read()

# copy-pasta of typical response for now.
result = {"id":"@jupyterlab/markdownviewer-extension:plugin","raw":"{}","schema":{"jupyter.lab.setting-icon":"ui-components:markdown","jupyter.lab.setting-icon-label":"Markdown Viewer","title":"Markdown Viewer","description":"Markdown viewer settings.","definitions":{"fontFamily":{"type":["string","null"]},"fontSize":{"type":["integer","null"],"minimum":1,"maximum":100},"lineHeight":{"type":["number","null"]},"lineWidth":{"type":["number","null"]},"hideFrontMatter":{"type":"boolean"},"renderTimeout":{"type":"number"}},"properties":{"fontFamily":{"title":"Font Family","description":"The font family used to render markdown.\nIf `null`, value from current theme is used.","$ref":"#/definitions/fontFamily","default":None},"fontSize":{"title":"Font Size","description":"The size in pixel of the font used to render markdown.\nIf `null`, value from current theme is used.","$ref":"#/definitions/fontSize","default":None},"lineHeight":{"title":"Line Height","description":"The line height used to render markdown.\nIf `null`, value from current theme is used.","$ref":"#/definitions/lineHeight","default":None},"lineWidth":{"title":"Line Width","description":"The text line width expressed in CSS ch units.\nIf `null`, lines fit the viewport width.","$ref":"#/definitions/lineWidth","default":None},"hideFrontMatter":{"title":"Hide Front Matter","description":"Whether to hide YAML front matter.\nThe YAML front matter must be placed at the top of the document,\nstarted by a line of three dashes (---) and ended by a line of\nthree dashes (---) or three points (...).","$ref":"#/definitions/hideFrontMatter","default":True},"renderTimeout":{"title":"Render Timeout","description":"The render timeout in milliseconds.","$ref":"#/definitions/renderTimeout","default":1000}},"additionalProperties":False,"type":"object"},"settings":{},"version":"2.2.0"}

return self.finish(result)


class ExtensionHandler(FileFindHandler):

def get(self, path):
extname, _, rest = path.partition('/')
dirname = 'md_package' if extname == 'example-federated-md' else 'middle_package'
path = os.path.join(dirname, 'build', rest)
return super().get(path)


class ExampleApp(LabServerApp):
base_url = '/foo'
Expand All @@ -53,11 +68,9 @@ def init_webapp(self):
# Handle md ext assets
web_app = self.web_app
base_url = web_app.settings['base_url']
static_path = ujoin(base_url, 'example', 'labextensions', '@jupyterlab', 'example-federated-md', '(.*)')
static_dir = os.path.join(HERE, 'md_package', 'build')
web_app.add_handlers('.*$', [(static_path, FileFindHandler, {
'path': static_dir,
})])

static_path = ujoin(base_url, 'example', 'labextensions', '@jupyterlab', '(.*)')
web_app.add_handlers('.*$', [(static_path, ExtensionHandler, { 'path': HERE })])

## Handle the specific setting
static_path = ujoin(base_url, 'example', 'api', 'settings', '@jupyterlab', '(.*)')
Expand Down
3 changes: 2 additions & 1 deletion md_package/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion md_package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@jupyterlab/application": "^3.0.0-alpha.4",
"@jupyterlab/apputils": "^3.0.0-alpha.4",
"@jupyterlab/coreutils": "^5.0.0-alpha.4",
"@jupyterlab/example-federated-middle": "~2.1.0",
"@jupyterlab/markdownviewer": "^3.0.0-alpha.4",
"@jupyterlab/rendermime": "^3.0.0-alpha.4",
"@jupyterlab/settingregistry": "^3.0.0-alpha.4"
Expand All @@ -24,6 +25,7 @@
},
"jupyterlab": {
"extension": true,
"schemaDir": "schema"
"schemaDir": "schema",
"singletonPackages": ["@jupyterlab/example-federated-middle"]
}
}
12 changes: 12 additions & 0 deletions middle_package/extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const IMiddleToken = require('./index').IMiddleToken;

module.exports = [{
id: '@jupyterlab/example-federated-middle',
autoStart: true,
provides: IMiddleToken,
activate: function (app) {
console.log('JupyterLab extension middle is activated!');
console.log(app.commands);
return 'hello';
}
}];
11 changes: 11 additions & 0 deletions middle_package/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions middle_package/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@jupyterlab/example-federated-middle",
"version": "2.1.0",
"private": true,
"scripts": {
"prepublishOnly": "npm run build",
"watch": "npm run clean && webpack --watch"
},
"dependencies": {
"@jupyterlab/coreutils": "^5.0.0-alpha.4"
},
"devDependencies": {
"rimraf": "~3.0.0",
"typedoc": "^0.17.7",
"typescript": "~3.9.2"
},
"publishConfig": {
"access": "public"
},
"jupyterlab": {
"extension": "./extension.js",
"schemaDir": "schema"
}
}
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"version": "2.1.0",
"private": true,
"scripts": {
"build": "npm run build:core && npm run build:ext",
"build": "npm run build:core && npm run build:middle && npm run build:md",
"build:core": "cd core_package && npm run build",
"build:ext": "node build-ext.js ./md_package",
"build:middle": "node build-ext.js ./middle_package",
"build:md": "node build-ext.js ./md_package",
"clean:core": "cd core_package && npm run clean",
"clean:ext": "rimraf md_package/build",
"clean": "npm run clean:ext && npm run clean:core"
"clean:md": "rimraf md_package/build",
"clean:middle": "rimraf middle_package/build",
"clean": "npm run clean:md && npm run clean:middle && npm run clean:core"
},
"devDependencies": {
"rimraf": "^3.0.2",
Expand Down
3 changes: 2 additions & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

<!-- This data should be gathered by the server and templated here or as part of the page config -->
<script id="jupyterlab-plugin-data" type="application/json">
[{"path":"example/labextensions/@jupyterlab/example-federated-md/remoteEntry.js","name":"@jupyterlab/example-federated-md","module":"./index"}]
[{"path":"example/labextensions/@jupyterlab/example-federated-md/remoteEntry.js","name":"@jupyterlab/example-federated-md","module":"./extension"},
{"path": "example/labextensions/@jupyterlab/example-federated-middle/remoteEntry.js","name":"@jupyterlab/example-federated-middle","module":"./extension"}]
</script>

<script src="{{page_config['fullStaticUrl'] | e}}/bundle.js"></script>
Expand Down
39 changes: 22 additions & 17 deletions webpack.config.ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,17 @@ const extras = Build.ensureAssets({
output: outputPath
});

let entryPoint = data.jupyterlab.extension ?? data.jupyterlab.mimeExtension;

if (entryPoint === true) {
// Use require to get the entry point
entryPoint = require.resolve(packagePath);
} else {
// Use the path to get the entry point
entryPoint = path.join(packagePath, entryPoint);
}
// Handle the extension entry point and the lib entry point, if different
let extPath = data.jupyterlab.extension ?? data.jupyterlab.mimeExtension;
const index = require.resolve(packagePath);
const exposes = {
'./index': index,
'./extension': index
}

if (extPath !== true) {
exposes['./extension'] = path.join(packagePath, extPath);
}

const coreData = require('./core_package/package.json');

Expand All @@ -97,7 +99,7 @@ Object.keys(data.dependencies).forEach((element) => {
// Remove non-shared.
data.jupyterlab.nonSharedPackages?.forEach((element) => {
delete shared[element];
});
});

// Start with core singletons.
coreData.jupyterlab.singletonPackages.forEach((element) => {
Expand All @@ -113,7 +115,7 @@ data.jupyterlab.singletonPackages?.forEach((element) => {
if (!shared[element]) {
shared[element] = {};
}
shared[element].singleton = true;
shared[element].import = false;
});

// Remove non-singletons.
Expand All @@ -126,6 +128,12 @@ data.jupyterlab.nonSingletonPackages?.forEach((element) => {

// Ensure a clean output directory.
fs.rmdirSync(outputPath, { recursive: true });
fs.mkdirSync(outputPath);

// Make a bootstrap entrypoint
const entryPoint = path.join(outputPath, 'bootstrap.js');
const bootstrap = 'import("' + exposes['./extension'] + '");'
fs.writeFileSync(entryPoint, bootstrap);

module.exports = [
{
Expand All @@ -146,9 +154,7 @@ module.exports = [
name: ['_JUPYTERLAB', data.name]
},
filename: 'remoteEntry.js',
exposes: {
'./index': entryPoint
},
exposes,
shared,
}),
new webpack.DefinePlugin({
Expand All @@ -159,6 +165,5 @@ module.exports = [
}
].concat(extras);

// TODO: remove debug log
// console.log(module.exports);
fs.writeFileSync('log.json', JSON.stringify(module.exports, null, ' '));
const logPath = path.join(outputPath, 'build_log.json');
fs.writeFileSync(logPath, JSON.stringify(module.exports, null, ' '));