Explorar o código

Merge pull request #9312 from jasongrout/optimizebuild

Refactor build conventions
Jeremy Tuloup %!s(int64=4) %!d(string=hai) anos
pai
achega
713430d7b8

+ 0 - 1
dev_mode/package.json

@@ -5,7 +5,6 @@
   "scripts": {
     "build": "jlpm run clean && webpack",
     "build:dev": "jlpm run build",
-    "build:dev:minimize": "jlpm run build:dev",
     "build:prod": "webpack --config webpack.prod.config.js",
     "build:prod:minimize": "webpack --config webpack.prod.minimize.config.js",
     "build:prod:release": "webpack --config webpack.prod.release.config.js",

+ 8 - 3
dev_mode/webpack.config.js

@@ -162,13 +162,18 @@ const shared = {};
 
 // Make sure any resolutions are shared
 for (let [key, requiredVersion] of Object.entries(package_data.resolutions)) {
-  shared[key] = { requiredVersion };
+  // eager so that built-in extensions can be bundled together into just a few
+  // js files to load
+  shared[key] = { requiredVersion, eager: true };
 }
 
 // Add any extension packages that are not in resolutions (i.e., installed from npm)
 for (let pkg of extensionPackages) {
   if (shared[pkg] === undefined) {
-    shared[pkg] = { requiredVersion: require(`${pkg}/package.json`).version };
+    shared[pkg] = {
+      requiredVersion: require(`${pkg}/package.json`).version,
+      eager: true
+    };
   }
 }
 
@@ -184,7 +189,7 @@ for (let pkg of extensionPackages) {
   } = require(`${pkg}/package.json`);
   for (let [dep, requiredVersion] of Object.entries(dependencies)) {
     if (!shared[dep]) {
-      pkgShared[dep] = { requiredVersion };
+      pkgShared[dep] = { requiredVersion, eager: true };
     }
   }
 

+ 1 - 0
dev_mode/webpack.prod.minimize.config.js

@@ -6,6 +6,7 @@ config[0] = merge(config[0], {
   mode: 'production',
   devtool: 'source-map',
   optimization: {
+    minimize: true,
     minimizer: [
       new TerserPlugin({
         parallel: true,

+ 23 - 23
jupyterlab/commands.py

@@ -453,15 +453,15 @@ def clean(app_options=None):
 
 
 def build(name=None, version=None, static_url=None,
-          command='build:prod', kill_event=None,
-          clean_staging=False, app_options=None):
+          kill_event=None,
+          clean_staging=False, app_options=None, production=True, minimize=True):
     """Build the JupyterLab application.
     """
     app_options = _ensure_options(app_options)
     _node_check(app_options.logger)
     handler = _AppHandler(app_options)
     return handler.build(name=name, version=version, static_url=static_url,
-                         command=command, clean_staging=clean_staging)
+                         production=production, minimize=minimize, clean_staging=clean_staging)
 
 
 def get_app_info(app_options=None):
@@ -630,19 +630,19 @@ class _AppHandler(object):
         return True
 
     def build(self, name=None, version=None, static_url=None,
-              command='build:prod:minimize', clean_staging=False):
+              clean_staging=False, production=True, minimize=True):
         """Build the application.
         """
-        # resolve the build type
-        parts = command.split(':')
-        if len(parts) < 2:
-            parts.append('dev')
-        elif parts[1] == 'none':
-            parts[1] = ('dev' if self.info['linked_packages'] or self.info['local_extensions'] else
-                        'prod')
-        command = ':'.join(parts)
+        if production is None:
+            production = not (self.info['linked_packages'] or self.info['local_extensions'])
 
-        self.logger.info('Building jupyterlab assets (%s)' % command)
+        if not production:
+            minimize = False
+
+        info = ['production' if production else 'development']
+        if production:
+            info.append('minimized' if minimize else 'not minimized')
+        self.logger.info(f'Building jupyterlab assets ({", ".join(info)})')
 
         # Set up the build directory.
         app_dir = self.app_dir
@@ -662,16 +662,16 @@ class _AppHandler(object):
             raise RuntimeError(msg)
 
         # Build the app.
-        if parts[1] != 'nobuild':
-            dedupe_yarn(staging, self.logger)
-            starting_dir = os.getcwd()
-            os.chdir(staging)
-            ret = self._run(['node', YARN_PATH, 'run', command])
-            os.chdir(starting_dir)
-            if ret != 0:
-                msg = 'JupyterLab failed to build'
-                self.logger.debug(msg)
-                raise RuntimeError(msg)
+        dedupe_yarn(staging, self.logger)
+        starting_dir = os.getcwd()
+        os.chdir(staging)
+        command = f'build:{"prod" if production else "dev"}{":minimize" if minimize else ""}'
+        ret = self._run(['node', YARN_PATH, 'run', command])
+        os.chdir(starting_dir)
+        if ret != 0:
+            msg = 'JupyterLab failed to build'
+            self.logger.debug(msg)
+            raise RuntimeError(msg)
 
     def watch(self):
         """Start the application watcher and then run the watch in

+ 2 - 2
jupyterlab/handlers/build_handler.py

@@ -100,13 +100,13 @@ class Builder(object):
             app_dir=app_dir, logger=logger, kill_event=kill_event,
             core_config=core_config)
         try:
-            return build(command='build', app_options=app_options)
+            return build(app_options=app_options)
         except Exception as e:
             if self._kill_event.is_set():
                 return
             self.log.warn('Build failed, running a clean and rebuild')
             clean(app_options=app_options)
-            return build(command='build', app_options=app_options)
+            return build(app_options=app_options)
 
 
 class BuildHandler(ExtensionHandlerMixin, APIHandler):

+ 14 - 12
jupyterlab/labapp.py

@@ -64,6 +64,15 @@ build_aliases['debug-log-path'] = 'DebugLogFileMixin.debug_log_path'
 
 build_flags = dict(flags)
 
+build_flags['dev-build'] = (
+    {'LabBuildApp': {'dev_build': True}},
+    "Build in development mode."
+)
+build_flags['no-minimize'] = (
+    {'LabBuildApp': {'minimize': False}},
+    "Do not minimize a production build."
+)
+
 version = __version__
 app_version = get_app_version()
 if version != app_version:
@@ -93,7 +102,7 @@ jupyter --paths
 Explanation:
 
 - `dev-build`: This option controls whether a `dev` or a more streamlined
-`production` build is used. This option will default to `False` (ie the
+`production` build is used. This option will default to `False` (i.e., the
 `production` build) for most users. However, if you have any labextensions
 installed from local files, this option will instead default to `True`.
 Explicitly setting `dev-build` to `False` will ensure that the `production`
@@ -131,23 +140,15 @@ class LabBuildApp(JupyterApp, DebugLogFileMixin):
         help="The version of the built application")
 
     dev_build = Bool(None, allow_none=True, config=True,
-        help="Whether to build in dev mode. Defaults to True (dev mode) if there are any locally linked extensions, else defaults to False (prod mode).")
+        help="Whether to build in dev mode. Defaults to True (dev mode) if there are any locally linked extensions, else defaults to False (production mode).")
 
     minimize = Bool(True, config=True,
-        help="Whether to use a minifier during the Webpack build (defaults to True). Only affects production builds.")
+        help="Whether to minimize a production build (defaults to True).")
 
     pre_clean = Bool(False, config=True,
         help="Whether to clean before building (defaults to False)")
 
     def start(self):
-        parts = ['build']
-        parts.append('none' if self.dev_build is None else
-                     'dev' if self.dev_build else
-                     'prod')
-        if self.minimize:
-            parts.append('minimize')
-        command = ':'.join(parts)
-
         app_dir = self.app_dir or get_app_dir()
         app_options = AppOptions(
             app_dir=app_dir, logger=self.log, core_config=self.core_config
@@ -159,8 +160,9 @@ class LabBuildApp(JupyterApp, DebugLogFileMixin):
                 clean(app_options=app_options)
             self.log.info('Building in %s', app_dir)
             try:
+                production = None if self.dev_build is None else not self.dev_build
                 build(name=self.name, version=self.version,
-                  command=command, app_options=app_options)
+                  app_options=app_options, production = production, minimize=self.minimize)
             except Exception as e:
                 print(buildFailureMsg)
                 raise e

+ 11 - 9
jupyterlab/labextensions.py

@@ -33,6 +33,14 @@ flags['no-build'] = (
     {'BaseExtensionApp': {'should_build': False}},
     "Defer building the app after the action."
 )
+flags['dev-build'] = (
+    {'BaseExtensionApp': {'dev_build': True}},
+    "Build in development mode."
+)
+flags['no-minimize'] = (
+    {'BaseExtensionApp': {'minimize': False}},
+    "Do not minimize a production build."
+)
 flags['clean'] = (
     {'BaseExtensionApp': {'should_clean': True}},
     "Cleanup intermediate files after the action."
@@ -93,7 +101,7 @@ class BaseExtensionApp(JupyterApp, DebugLogFileMixin):
         help="Whether to build in dev mode. Defaults to True (dev mode) if there are any locally linked extensions, else defaults to False (production mode).")
 
     minimize = Bool(True, config=True,
-        help="Whether to use a minifier during the Webpack build (defaults to True). Only affects production builds.")
+        help="Whether to minimize a production build (defaults to True).")
 
     should_clean = Bool(False, config=True,
         help="Whether temporary files should be cleaned up after building jupyterlab")
@@ -112,17 +120,11 @@ class BaseExtensionApp(JupyterApp, DebugLogFileMixin):
         with self.debug_logging():
             ans = self.run_task()
             if ans and self.should_build:
-                parts = ['build']
-                parts.append('none' if self.dev_build is None else
-                             'dev' if self.dev_build else
-                             'prod')
-                if self.minimize:
-                    parts.append('minimize')
-                command = ':'.join(parts)
+                production = None if self.dev_build is None else not self.dev_build
                 app_options = AppOptions(app_dir=self.app_dir, logger=self.log,
                       core_config=self.core_config)
                 build(clean_staging=self.should_clean,
-                      command=command, app_options=app_options)
+                      production = production, minimize = self.minimize, app_options=app_options)
 
     def run_task(self):
         pass