From 2921c2adac93ddc32bd13824e961e6747720b3bb Mon Sep 17 00:00:00 2001 From: Brett Sun Date: Thu, 2 Jun 2016 15:35:31 +0200 Subject: [PATCH] Handle dependencies that should be split from the main app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using ES6’s System.import allows webpack to split up the dependency into its own chunk and load it as necessary. When this is not possible (ie. when a script expects itself to be dropped into the html), follow the previous strategy of copying the dependency folder into the build folder. --- js/components/ascribe_media/media_player.js | 33 ++++++++++----------- js/constants/application_constants.js | 6 +--- js/third_party/imports/audiojs.js | 18 +++++++++++ js/third_party/imports/shmui.js | 19 ++++++++++++ js/third_party/imports/videojs.js | 18 +++++++++++ package.json | 1 + webpack.config.js | 18 +++++++++++ 7 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 js/third_party/imports/audiojs.js create mode 100644 js/third_party/imports/shmui.js create mode 100644 js/third_party/imports/videojs.js diff --git a/js/components/ascribe_media/media_player.js b/js/components/ascribe_media/media_player.js index 888e148f..73921d0b 100644 --- a/js/components/ascribe_media/media_player.js +++ b/js/components/ascribe_media/media_player.js @@ -7,10 +7,15 @@ import Panel from 'react-bootstrap/lib/Panel'; import AppConstants from '../../constants/application_constants'; +import audiojs from '../../third_party/imports/audiojs'; +import shmui from '../../third_party/imports/shmui'; +import videojs from '../../third_party/imports/videojs'; + import { escapeHTML } from '../../utils/general_utils'; import { extractFileExtensionFromUrl } from '../../utils/file_utils'; import { InjectInHeadUtils } from '../../utils/inject_utils'; + /** * This is the component that implements display-specific functionality. * @@ -57,12 +62,9 @@ let Image = React.createClass({ componentDidMount() { if (this.props.url) { - InjectInHeadUtils.inject(AppConstants.jquery.sdkUrl) - .then(() => - Q.all([ - InjectInHeadUtils.inject(AppConstants.shmui.cssUrl), - InjectInHeadUtils.inject(AppConstants.shmui.sdkUrl) - ]).then(() => { window.jQuery('.shmui-ascribe').shmui(); })); + shmui + .importLib() + .then(() => window.jQuery('.shmui-ascribe').shmui()); } }, @@ -89,13 +91,9 @@ let Audio = React.createClass({ }, componentDidMount() { - InjectInHeadUtils.inject(AppConstants.audiojs.sdkUrl).then(this.ready); - }, - - ready() { - window.audiojs.events.ready(function() { - window.audiojs.createAll(); - }); + audiojs + .importLib() + .then(() => window.audiojs.events.ready(() => window.audiojs.createAll())); }, render() { @@ -142,11 +140,10 @@ let Video = React.createClass({ }, componentDidMount() { - Q.all([ - InjectInHeadUtils.inject(AppConstants.videojs.cssUrl), - InjectInHeadUtils.inject(AppConstants.videojs.sdkUrl)]) - .then(() => this.setState({libraryLoaded: true})) - .fail(() => this.setState({libraryLoaded: false})); + videojs + .importLib() + .then(() => this.setState({ libraryLoaded: true })) + .catch(() => this.setState({ libraryLoaded: false })); }, shouldComponentUpdate(nextProps, nextState) { diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index 88e0133d..f448b432 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -98,12 +98,8 @@ const constants = { 'jquery': { 'sdkUrl': 'https://code.jquery.com/jquery-2.1.4.min.js' }, - 'shmui': { - 'sdkUrl': baseUrl + 'static/thirdparty/shmui/jquery.shmui.js', - 'cssUrl': baseUrl + 'static/thirdparty/shmui/shmui.css' - }, 'audiojs': { - 'sdkUrl': baseUrl + 'static/thirdparty/audiojs/audiojs/audio.min.js' + 'sdkUrl': baseUrl + '/static/third_party/audiojs/audio.min.js' }, 'videojs': { 'sdkUrl': '//vjs.zencdn.net/4.12/video.js', diff --git a/js/third_party/imports/audiojs.js b/js/third_party/imports/audiojs.js new file mode 100644 index 00000000..0b96d3f7 --- /dev/null +++ b/js/third_party/imports/audiojs.js @@ -0,0 +1,18 @@ +import AppConstants from '../../constants/application_constants'; + +import { InjectInHeadUtils } from '../../utils/inject_utils'; + + +/** + * Imports audiojs from the copied directory. + * + * Unfortunately, audiojs' package structure and the way it currently loads image assets prevents us + * from using System.import. + * + * @return {Promise} Promise that resolves with [audio.min.js] on success. + */ +function importLib() { + return InjectInHeadUtils.inject(AppConstants.audiojs.sdkUrl); +} + +export default { importLib }; diff --git a/js/third_party/imports/shmui.js b/js/third_party/imports/shmui.js new file mode 100644 index 00000000..e1be32f3 --- /dev/null +++ b/js/third_party/imports/shmui.js @@ -0,0 +1,19 @@ +import AppConstants from '../../constants/application_constants'; + +import { InjectInHeadUtils } from '../../utils/inject_utils'; + + +/** + * Imports shmui and its dependencies (jQuery) + * + * @return {Promise} Promise that resolves with [jquery.shmui.js, shmui.css] on success. + */ +function importLib() { + return InjectInHeadUtils.inject(AppConstants.jquery.sdkUrl) + .then(() => Promise.all([ + System.import('shmui/jquery.shmui.js'), + System.import('shmui/shmui.css') + ])) +} + +export default { importLib }; diff --git a/js/third_party/imports/videojs.js b/js/third_party/imports/videojs.js new file mode 100644 index 00000000..d06e7004 --- /dev/null +++ b/js/third_party/imports/videojs.js @@ -0,0 +1,18 @@ +import AppConstants from '../../constants/application_constants'; + +import { InjectInHeadUtils } from '../../utils/inject_utils'; + + +/** + * Imports videojs and its stylesheet. + * + * @return {Promise} Promise that resolves with [video.js, video-js.css] on success. + */ +function importLib() { + return Promise.all([ + InjectInHeadUtils.inject(AppConstants.videojs.cssUrl), + InjectInHeadUtils.inject(AppConstants.videojs.sdkUrl) + ]); +} + +export default { importLib }; diff --git a/package.json b/package.json index 8208d291..c60b246f 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "classlist-polyfill": "^1.0.2", "classnames": "^1.2.2", "compression": "^1.6.2", + "copy-webpack-plugin": "^3.0.1", "core-js": "^2.4.0", "css-loader": "^0.23.1", "decamelize": "^1.1.1", diff --git a/webpack.config.js b/webpack.config.js index 5ebb0600..2efbbee1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,7 @@ const removeTrailingSlash = require('remove-trailing-slash'); const webpack = require('webpack'); const autoPrefixer = require('autoprefixer'); const combineLoaders = require('webpack-combine-loaders'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); @@ -51,6 +52,15 @@ const DEFINITIONS = { const PLUGINS = [ new webpack.DefinePlugin(DEFINITIONS), new webpack.NoErrorsPlugin(), + + // Handle any dependencies that don't play nicely with System.import resolution + new CopyWebpackPlugin([ + { + from: path.resolve(PATHS.NODE_MODULES, 'audiojs/audiojs'), + to: 'third_party/audiojs' + }, + ]), + // Extract stylesheets out of bundle new ExtractTextPlugin( PRODUCTION ? 'css/styles.min.css' : 'css/styles.css', { @@ -153,6 +163,14 @@ const LOADERS = [ loader: ExtractTextPlugin.extract('style', SASS_LOADER), }, + // Dependencies + // Shmui + { + test: /\.css$/, + include: [path.resolve(PATHS.NODE_MODULES, 'shmui')], + loader: `style!${CSS_LOADER}`, + }, + // Fonts // woffs and svgs are typically smaller should we can try to load them as a url {