diff --git a/awx/ui/build/webpack.base.js b/awx/ui/build/webpack.base.js index dbdec3eafb..e0b6998974 100644 --- a/awx/ui/build/webpack.base.js +++ b/awx/ui/build/webpack.base.js @@ -27,7 +27,7 @@ const VENDOR_ENTRY = path.join(SOURCE_PATH, 'vendor.js'); const INDEX_ENTRY = path.join(CLIENT_PATH, 'index.template.ejs'); const INDEX_OUTPUT = path.join(UI_PATH, 'templates/ui/index.html'); const THEME_ENTRY = path.join(LIB_PATH, 'theme', 'index.less'); -const OUTPUT = 'js/[name].[hash].js'; +const OUTPUT = 'js/[name].[chunkhash].js'; const CHUNKS = ['vendor', 'app']; const VENDOR = VENDOR_ENTRY; @@ -49,7 +49,7 @@ const base = { chunks: false, excludeAssets: name => { const chunkNames = `(${CHUNKS.join('|')})`; - const outputPattern = new RegExp(`${chunkNames}\.[a-f0-9]+\.(js|css)$`, 'i'); + const outputPattern = new RegExp(`${chunkNames}\.[a-f0-9]+\.(js|css)(|\.map)$`, 'i'); return !outputPattern.test(name); } @@ -87,17 +87,6 @@ const base = { use: ['css-loader', 'less-loader'] }) }, - { - test: require.resolve('jquery'), - loader: 'expose-loader?$!expose-loader?jQuery!expose-loader?jquery' - }, - { - loader: 'script-loader', - test: [ - /node_modules\/javascript-detect-element-resize\/jquery.resize\.js$/, - /node_modules\/d3\/d3\.min.js$/ - ] - }, { test: /\.html$/, use: ['ngtemplate-loader', 'html-loader'], @@ -117,10 +106,9 @@ const base = { new webpack.ProvidePlugin({ jsyaml: 'js-yaml', CodeMirror: 'codemirror', - jsonlint: 'codemirror.jsonlint', - _: 'lodash' + jsonlint: 'codemirror.jsonlint' }), - new ExtractTextPlugin('css/[name].[hash].css'), + new ExtractTextPlugin('css/[name].[chunkhash].css'), new CleanWebpackPlugin([STATIC_PATH, COVERAGE_PATH, LANGUAGES_PATH], { root: UI_PATH, verbose: false @@ -182,13 +170,7 @@ const base = { filename: INDEX_OUTPUT, inject: false, chunks: CHUNKS, - chunksSortMode: (chunk) => { - if (chunk.names[0] === 'polyfill' || chunk.names[0] === 'vendor') { - return -1; - } - - return 1; - } + chunksSortMode: chunk => chunk.names[0] === 'vendor' ? -1 : 1 }) ], resolve: { @@ -200,12 +182,14 @@ const base = { '~theme': THEME_PATH, '~modules': NODE_MODULES_PATH, '~assets': ASSETS_PATH, - d3$: '~modules/d3/d3.min.js', + 'd3$': '~modules/d3/d3.min.js', 'codemirror.jsonlint$': '~modules/codemirror/addon/lint/json-lint.js', + 'jquery': '~modules/jquery/dist/jquery.js', 'jquery-resize$': '~modules/javascript-detect-element-resize/jquery.resize.js', - select2$: '~modules/select2/dist/js/select2.full.min.js', + 'select2$': '~modules/select2/dist/js/select2.full.min.js', 'js-yaml$': '~modules/js-yaml/dist/js-yaml.min.js', 'lr-infinite-scroll$': '~modules/lr-infinite-scroll/lrInfiniteScroll.js', + 'angular-tz-extensions$': '~modules/angular-tz-extensions/lib/angular-tz-extensions.js', 'angular-ui-router$': '~modules/angular-ui-router/release/angular-ui-router.js', 'angular-ui-router-state-events$': '~modules/angular-ui-router/release/stateEvents.js', 'ng-toast-provider$': '~modules/ng-toast/src/scripts/provider.js', diff --git a/awx/ui/build/webpack.development.js b/awx/ui/build/webpack.development.js index 2d85a4bd7a..5e936c0a7e 100644 --- a/awx/ui/build/webpack.development.js +++ b/awx/ui/build/webpack.development.js @@ -5,7 +5,7 @@ const _ = require('lodash'); const base = require('./webpack.base'); const development = { - devtool: 'cheap-source-map' + devtool: 'source-map' }; module.exports = _.merge(base, development); diff --git a/awx/ui/build/webpack.production.js b/awx/ui/build/webpack.production.js index e709962765..4c61eef4a4 100644 --- a/awx/ui/build/webpack.production.js +++ b/awx/ui/build/webpack.production.js @@ -25,12 +25,11 @@ const production = { filename: INSTALL_RUNNING_OUTPUT, inject: false, chunks: CHUNKS, - chunksSortMode: (chunk) => { - if (chunk.names[0] === 'polyfill' || chunk.names[0] === 'vendor') { - return -1; - } - - return 1; + chunksSortMode: chunk => chunk.names[0] === 'vendor' ? -1 : 1 + }), + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify('production') } }) ] diff --git a/awx/ui/build/webpack.watch.js b/awx/ui/build/webpack.watch.js index 85431adddc..1c2f9e5270 100644 --- a/awx/ui/build/webpack.watch.js +++ b/awx/ui/build/webpack.watch.js @@ -3,14 +3,21 @@ const path = require('path'); const _ = require('lodash'); const webpack = require('webpack'); const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin'); +const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); const TARGET_PORT = _.get(process.env, 'npm_package_config_django_port', 8043); const TARGET_HOST = _.get(process.env, 'npm_package_config_django_host', 'https://localhost'); const TARGET = `https://${TARGET_HOST}:${TARGET_PORT}`; +const OUTPUT = 'js/[name].js'; const development = require('./webpack.development'); const watch = { + cache: true, + devtool: 'cheap-source-map', + output: { + filename: OUTPUT + }, module: { rules: [ { @@ -22,10 +29,24 @@ const watch = { ] }, plugins: [ + new HardSourceWebpackPlugin({ + cacheDirectory: 'node_modules/.cache/hard-source/[confighash]', + recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json', + configHash: config => { + return require('node-object-hash')({ sort: false }).hash(config); + }, + environmentHash: { + root: process.cwd(), + directories: ['node_modules'], + files: ['package.json'] + } + }), new HtmlWebpackHarddiskPlugin(), new webpack.HotModuleReplacementPlugin() ], devServer: { + hot: true, + inline: true, contentBase: path.resolve(__dirname, '..', 'static'), stats: 'minimal', publicPath: '/static/', @@ -35,7 +56,8 @@ const watch = { '/': { target: TARGET, secure: false, - ws: false + ws: false, + bypass: req => req.originalUrl.includes('hot-update.json') }, '/websocket': { target: TARGET, @@ -50,4 +72,3 @@ watch.module.rules = development.module.rules.concat(watch.module.rules); watch.plugins = development.plugins.concat(watch.plugins); module.exports = _.merge(development, watch); - diff --git a/awx/ui/client/src/vendor.js b/awx/ui/client/src/vendor.js index 4af531a78f..11c361d314 100644 --- a/awx/ui/client/src/vendor.js +++ b/awx/ui/client/src/vendor.js @@ -1,3 +1,4 @@ +// Theme require('~assets/custom-theme/jquery-ui-1.10.3.custom.min.css'); require('~assets/ansible-bootstrap.min.css'); require('~assets/fontcustom/fontcustom.css'); @@ -9,17 +10,28 @@ require('~modules/codemirror/addon/lint/lint.css'); require('~modules/nvd3/build/nv.d3.css'); require('~modules/ng-toast/dist/ngToast.min.css'); -require('jquery'); +// jQuery + extensions +global.jQuery = require('jquery'); +global.jquery = global.jQuery; +global.$ = global.jQuery; require('jquery-resize'); require('jquery-ui'); require('bootstrap'); require('bootstrap-datepicker'); -require('moment'); require('select2'); + +// Standalone libs +global._ = require('lodash'); +require('moment'); +require('rrule'); require('sprintf-js'); require('reconnectingwebsocket'); + +// D3 + extensions require('d3'); require('nvd3'); + +// Angular require('angular'); require('angular-cookies'); require('angular-sanitize'); diff --git a/awx/ui/package.json b/awx/ui/package.json index f79ca4aa32..505a27810b 100644 --- a/awx/ui/package.json +++ b/awx/ui/package.json @@ -47,7 +47,6 @@ "eslint-import-resolver-webpack": "^0.8.3", "eslint-loader": "^1.9.0", "eslint-plugin-import": "^2.7.0", - "expose-loader": "^0.7.3", "extract-text-webpack-plugin": "^3.0.0", "grunt": "^1.0.1", "grunt-angular-gettext": "^2.2.3", @@ -55,12 +54,12 @@ "grunt-concurrent": "^2.3.0", "grunt-contrib-jshint": "^1.0.0", "grunt-newer": "^1.2.0", + "hard-source-webpack-plugin": "^0.4.9", "html-loader": "^0.5.1", "html-webpack-harddisk-plugin": "^0.1.0", "html-webpack-plugin": "^2.30.1", "jasmine-core": "^2.5.2", "jshint": "^2.9.4", - "jshint-loader": "^0.8.3", "jshint-stylish": "^2.2.0", "json-loader": "^0.5.4", "karma": "^1.4.1", @@ -81,9 +80,8 @@ "load-grunt-tasks": "^3.5.0", "ngtemplate-loader": "^2.0.1", "nightwatch": "^0.9.16", + "node-object-hash": "^1.3.0", "phantomjs-prebuilt": "^2.1.12", - "script-loader": "^0.7.0", - "style-loader": "^0.18.2", "time-grunt": "^1.4.0", "uglifyjs-webpack-plugin": "^0.4.6", "webpack": "^3.0.0",