Browse Source

Disambiguate between outputDir and buildDir for the federated example.

Jason Grout 4 years ago
parent
commit
72567b896c

+ 1 - 0
examples/federated/.gitignore

@@ -1,4 +1,5 @@
 stats.json
 node_modules
 core_package/build
+core_package/static
 labextensions/

+ 1 - 1
examples/federated/core_package/package.json

@@ -175,7 +175,7 @@
   },
   "jupyterlab": {
     "buildDir": "./build",
-    "outputDir": "./build",
+    "outputDir": "./static",
     "singletonPackages": [
       "@jupyterlab/application",
       "@jupyterlab/apputils",

+ 86 - 76
examples/federated/core_package/webpack.config.js

@@ -15,12 +15,6 @@ const packageData = require('./package.json');
 // Handle the extensions.
 const jlab = packageData.jupyterlab;
 
-const singletons = {};
-
-jlab.singletonPackages.forEach(element => {
-  singletons[element] = { singleton: true };
-});
-
 // Create a list of application extensions and mime extensions from
 // jlab.extensions
 const extensions = {};
@@ -48,12 +42,22 @@ if (fs.existsSync(buildDir)) {
 fs.ensureDirSync(buildDir);
 
 const outputDir = path.resolve(jlab.outputDir);
+if (fs.existsSync(outputDir)) {
+  fs.removeSync(outputDir);
+}
+fs.ensureDirSync(outputDir);
 
 // Configuration to handle extension assets
 const extensionAssetConfig = Build.ensureAssets({
   packageNames: extensionPackages,
   output: outputDir
 });
+if (outputDir !== buildDir) {
+  fs.moveSync(
+    path.join(outputDir, 'style.js'),
+    path.join(buildDir, 'style.js')
+  )
+}
 
 // Create the entry point and other assets in build directory.
 const source = fs.readFileSync('index.template.js').toString();
@@ -70,94 +74,100 @@ fs.writeFileSync(path.join(buildDir, 'index.js'), template(extData));
 const entryPoint = path.join(buildDir, 'bootstrap.js');
 fs.copySync('./bootstrap.js', entryPoint);
 
-// Set up module federation sharing config
-const shared = {};
 
-// Make sure any resolutions are shared
-for (let [pkg, requiredVersion] of Object.entries(packageData.resolutions)) {
-  shared[pkg] = { requiredVersion };
-}
+function createShared(packageData) {
+  // Set up module federation sharing config
+  const shared = {};
+  const extensionPackages = packageData.jupyterlab.extensions;
 
-// Add any extension packages that are not in resolutions (i.e., installed from npm)
-for (let pkg of extensionPackages) {
-  if (!shared[pkg]) {
-    shared[pkg] = {
-      requiredVersion: require(`${pkg}/package.json`).version
-    };
+  // Make sure any resolutions are shared
+  for (let [pkg, requiredVersion] of Object.entries(packageData.resolutions)) {
+    shared[pkg] = { requiredVersion };
   }
-}
 
-// Add dependencies and sharedPackage config from extension packages if they
-// are not already in the shared config. This means that if there is a
-// conflict, the resolutions package version is the one that is shared.
-const extraShared = [];
-for (let pkg of extensionPackages) {
-  let pkgShared = {};
-  let {
-    dependencies = {},
-    jupyterlab: { sharedPackages = {} } = {}
-  } = require(`${pkg}/package.json`);
-  for (let [dep, requiredVersion] of Object.entries(dependencies)) {
-    if (!shared[dep]) {
-      pkgShared[dep] = { requiredVersion };
+  // Add any extension packages that are not in resolutions (i.e., installed from npm)
+  for (let pkg of extensionPackages) {
+    if (!shared[pkg]) {
+      shared[pkg] = {
+        requiredVersion: require(`${pkg}/package.json`).version
+      };
     }
   }
 
-  // Overwrite automatic dependency sharing with custom sharing config
-  for (let [dep, config] of Object.entries(sharedPackages)) {
-    if (config === false) {
-      delete pkgShared[dep];
-    } else {
-      if ('bundled' in config) {
-        config.import = config.bundled;
-        delete config.bundled;
+  // Add dependencies and sharedPackage config from extension packages if they
+  // are not already in the shared config. This means that if there is a
+  // conflict, the resolutions package version is the one that is shared.
+  const extraShared = [];
+  for (let pkg of extensionPackages) {
+    let pkgShared = {};
+    let {
+      dependencies = {},
+      jupyterlab: { sharedPackages = {} } = {}
+    } = require(`${pkg}/package.json`);
+    for (let [dep, requiredVersion] of Object.entries(dependencies)) {
+      if (!shared[dep]) {
+        pkgShared[dep] = { requiredVersion };
       }
-      pkgShared[dep] = config;
     }
-  }
-  extraShared.push(pkgShared);
-}
 
-// Now merge the extra shared config
-const mergedShare = {};
-for (let sharedConfig of extraShared) {
-  for (let [pkg, config] of Object.entries(sharedConfig)) {
-    // Do not override the basic share config from resolutions
-    if (shared[pkg]) {
-      continue;
+    // Overwrite automatic dependency sharing with custom sharing config
+    for (let [dep, config] of Object.entries(sharedPackages)) {
+      if (config === false) {
+        delete pkgShared[dep];
+      } else {
+        if ('bundled' in config) {
+          config.import = config.bundled;
+          delete config.bundled;
+        }
+        pkgShared[dep] = config;
+      }
     }
+    extraShared.push(pkgShared);
+  }
 
-    // Add if we haven't seen the config before
-    if (!mergedShare[pkg]) {
-      mergedShare[pkg] = config;
-      continue;
-    }
+  // Now merge the extra shared config
+  const mergedShare = {};
+  for (let sharedConfig of extraShared) {
+    for (let [pkg, config] of Object.entries(sharedConfig)) {
+      // Do not override the basic share config from resolutions
+      if (shared[pkg]) {
+        continue;
+      }
 
-    // Choose between the existing config and this new config. We do not try
-    // to merge configs, which may yield a config no one wants
-    let oldConfig = mergedShare[pkg];
+      // Add if we haven't seen the config before
+      if (!mergedShare[pkg]) {
+        mergedShare[pkg] = config;
+        continue;
+      }
+
+      // Choose between the existing config and this new config. We do not try
+      // to merge configs, which may yield a config no one wants
+      let oldConfig = mergedShare[pkg];
 
-    // if the old one has import: false, use the new one
-    if (oldConfig.import === false) {
-      mergedShare[pkg] = config;
+      // if the old one has import: false, use the new one
+      if (oldConfig.import === false) {
+        mergedShare[pkg] = config;
+      }
     }
   }
-}
 
-Object.assign(shared, mergedShare);
+  Object.assign(shared, mergedShare);
 
-// Transform any file:// requiredVersion to the version number from the
-// imported package. This assumes (for simplicity) that the version we get
-// importing was installed from the file.
-for (let [pkg, { requiredVersion }] of Object.entries(shared)) {
-  if (requiredVersion && requiredVersion.startsWith('file:')) {
-    shared[pkg].requiredVersion = require(`${pkg}/package.json`).version;
+  // Transform any file:// requiredVersion to the version number from the
+  // imported package. This assumes (for simplicity) that the version we get
+  // importing was installed from the file.
+  for (let [pkg, { requiredVersion }] of Object.entries(shared)) {
+    if (requiredVersion && requiredVersion.startsWith('file:')) {
+      shared[pkg].requiredVersion = require(`${pkg}/package.json`).version;
+    }
+  }
+
+  // Add singleton package information
+  for (let pkg of packageData.jupyterlab.singletonPackages) {
+    shared[pkg].singleton = true;
   }
-}
 
-// Add singleton package information
-for (let pkg of jlab.singletonPackages) {
-  shared[pkg].singleton = true;
+  return shared;
 }
 
 const plugins = [
@@ -167,7 +177,7 @@ const plugins = [
       name: ['_JUPYTERLAB', 'CORE_LIBRARY_FEDERATION']
     },
     name: 'CORE_FEDERATION',
-    shared
+    shared: createShared(packageData)
   })
 ];
 
@@ -177,7 +187,7 @@ module.exports = [
     devtool: 'source-map',
     entry: ['./publicpath.js', entryPoint],
     output: {
-      path: path.resolve(buildDir),
+      path: path.resolve(outputDir),
       library: {
         type: 'var',
         name: ['_JUPYTERLAB', 'CORE_OUTPUT']

+ 6 - 6
examples/federated/main.py

@@ -28,14 +28,14 @@ class ExamplePrebuiltApp(LabServerApp):
     name = 'lab'
     load_other_extensions = False
     app_name = 'JupyterLab Example App with Prebuilt Extensions'
-    app_settings_dir = os.path.join(HERE, 'build', 'application_settings')
+    app_settings_dir = os.path.join(HERE, 'core_package', 'static', 'application_settings')
     app_version = version
-    schemas_dir = os.path.join(HERE, 'core_package', 'build', 'schemas')
-    static_dir = os.path.join(HERE, 'core_package', 'build')
+    schemas_dir = os.path.join(HERE, 'core_package', 'static', 'schemas')
+    static_dir = os.path.join(HERE, 'core_package', 'static')
     templates_dir = os.path.join(HERE, 'templates')
-    themes_dir = os.path.join(HERE, 'core_package', 'build', 'themes')
-    user_settings_dir = os.path.join(HERE, 'core_package', 'build', 'user_settings')
-    workspaces_dir = os.path.join(HERE, 'core_package', 'build', 'workspaces')
+    themes_dir = os.path.join(HERE, 'core_package', 'static', 'themes')
+    user_settings_dir = os.path.join(HERE, 'core_package', 'static', 'user_settings')
+    workspaces_dir = os.path.join(HERE, 'core_package', 'static', 'workspaces')
 
     # Set the location for prebuilt extensions, overriding the default
     # of looking in each of the Jupyter data paths.