├── .gitignore ├── HelloWorld.png ├── README.md ├── package.json ├── src ├── Hello.vue ├── index.ts └── vue-shim.d.ts ├── tsconfig.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.bundle.* 2 | lib/ 3 | node_modules/ 4 | .ipynb_checkpoints 5 | yarn.lock 6 | tsconfig.tsbuildinfo 7 | -------------------------------------------------------------------------------- /HelloWorld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studyhub-co/jupyterlab_vue/c4b2b520ca36887ad8f204c8caf208549c36cab5/HelloWorld.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JupyterLab Hello World Vue.js extension 2 | 3 | Shows "Hello World" 4 | 5 | ![JupyterLab Hello World Vue.js](HelloWorld.png "JupyterLab Hello World Vue.js extension") 6 | 7 | ## Prerequisites 8 | 9 | * JupyterLab 10 | 11 | 12 | ## Development 13 | 14 | For a development install (requires npm version 4 or later), do the following in the repository directory: 15 | 16 | ```bash 17 | npm install 18 | npm run build 19 | jupyter labextension link . 20 | ``` 21 | 22 | To rebuild the package and the JupyterLab app: 23 | 24 | ```bash 25 | npm run build 26 | jupyter lab build 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@jupyterlab/jupyterlab_vue", 3 | "version": "0.1.0", 4 | "description": "JupyterLab extension using Vue.js", 5 | "keywords": [ 6 | "jupyter", 7 | "jupyterlab", 8 | "jupyterlab-extension" 9 | ], 10 | "homepage": "https://github.com/nscozzaro/jupyterlab_vue", 11 | "bugs": { 12 | "url": "https://github.com/nscozzaro/jupyterlab_vue/issues" 13 | }, 14 | "license": "BSD-3-Clause", 15 | "author": "Nic Scozzaro", 16 | "main": "lib/index.js", 17 | "types": "lib/index.d.ts", 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/nscozzaro/jupyterlab_vue.git" 21 | }, 22 | "scripts": { 23 | "build": "webpack", 24 | "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo", 25 | "prepare": "npm run clean && npm run build" 26 | }, 27 | "dependencies": { 28 | "@babel/core": "^7.5.5", 29 | "@babel/preset-env": "^7.5.5", 30 | "@jupyterlab/application": "^1.0.0-rc.0", 31 | "@jupyterlab/apputils": "^1.0.0-rc.0", 32 | "@phosphor/messaging": "^1.2.3", 33 | "@phosphor/widgets": "^1.8.1", 34 | "autoprefixer": "^9.6.1", 35 | "babel-loader": "^8.0.6", 36 | "css-loader": "^3.1.0", 37 | "postcss-loader": "^3.0.0", 38 | "rimraf": "^2.6.1", 39 | "sass-loader": "^7.1.0", 40 | "style-loader": "^0.23.1", 41 | "ts-loader": "^6.0.4", 42 | "typescript": "~3.5.2", 43 | "vue": "^2.6.10", 44 | "vue-loader": "^15.7.1", 45 | "vue-template-compiler": "^2.6.10", 46 | "webpack": "^4.36.1", 47 | "webpack-cli": "^3.3.6", 48 | "webpack-node-externals": "^1.7.2" 49 | }, 50 | "jupyterlab": { 51 | "extension": true 52 | }, 53 | "postcss": { 54 | "plugins": { 55 | "autoprefixer": {} 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Hello.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | 15 | 21 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import {ILayoutRestorer, JupyterFrontEnd, JupyterFrontEndPlugin} from '@jupyterlab/application'; 2 | import {ICommandPalette, MainAreaWidget, WidgetTracker} from '@jupyterlab/apputils'; 3 | import {Message} from '@phosphor/messaging'; 4 | import {Widget} from '@phosphor/widgets'; 5 | import Vue from 'vue'; 6 | import Hello from './Hello.vue' 7 | 8 | 9 | class HelloVue extends Widget { 10 | /** 11 | * Construct a new HelloVue widget. 12 | */ 13 | constructor() { 14 | super(); 15 | } 16 | 17 | /** 18 | * Handle update requests for the widget. 19 | */ 20 | async onUpdateRequest(msg: Message): Promise { 21 | new Vue({ 22 | el: this.node, 23 | render: h => h(Hello) 24 | }) 25 | } 26 | } 27 | 28 | 29 | /** 30 | * Activate the HelloVue widget extension. 31 | */ 32 | function activate(app: JupyterFrontEnd, palette: ICommandPalette, restorer: ILayoutRestorer) { 33 | console.log('JupyterLab extension jupyterlab_vue is activated!'); 34 | 35 | // Declare a widget variable 36 | let widget: MainAreaWidget; 37 | 38 | // Add an application command 39 | const command: string = 'vue:open'; 40 | app.commands.addCommand(command, { 41 | label: 'Hello World Vue.js', 42 | execute: () => { 43 | if (!widget) { 44 | // Create a new widget if one does not exist 45 | const content = new HelloVue(); 46 | widget = new MainAreaWidget({content}); 47 | widget.id = 'vue-jupyterlab'; 48 | widget.title.label = 'Hello World Vue.js'; 49 | widget.title.closable = true; 50 | } 51 | if (!tracker.has(widget)) { 52 | // Track the state of the widget for later restoration 53 | tracker.add(widget); 54 | } 55 | if (!widget.isAttached) { 56 | // Attach the widget to the main work area if it's not there 57 | app.shell.add(widget, 'main'); 58 | } 59 | widget.content.update(); 60 | 61 | // Activate the widget 62 | app.shell.activateById(widget.id); 63 | } 64 | }); 65 | 66 | // Add the command to the palette. 67 | palette.addItem({command, category: 'Hello World Vue.js'}); 68 | 69 | // Track and restore the widget state 70 | let tracker = new WidgetTracker>({ 71 | namespace: 'vue' 72 | }); 73 | restorer.restore(tracker, { 74 | command, 75 | name: () => 'vue' 76 | }); 77 | } 78 | 79 | /** 80 | * Initialization data for the jupyterlab_vue extension. 81 | */ 82 | const extension: JupyterFrontEndPlugin = { 83 | id: 'jupyterlab_vue', 84 | autoStart: true, 85 | requires: [ICommandPalette, ILayoutRestorer], 86 | activate: activate 87 | }; 88 | 89 | export default extension; 90 | -------------------------------------------------------------------------------- /src/vue-shim.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import Vue from "vue"; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "composite": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "incremental": true, 8 | "jsx": "react", 9 | "module": "esnext", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noImplicitAny": true, 13 | "noUnusedLocals": true, 14 | "preserveWatchOutput": true, 15 | "resolveJsonModule": true, 16 | "outDir": "lib", 17 | "rootDir": "src", 18 | "strict": true, 19 | "strictNullChecks": false, 20 | "target": "es2017", 21 | "types": [] 22 | }, 23 | "include": ["src/*"] 24 | } 25 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const nodeExternals = require('webpack-node-externals'); 3 | const VueLoaderPlugin = require('vue-loader/lib/plugin') 4 | 5 | 6 | module.exports = { 7 | entry: ['./src/index.ts'], 8 | target: 'node', 9 | externals: [nodeExternals()], 10 | output: { 11 | path: path.resolve(__dirname, 'lib'), 12 | filename: 'index.js', 13 | libraryTarget: 'commonjs-module' 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.tsx?$/, 19 | use: 'ts-loader', 20 | exclude: /node_modules/ 21 | }, 22 | { 23 | test: /\.vue$/, 24 | loader: 'vue-loader', 25 | options: { 26 | optimizeSSR: false 27 | } 28 | }, 29 | // this will apply to both plain `.js` files 30 | // AND `