|
@@ -1,261 +0,0 @@
|
|
|
-// Copyright (c) Jupyter Development Team.
|
|
|
-// Distributed under the terms of the Modified BSD License.
|
|
|
-
|
|
|
-var path = require('path');
|
|
|
-var walkSync = require('walk-sync');
|
|
|
-
|
|
|
-/**
|
|
|
- Helper scripts to be used by extension authors (and extension extenders) in a
|
|
|
- webpack.config.json to create builds that do not include upstream extensions.
|
|
|
-
|
|
|
- Inspects the package.json of the user's package and those of its dependencies
|
|
|
- to find extensions that should be excluded.
|
|
|
-
|
|
|
- Slightly more than minimal valid setup in package.json:
|
|
|
-
|
|
|
- {
|
|
|
- "name": "foo-widget",
|
|
|
- "jupyter": {
|
|
|
- "lab": {
|
|
|
- "main": "lab-extension.js"
|
|
|
- }
|
|
|
- },
|
|
|
- "dependencies": {
|
|
|
- "jupyterlab": "*",
|
|
|
- "jupyter-js-widgets": "*"
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Example usage in webpack.config.js:
|
|
|
-
|
|
|
- var jlab_helpers = require('jupyterlab/scripts/extension_helpers');
|
|
|
-
|
|
|
- module.exports = [{
|
|
|
- entry: './src/lab/extension.js',
|
|
|
- output: {
|
|
|
- filename: 'lab-extension.js',
|
|
|
- path: '../pythonpkg/static',
|
|
|
- libraryTarget: 'this'
|
|
|
- },
|
|
|
- externals: jlab_helpers.upstreamExternals(require)
|
|
|
- }];
|
|
|
-*/
|
|
|
-
|
|
|
-/**
|
|
|
- * Determine if a string starts with another.
|
|
|
- *
|
|
|
- * @param str (string) - the string possibly starting with the substring.
|
|
|
- *
|
|
|
- * @param query (string) - the substring whose presence we are testing.
|
|
|
- *
|
|
|
- * @returns true if str starts with query
|
|
|
- *
|
|
|
- * #### Notes
|
|
|
- * This is a cross-browser version of String.prototype.startsWith
|
|
|
- */
|
|
|
-function startsWith(str, query) {
|
|
|
- return str.lastIndexOf(query, 0) === 0;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Create a Webpack `externals` function for a shimmed external package.
|
|
|
- *
|
|
|
- * @param pkgName (string) - The name of the package
|
|
|
- *
|
|
|
- * @returns A function to be used as part of a WebPack config.
|
|
|
- */
|
|
|
-function createShimHandler(pkgName) {
|
|
|
- return function(context, request, callback) {
|
|
|
- // TODO: better path regex, probably only looking for .js or .css
|
|
|
- // since that is all we save
|
|
|
- if (startsWith(request, pkgName)) {
|
|
|
- try {
|
|
|
- var path = require.resolve(request);
|
|
|
- } catch (err) {
|
|
|
- return callback(err);
|
|
|
- }
|
|
|
- var index = path.indexOf(request);
|
|
|
- path = path.slice(index + pkgName.length);
|
|
|
- if (path.indexOf('/') === 0) {
|
|
|
- path = path.slice(1);
|
|
|
- }
|
|
|
- var shim = 'var jupyter.externals["' + pkgName + '"]["' + path + '"]';
|
|
|
- return callback(null, shim);
|
|
|
- }
|
|
|
- callback();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Create a shim to export all of a library's modules to a namespaced object.
|
|
|
- *
|
|
|
- * @param modName (string) - The name of the module to shim.
|
|
|
- *
|
|
|
- * @param sourceFolder (string) - The source folder (defaults to `lib`).
|
|
|
- *
|
|
|
- * @returns The code used to export the entire package.
|
|
|
- */
|
|
|
-function createShim(modName, sourceFolder) {
|
|
|
- var dirs = [];
|
|
|
- var files = [];
|
|
|
- var lines = ['var shim = {};'];
|
|
|
-
|
|
|
- // Find the path to the module.
|
|
|
- var modPath = require.resolve(modName + '/package.json');
|
|
|
- sourceFolder = sourceFolder || 'lib';
|
|
|
- modPath = path.posix.join(path.dirname(modPath), sourceFolder);
|
|
|
-
|
|
|
- // Walk through the source tree.
|
|
|
- var entries = walkSync.entries(modPath, {
|
|
|
- directories: false,
|
|
|
- globs: ['**/*.js', '**/*.css']
|
|
|
- });
|
|
|
- for (var i = 0; i < entries.length; i++) {
|
|
|
- // Get the relative path to the entry.
|
|
|
- var entryPath = path.posix.join(sourceFolder, entries[i].relativePath);
|
|
|
- // Add an entries for each file.
|
|
|
- lines.push('shim["' + entryPath + '"] = require("' + path.posix.join(modName, entryPath) + '");');
|
|
|
- }
|
|
|
- lines.push('module.exports = shim;');
|
|
|
-
|
|
|
- return lines.join('\n');
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Determine whether a package is a JupyterLab extension.
|
|
|
- *
|
|
|
- * @param pkg (string) - The package.json object.
|
|
|
- *
|
|
|
- * @returns true if the package is a JupyterLab extension.
|
|
|
- */
|
|
|
-function isLabExtension(pkg){
|
|
|
- try {
|
|
|
- // for now, just try to load the key... could check whether file exists?
|
|
|
- pkg['jupyter']['lab']['main']
|
|
|
- return true;
|
|
|
- } catch(err) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Recurse through dependencies, collecting all external functions.
|
|
|
- *
|
|
|
- * @param function - the environment require function.
|
|
|
- *
|
|
|
- * @param onlyUpstream - if true, do not return externals provided by this package
|
|
|
- *
|
|
|
- * @returns an externals object to be used in a Webpack config.
|
|
|
- *
|
|
|
- * #### Notes
|
|
|
- * A sample Webpack config will look like
|
|
|
- *
|
|
|
- var jlab_helpers = require('jupyterlab/scripts/extension_helpers');
|
|
|
-
|
|
|
- module.exports = [{
|
|
|
- entry: './src/lab/extension.js',
|
|
|
- output: {
|
|
|
- filename: 'lab-extension.js',
|
|
|
- path: '../pythonpkg/static',
|
|
|
- libraryTarget: 'this'
|
|
|
- },
|
|
|
- externals: jlab_helpers.upstreamExternals(require)
|
|
|
- }];
|
|
|
- */
|
|
|
-function upstreamExternals(_require, onlyUpstream) {
|
|
|
- // Parse the externals of this package.
|
|
|
-
|
|
|
- // remember which packages we have seen
|
|
|
- var _seen = {};
|
|
|
-
|
|
|
- /**
|
|
|
- * Load the externals from a JupyterLab extension package.
|
|
|
- *
|
|
|
- * @param pkg_path (string) - the path on the filesystem to the package.
|
|
|
- *
|
|
|
- * @param pkg (object) - the package.json object.
|
|
|
- *
|
|
|
- * @returns an array containing the externals this package provides, excluding itself.
|
|
|
- *
|
|
|
- * #### Notes
|
|
|
- * This returns an array containing the externals referred to in the
|
|
|
- * package.json jupyter.lab.externals object:
|
|
|
- *
|
|
|
- * {module: "module-exporting-externals"}
|
|
|
- *
|
|
|
- * or
|
|
|
- *
|
|
|
- * {module: "module-exporting-externals", name: "exported-object"}
|
|
|
- */
|
|
|
- function _load_externals(pkg_path, pkg) {
|
|
|
- var externals = pkg.jupyter.lab.externals;
|
|
|
- if (externals) {
|
|
|
- try {
|
|
|
- var externalModule = _require(pkg_path + '/' + externals['module']);
|
|
|
- if (externals['name']) {
|
|
|
- pkgExternals = externalModule[externals['name']];
|
|
|
- } else {
|
|
|
- pkgExternals = externalModule;
|
|
|
- }
|
|
|
- } catch (err) {
|
|
|
- console.error('Error importing externals for ' + pkg.name);
|
|
|
- }
|
|
|
- }
|
|
|
- pkgExternals = pkgExternals || [];
|
|
|
- if (!Array.isArray(pkgExternals)) {
|
|
|
- pkgExternals = [pkgExternals];
|
|
|
- }
|
|
|
-
|
|
|
- return pkgExternals;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // return an array of strings, functions or regexen that can be deferenced by
|
|
|
- // webpack `externals` config directive
|
|
|
- // https://webpack.github.io/docs/configuration.html#externals
|
|
|
- function _find_externals(pkg_path, root) {
|
|
|
- var pkg = _require(pkg_path + '/package.json');
|
|
|
- var pkgName = pkg['name'];
|
|
|
- var lab_config;
|
|
|
- var externals = [];
|
|
|
-
|
|
|
- // only visit each named package once
|
|
|
- _seen[pkgName] = true;
|
|
|
-
|
|
|
- if (!isLabExtension(pkg)) {
|
|
|
- return [];
|
|
|
- }
|
|
|
-
|
|
|
- console.info("Inspecting " + pkgName + " for externals it provides...");
|
|
|
-
|
|
|
- if (!(root && onlyUpstream)) {
|
|
|
- externals.push.apply(externals, _load_externals(pkg_path, pkg, _require));
|
|
|
- }
|
|
|
- if (!root) {
|
|
|
- externals.push(createShimHandler(pkg['name']));
|
|
|
- }
|
|
|
-
|
|
|
- // Recurse through the dependencies, and collect externals
|
|
|
- // for JupyterLab extensions
|
|
|
- return Object.keys(pkg['dependencies'])
|
|
|
- .filter(function(depName){ return !_seen[depName]; })
|
|
|
- .reduce(function(externals, depName){
|
|
|
- return externals.concat(
|
|
|
- // We assume the node_modules is flat
|
|
|
- // TODO: actually change directory before doing _find_externals?
|
|
|
- _find_externals(depName));
|
|
|
- }, externals);
|
|
|
- }
|
|
|
-
|
|
|
- var externals = _find_externals(".", true);
|
|
|
- return externals;
|
|
|
-}
|
|
|
-
|
|
|
-module.exports = {
|
|
|
- upstreamExternals: upstreamExternals,
|
|
|
- isLabExtension: isLabExtension,
|
|
|
- createShim: createShim,
|
|
|
- createShimHandler: createShimHandler,
|
|
|
-};
|