Skip to content

Commit 69b4325

Browse files
fixed library target for nbclassic nbextension for graph_notebook_widget (#739)
1 parent cff1643 commit 69b4325

File tree

4 files changed

+25
-8
lines changed

4 files changed

+25
-8
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ dependencies = [
3939
'nbclient>=0.7.3',
4040
'nbconvert>=6.3.0,<=7.2.8',
4141
'notebook>=7.0.0,<8.0.0',
42-
'nbclassic>=1.0.0',
42+
'nbclassic>=1.3.0',
4343

4444
# Data processing and visualization
4545
'itables>=2.0.0,<=2.1.0',

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jupyterlab-widgets>=3.0.0,<4.0.0
1111
nbclient>=0.7.3
1212
nbconvert>=6.3.0,<=7.2.8
1313
notebook>=7.0.0,<8.0.0
14-
nbclassic>=1.0.0
14+
nbclassic>=1.3.0
1515

1616
# Data processing and visualization
1717
itables>=2.0.0,<=2.1.0

src/graph_notebook/start_notebook.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def main():
7171
# Starting with Notebook 7.0+, the classic notebook interface was rewritten to use JupyterLab's architecture.
7272
# This means traditional nbextensions (which rely on requirejs and jQuery) are not directly supported.
7373
# We use nbclassic package to maintain compatibility
74+
# Reference: https://jupyter-notebook.readthedocs.io/en/latest/migrating/multiple-interfaces.html#simultaneous-usage-of-different-versions-of-notebook-7-and-the-classic-notebook-ui
7475
kernel_manager_option = "--NotebookApp.kernel_manager_class=notebook.services.kernels.kernelmanager.AsyncMappingKernelManager"
7576
notebooks_dir = '~/notebook/destination/dir' if args.notebooks_dir == '' else args.notebooks_dir
7677
os.system(f'''jupyter nbclassic {kernel_manager_option} {notebooks_dir}''')

src/graph_notebook/widgets/webpack.config.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,17 @@ const labModuleFederationConfig = {
8585

8686
// Export array of webpack configurations
8787
module.exports = [
88-
// 1. Notebook extension AMD module
88+
// 1. Notebook extension AMD module - Used by NBClassic (Jupyter Notebook < 7.0)
8989
{
9090
mode,
9191
entry: "./src/extension.js",
9292
output: {
9393
filename: "extension.js",
9494
path: path.resolve(__dirname, "nbextension"),
95-
libraryTarget: "amd",
95+
// libraryTarget: "var" exposes the library by creating a global variable
96+
// Example: var graph_notebook_widgets = { ... }
97+
// This is the classic way NBClassic loads extensions through RequireJS
98+
libraryTarget: "var",
9699
library: "graph_notebook_widgets",
97100
publicPath: "nbextensions/graph_notebook_widgets/",
98101
},
@@ -104,15 +107,22 @@ module.exports = [
104107
watchOptions,
105108
},
106109

107-
// 2. Notebook extension
110+
// 2. Notebook extension - Used by NBClassic (Jupyter Notebook < 7.0)
108111
{
109112
mode,
110113
entry: "./src/extension.ts",
111114
output: {
112115
filename: "index.js",
113116
path: path.resolve(__dirname, "nbextension"),
117+
// libraryTarget: "amd" creates an AMD module that can be loaded by RequireJS
118+
// AMD (Asynchronous Module Definition) allows modules to be loaded asynchronously
119+
// Example: define(['dependency'], function(dependency) { ... })
120+
// NBClassic uses RequireJS to load extensions in this format
114121
libraryTarget: "amd",
115-
library: "graph_notebook_widgets",
122+
// This creates a "named define" module without a global variable
123+
// It allows the module to be imported by name in RequireJS
124+
// Example: define('graph_notebook_widgets', ['dependency'], function(dependency) { ... })
125+
library: undefined,
116126
publicPath: "nbextensions/graph_notebook_widgets/",
117127
},
118128
module: { rules },
@@ -123,7 +133,7 @@ module.exports = [
123133
watchOptions,
124134
},
125135

126-
// 3. Lab extension with Module Federation
136+
// 3. Lab extension with Module Federation - Used by JupyterLab 4.x and Notebook 7+
127137
{
128138
mode,
129139
entry: "./src/index.ts",
@@ -132,6 +142,9 @@ module.exports = [
132142
chunkFilename: '[name].[contenthash].js',
133143
path: path.resolve(__dirname, 'labextension/static'),
134144
publicPath: 'static/',
145+
// AMD format is used as the base format for JupyterLab extensions
146+
// Module Federation builds on top of this to enable dynamic loading
147+
// This configuration creates a JupyterLab 4.x compatible extension
135148
libraryTarget: 'amd'
136149
},
137150
devtool: "source-map",
@@ -143,18 +156,21 @@ module.exports = [
143156
resolve,
144157
plugins: [
145158
...basePlugins,
159+
// ModuleFederationPlugin enables the extension to be loaded dynamically
160+
// by JupyterLab 4.x and Notebook 7+ which both use this architecture
146161
new ModuleFederationPlugin(labModuleFederationConfig),
147162
],
148163
watchOptions
149164
},
150165

151-
// 4. Documentation widget bundle
166+
// 4. Documentation widget bundle - Used for documentation examples
152167
{
153168
mode,
154169
entry: "./src/index.ts",
155170
output: {
156171
filename: "embed-bundle.js",
157172
path: path.resolve(__dirname, "docs", "source", "_static"),
173+
// AMD format used for documentation examples to match JupyterLab format
158174
libraryTarget: "amd",
159175
},
160176
module: { rules },

0 commit comments

Comments
 (0)