From b88fa0163a61c02bfbf0ddef8772fa9a5d931295 Mon Sep 17 00:00:00 2001 From: jdfreder Date: Tue, 11 Aug 2015 14:06:46 -0700 Subject: [PATCH] Use npm for js and less builds --- bower.json | 1 - notebook/templates/edit.html | 2 +- notebook/templates/notebook.html | 6 +- notebook/templates/page.html | 59 ---------- notebook/templates/terminal.html | 2 +- notebook/templates/tree.html | 2 +- package.json | 20 +++- setup.py | 4 +- setupbase.py | 189 ++++++------------------------- 9 files changed, 58 insertions(+), 227 deletions(-) diff --git a/bower.json b/bower.json index dbebe4be0..0bb7b93db 100644 --- a/bower.json +++ b/bower.json @@ -14,7 +14,6 @@ "marked": "~0.3", "MathJax": "components/MathJax#~2.5", "moment": "~2.8.4", - "requirejs": "~2.1", "term.js": "chjj/term.js#~0.0.4", "text-encoding": "~0.1", "underscore": "components/underscore#~1.5", diff --git a/notebook/templates/edit.html b/notebook/templates/edit.html index 1c543fc2f..7b22a857e 100644 --- a/notebook/templates/edit.html +++ b/notebook/templates/edit.html @@ -95,5 +95,5 @@ data-file-path="{{file_path}}" {{super()}} - + {% endblock %} diff --git a/notebook/templates/notebook.html b/notebook/templates/notebook.html index c9b024f08..b33ce905e 100644 --- a/notebook/templates/notebook.html +++ b/notebook/templates/notebook.html @@ -328,10 +328,6 @@ data-notebook-path="{{notebook_path}}" -{% if ignore_minified_js %} - -{% else %} - -{% endif %} + {% endblock %} diff --git a/notebook/templates/page.html b/notebook/templates/page.html index 95dee7186..3c539e75b 100644 --- a/notebook/templates/page.html +++ b/notebook/templates/page.html @@ -16,65 +16,6 @@ {% endblock %} - - {% block meta %} {% endblock %} diff --git a/notebook/templates/terminal.html b/notebook/templates/terminal.html index e174b55e4..339968b73 100644 --- a/notebook/templates/terminal.html +++ b/notebook/templates/terminal.html @@ -60,5 +60,5 @@ data-ws-path="{{ws_path}}" {{super()}} - + {% endblock %} diff --git a/notebook/templates/tree.html b/notebook/templates/tree.html index 4e4bb3bb3..303044ad2 100644 --- a/notebook/templates/tree.html +++ b/notebook/templates/tree.html @@ -167,5 +167,5 @@ data-terminals-available="{{terminals_available}}" {% block script %} {{super()}} - + {% endblock %} diff --git a/package.json b/package.json index 603923bfd..a9278969f 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,24 @@ "url": "https://github.com/jupyter/notebook.git" }, "scripts": { - "bower": "bower install", - "build": "python setup.py js css" + "bower": "bower install --allow-root --config.interactive=false", + "build": "npm run build:css && npm run build:js", + + "build:css": "concurrent \"npm run build:css:ipython\" \"npm run build:css:style\"", + "build:css:ipython": "lessc --source-map --include-path=./notebook/static/ ./notebook/static/style/ipython.less ./notebook/static/style/ipython.min.css", + "build:css:style": "lessc --source-map --include-path=./notebook/static/ ./notebook/static/style/style.less ./notebook/static/style/style.min.css", + + "build:js": "concurrent \"npm run build:js:tree\" \"npm run build:js:terminal\" \"npm run build:js:notebook\" \"npm run build:js:edit\" \"npm run build:js:auth\"", + "build:js:notebook": "browserify notebook/static/notebook/js/main.js -o notebook/static/notebook/js/main.bundle.js", + "build:js:edit": "browserify notebook/static/edit/js/main.js -o notebook/static/edit/js/main.bundle.js", + "build:js:tree": "browserify notebook/static/tree/js/main.js -o notebook/static/tree/js/main.bundle.js", + "build:js:auth": "browserify notebook/static/auth/js/main.js -o notebook/static/auth/js/main.bundle.js", + "build:js:terminal": "browserify notebook/static/terminal/js/main.js -o notebook/static/terminal/js/main.bundle.js" }, "devDependencies": { "bower": "*", - "less": "~2", - "requirejs": "^2.1.17" + "browserify": "^11.0.1", + "concurrently": "^0.1.1", + "less": "~2" } } diff --git a/setup.py b/setup.py index 94919873b..b7aff920c 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ from setupbase import ( check_package_data_first, CompileCSS, CompileJS, - Bower, + JSDeps, JavascriptVersion, css_js_prerelease, ) @@ -111,7 +111,7 @@ setup_args['cmdclass'] = { 'sdist' : css_js_prerelease(sdist, strict=True), 'css' : CompileCSS, 'js' : CompileJS, - 'jsdeps' : Bower, + 'jsdeps' : JSDeps, 'jsversion' : JavascriptVersion, } diff --git a/setupbase.py b/setupbase.py index 50f0489a2..a379b9e92 100644 --- a/setupbase.py +++ b/setupbase.py @@ -300,61 +300,28 @@ def run(cmd, *args, **kwargs): return check_call(cmd, *args, **kwargs) -class Bower(Command): +class JSDeps(Command): description = "fetch static client-side components with bower" - - user_options = [ - ('force', 'f', "force fetching of bower dependencies"), - ] - + user_options = [] + def initialize_options(self): - self.force = False - + pass + def finalize_options(self): - self.force = bool(self.force) - - bower_dir = pjoin(static, 'components') - node_modules = pjoin(repo_root, 'node_modules') - - def should_run(self): - if self.force: - return True - if not os.path.exists(self.bower_dir): - return True - return mtime(self.bower_dir) < mtime(pjoin(repo_root, 'bower.json')) - - def should_run_npm(self): - if not which('npm'): - print("npm unavailable", file=sys.stderr) - return False - if not os.path.exists(self.node_modules): - return True - return mtime(self.node_modules) < mtime(pjoin(repo_root, 'package.json')) + pass def run(self): - if not self.should_run(): - print("bower dependencies up to date") - return - - if self.should_run_npm(): - print("installing build dependencies with npm") - run(['npm', 'install'], cwd=repo_root) - os.utime(self.node_modules, None) - env = os.environ.copy() env['PATH'] = npm_path - try: run( - ['bower', 'install', '--allow-root', '--config.interactive=false'], + ['npm', 'install'], cwd=repo_root, env=env ) except OSError as e: - print("Failed to run bower: %s" % e, file=sys.stderr) - print("You can install js dependencies with `npm install`", file=sys.stderr) + print("Failed to run `npm install`: %s" % e, file=sys.stderr) raise - os.utime(self.bower_dir, None) # update package data in case this created new files update_package_data(self.distribution) @@ -374,103 +341,51 @@ class CompileCSS(Command): def finalize_options(self): pass - - sources = [] - targets = [] - for name in ('ipython', 'style'): - sources.append(pjoin(static, 'style', '%s.less' % name)) - targets.append(pjoin(static, 'style', '%s.min.css' % name)) - + def run(self): - self.run_command('jsdeps') env = os.environ.copy() env['PATH'] = npm_path - - for src, dst in zip(self.sources, self.targets): - try: - run(['lessc', - '--source-map', - '--include-path=%s' % pipes.quote(static), - src, - dst, - ], cwd=repo_root, env=env) - except OSError as e: - print("Failed to build css: %s" % e, file=sys.stderr) - print("You can install js dependencies with `npm install`", file=sys.stderr) - raise + try: + run( + ['npm', 'run', 'build:css'], + cwd=repo_root, + env=env + ) + except OSError as e: + print("Failed to run `npm run build:css`: %s" % e, file=sys.stderr) + raise # update package data in case this created new files update_package_data(self.distribution) - class CompileJS(Command): """Rebuild Notebook Javascript main.min.js files Calls require via build-main.js """ description = "Rebuild Notebook Javascript main.min.js files" - user_options = [ - ('force', 'f', "force rebuilding js targets"), - ] - + user_options = [] + def initialize_options(self): - self.force = False + pass def finalize_options(self): - self.force = bool(self.force) - - apps = ['notebook', 'tree', 'edit', 'terminal', 'auth'] - targets = [ pjoin(static, app, 'js', 'main.min.js') for app in apps ] - - def sources(self, name): - """Generator yielding .js sources that an application depends on""" - yield pjoin(static, name, 'js', 'main.js') - - for sec in [name, 'base', 'auth']: - for f in glob(pjoin(static, sec, 'js', '*.js')): - if not f.endswith('.min.js'): - yield f - yield pjoin(static, 'services', 'config.js') - if name == 'notebook': - for f in glob(pjoin(static, 'services', '*', '*.js')): - yield f - for parent, dirs, files in os.walk(pjoin(static, 'components')): - if os.path.basename(parent) == 'MathJax': - # don't look in MathJax, since it takes forever to walk it - dirs[:] = [] - continue - for f in files: - yield pjoin(parent, f) + pass - def should_run(self, name, target): - if self.force or not os.path.exists(target): - return True - target_mtime = mtime(target) - for source in self.sources(name): - if mtime(source) > target_mtime: - print(source, target) - return True - return False - - def build_main(self, name): - """Build main.min.js""" - target = pjoin(static, name, 'js', 'main.min.js') - - if not self.should_run(name, target): - log.info("%s up to date" % target) - return - log.info("Rebuilding %s" % target) - run(['node', 'tools/build-main.js', name]) - def run(self): - self.run_command('jsdeps') env = os.environ.copy() env['PATH'] = npm_path - pool = ThreadPool() - pool.map(self.build_main, self.apps) + try: + run( + ['npm', 'run', 'build:js'], + cwd=repo_root, + env=env + ) + except OSError as e: + print("Failed to run `npm run build:js`: %s" % e, file=sys.stderr) + raise # update package data in case this created new files update_package_data(self.distribution) - class JavascriptVersion(Command): """write the javascript version to notebook javascript""" description = "Write Jupyter version to javascript" @@ -502,45 +417,13 @@ def css_js_prerelease(command, strict=False): class DecoratedCommand(command): def run(self): self.distribution.run_command('jsversion') - jsdeps = self.distribution.get_command_obj('jsdeps') - js = self.distribution.get_command_obj('js') - css = self.distribution.get_command_obj('css') - jsdeps.force = js.force = strict - - targets = [ jsdeps.bower_dir ] - targets.extend(js.targets) - targets.extend(css.targets) - missing = [ t for t in targets if not os.path.exists(t) ] - - if not is_repo and not missing: - # If we're an sdist, we aren't a repo and everything should be present. - # Don't rebuild js/css in that case. - command.run(self) - return - try: - self.distribution.run_command('css') + self.distribution.run_command('jsdeps') self.distribution.run_command('js') + self.distribution.run_command('css') except Exception as e: - # refresh missing - missing = [ t for t in targets if not os.path.exists(t) ] - if strict or missing: - # die if strict or any targets didn't build - prefix = os.path.commonprefix([repo_root + os.sep] + missing) - missing = [ m[len(prefix):] for m in missing ] - log.warn("rebuilding js and css failed. The following required files are missing: %s" % missing) - raise e - else: - log.warn("rebuilding js and css failed (not a problem)") - log.warn(str(e)) - - # check again for missing targets, just in case: - missing = [ t for t in targets if not os.path.exists(t) ] - if missing: - # command succeeded, but targets still missing (?!) - prefix = os.path.commonprefix([repo_root + os.sep] + missing) - missing = [ m[len(prefix):] for m in missing ] - raise ValueError("The following required files are missing: %s" % missing) - + log.warn("rebuilding js and css failed.) + raise e + command.run(self) return DecoratedCommand