Merge pull request #24 from dolfs/pr-ui-dev-2

Settings can now be taken from separate file with local override.
This commit is contained in:
Scott Lamb 2018-03-08 21:59:49 -08:00 committed by GitHub
commit 84ce24b7f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 800 additions and 92 deletions

2
.gitignore vendored
View File

@ -1,9 +1,11 @@
cameras.sql cameras.sql
.DS_Store
.project .project
.settings .settings
*.swp *.swp
node_modules node_modules
prep.config prep.config
settings-nvr-local.js
target target
ui-dist ui-dist
yarn-error.log yarn-error.log

View File

@ -56,6 +56,7 @@ make this possible:
* [License](LICENSE.txt) — GPLv3 * [License](LICENSE.txt) — GPLv3
* [Building and installing](guide/install.md) * [Building and installing](guide/install.md)
* [UI Development](guide/developing-ui.md)
* [Troubleshooting](guide/troubleshooting.md) * [Troubleshooting](guide/troubleshooting.md)
# <a name="help"></a> Getting help and getting involved # <a name="help"></a> Getting help and getting involved

146
guide/developing-ui.md Normal file
View File

@ -0,0 +1,146 @@
# Working on UI development
The UI is presented from a single HTML page (index.html) and any number
of Javascript files, css files, images, etc. These are "packed" together
using [webpack](https://webpack.js.org).
For ongoing development it is possible to have the UI running in a web
browser using "hot loading". This means that as you make changes to source
files, they will be detected, the webpack will be recompiled and generated
and then the browser will be informed to reload things. In combination with
the debugger built into modern browsers this makes for a reasonable process.
For a production build, the same process is followed, except with different
settings. In particular, no hot loading development server will be started
and more effort is expended on packing and minimizing the components of
the application as represented in the various "bundles". Read more about
this in the webpack documentation.
## Getting started
Checkout the branch you want to work on and type
$ yarn start
This will pack and prepare a development setup. By default the development
server that serves up the web page(s) will listen on
[http://localhost:3000](http://localhost:3000) so you can direct your browser
there.
Make any changes to the source code as you desire (look at existing code
for examples and typical style), and the browser will hot-load your changes.
Often times you will make mistakes. Anything from a coding error (for which
you can use the browser's debugger), or compilation breaking Javascript errors.
The latter will often be reported as errors during the webpack assembly
process, but some will show up in the browser console, or both.
## Control and location of settings
Much of the settings needed to put the UI together, run webpack etc. is
located in a series of files that contain webpack configuration. These
files all live in the "webpack" subdirectory. We will not explain all
of them here, as you should rarely need to understand them, let alone
modify them.
What is worth mentioning is that the `package.json` file is configured
to use a different webpack configuration for development vs. production
builds. Both configurations depend on a shared configuration common to
both.
There are also some settings that control aspects of the MoonFire UI
behavior, such as window titles etc. These settings are found in the
`settings-nvr.js` file in the project root directory. They should be
pretty self explanatory.
The webpack configuration for all webpack builds is able to load the
values from `settings-nvr.js` and then, if the file exists, load those
from `settings-nvr-local.js` and use them to add to the configuration,
or replace. You can take advantage of this to add your own configuration
values in the "local" file, which does not get checked in, but is used
to affect development, and production builds.
## Special considerations for API calls
The UI code will make calls to the MoonFire NVR's server API, which is
assumed to run on the same host as the MoonFire server. This makes sense
because that server is also normally the one serving up the UI. For UI
development, however this is not always convenient, or even useful.
For one, you may be doing this development on a machine other than where
the main MoonFire server is running. That can work, but of course that
machine will not be responding the the API calls. If the UI does not
gracefully handle API failure errors (it should but development on that
is ongoing), it may break your UI code.
Therefore, for practical purposes, you may want the API calls to go to
a different server than where the localhost is. Rather than editing the
`webpack/dev.conf.js` file to make this happen, you should use a different
mechanism. The reason for not modifying this file (unless the change is
needed by all), is that the file is under source control and thus should
not reflect settings that are just for your personal use.
The manner in which you can achieve using a different server for API
calls is by telling the development server to use a "proxy" for
certain urls. All API calls start with "/api", so we'll take advantage
of that. Create a the file `settings-nvr-local.js` right next to the standard
`settings-nvr.js`. The file should look something like this:
module.exports.settings = {
devServer: {
proxy: {
'/api': 'http://192.168.1.232:8080'
}
}
};
This tells the development server to proxy all urls that it encounters
requests for to the url specified. The way this is done is by taking the
full URI component for the original request, and appending it to the string
configured on the right side of the path to be rewritten above. In a standard
MoonFire install, the server (and thus the API server as well), will be
listening on port 8080 a the IP address where the server lives. So adjust
the above for reach your own MoonFire instance where there is a server
running with some real data behind it.
### Issues with "older" MoonFire builds
You might also have though to change the "/api" string in the source code
to include the IP address of the MoonFire server. This would use the
"right" (desirable) URLs, but the requests will fail due to a violation
of the Cross-Origin Resource Sharing (CORS) protocol. If you really
need to, you can add a configuration option to the MoonFire server
by modifying its "service definition". We will not explain here how.
## Changing development server configuration
You can find our standard configuration for the development server inside
the `webpacks/dev.conf.js` file. Using the technique outlined above you
can change ports, ip addresses etc. One example where this may come in
useful is that you may want to "test" your new API code, running on
machine "A" (from a development server), proxying API requests to machine
"B" (because it has real data), from a browser running on machine "C".
The development server normally is configured to listing on port 3000
on "localhost." (which would correspond to machine "A" in this example).
However, you cannot use "localhost" on another machine to refer to "A".
You may think that using the IP address of "A" works, but it doesn't
because "localhost" lives at an IP address local to machine "A".
To make this work you must tell the development server on host "A" to
listen differently. You need to configure it to listen on IP address
"0.0.0.0", which means "all available interfaces". Once that is in
place you can use the IP address to reach "A" from "C". "A" will then
send API requests on to "B", and present final UI using information
from "A" and "B" to the browser on "C".
Modify the local settings to something like this:
module.exports.settings = {
devServer: {
host: "0.0.0.0",
proxy: {
'/api': 'http://192.168.1.232:8080'
}
}
};

View File

@ -4,7 +4,7 @@ There are no binary packages of Moonfire NVR available yet, so it must be built
from source. This is made easy using a few scripts that will do the job for you from source. This is made easy using a few scripts that will do the job for you
unless you have very a different operating system. The scripts are written and unless you have very a different operating system. The scripts are written and
tested under ubuntu and raspbian but should not be hard to modify if necessary. tested under ubuntu and raspbian but should not be hard to modify if necessary.
You'll start by downloading moonfire if you have not already done so. You'll start by downloading Moonfire if you have not already done so.
## Downloading ## Downloading
@ -55,12 +55,12 @@ hard disk.
Start by executing the setup script: Start by executing the setup script:
$ cd moonfire-nr $ cd moonfire-nvr
$ scripts/setup-ubuntu.sh $ scripts/setup-ubuntu.sh
If this is the very first time you run this script, a file named `prep.config` If this is the very first time you run this script, a file named `prep.config`
will be created and the script will stop. This file is where you will set will be created and the script will stop. This file is where you will set
or change variables that describe the moonfire installation you want. The or change variables that describe the Moonfire installation you want. The
initial execution will put default values in this value, but only for the initial execution will put default values in this value, but only for the
most commonly changed variables. For a full list of variables, see below. most commonly changed variables. For a full list of variables, see below.
@ -73,12 +73,12 @@ case you must either resolve those first, or go the manual route.
The script may be given the "-f" option. If you do, you are telling the script The script may be given the "-f" option. If you do, you are telling the script
that you do not want any existing installation of ffmpeg to be overwritten with that you do not want any existing installation of ffmpeg to be overwritten with
a newer one. This could be important to you. If you do use it, and the version a newer one. This could be important to you. If you do use it, and the version
you have installed is not compatible with moonfire, you will be told through you have installed is not compatible with Moonfire, you will be told through
a message. If you have no ffmpeg installed, the option is effectively ignored a message. If you have no ffmpeg installed, the option is effectively ignored
and the necessary version of ffmpeg will be installed. and the necessary version of ffmpeg will be installed.
The setup script should only need to be run once (after `prep.config` has been The setup script should only need to be run once (after `prep.config` has been
created), although if you do a re-install of moonfire, in particular a much created), although if you do a re-install of Moonfire, in particular a much
newer version, it is a good idea to run it again as requirements and pre-requisites newer version, it is a good idea to run it again as requirements and pre-requisites
may have changed. Running the script multiple times should not have any negative effects. may have changed. Running the script multiple times should not have any negative effects.
@ -86,7 +86,7 @@ may have changed. Running the script multiple times should not have any negative
in particular during the building of libavutil you will see several compiler in particular during the building of libavutil you will see several compiler
warnings. This, while undesirable, is a direct result of the original warnings. This, while undesirable, is a direct result of the original
developers not cleaning up the cause(s) of these warnings. They are, however, developers not cleaning up the cause(s) of these warnings. They are, however,
just warnings and will not affect correct functioning of moonfire. just warnings and will not affect correct functioning of Moonfire.
Once the setup is complete, two steps remain: building and then installing. Once the setup is complete, two steps remain: building and then installing.
There is a script for each of these scenarios, but since generally you would There is a script for each of these scenarios, but since generally you would
@ -99,7 +99,7 @@ The build script is involved like this:
$ scripts/build.sh $ scripts/build.sh
This script will perform all steps necessary to build a complete moonfire This script will perform all steps necessary to build a complete Moonfire
setup. If there are no build errors, this script will then automatically setup. If there are no build errors, this script will then automatically
invoke the install script (see below). invoke the install script (see below).
@ -120,7 +120,7 @@ like this:
This script will copy various files resulting from the build to the correct This script will copy various files resulting from the build to the correct
locations. It will also create a "service configuration" for systemctl that locations. It will also create a "service configuration" for systemctl that
can be used to control moonfire. This service configuration can be prevented can be used to control Moonfire. This service configuration can be prevented
by using the "-s" option to this script. It will also prevent the automatic by using the "-s" option to this script. It will also prevent the automatic
start of this configuration. start of this configuration.

View File

@ -5,13 +5,12 @@
}, },
"scripts": { "scripts": {
"start": "webpack-dev-server --mode development --config webpack/dev.config.js --progress", "start": "webpack-dev-server --mode development --config webpack/dev.config.js --progress",
"build": "webpack --mode production --config webpack/prod.config.js && cp ui-src/index.html ui-dist/" "build": "webpack --mode production --config webpack/prod.config.js"
}, },
"dependencies": { "dependencies": {
"jquery": "^3.2.1", "jquery": "^3.2.1",
"jquery-ui": "^1.12.1", "jquery-ui": "^1.12.1",
"moment-timezone": "^0.5.13", "moment-timezone": "^0.5.13"
"webpack-merge": "^4.1.2"
}, },
"homepage": "https://github.com/scottlamb/moonfire-nvr", "homepage": "https://github.com/scottlamb/moonfire-nvr",
"license": "GPL-3.0", "license": "GPL-3.0",
@ -26,9 +25,11 @@
"clean-webpack-plugin": "^0.1.18", "clean-webpack-plugin": "^0.1.18",
"css-loader": "^0.28.10", "css-loader": "^0.28.10",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"html-webpack-plugin": "^3.0.6",
"style-loader": "^0.19.0", "style-loader": "^0.19.0",
"webpack": "^4.0.1", "webpack": "^4.0.1",
"webpack-cli": "^2.0.10", "webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0" "webpack-dev-server": "^3.1.0",
"webpack-merge": "^4.1.2"
} }
} }

37
settings-nvr.js Normal file
View File

@ -0,0 +1,37 @@
// vim: set et ts=2 sw=2:
//
/**
* This module must export a map, but can use a function with no arguments
* that returns a map, or a function that receives the "env" and "args"
* values from webpack.
*
* @type {Object}
*/
module.exports.settings = {
// Project related: use ./ in front of project root relative files!
app_src_dir: './ui-src',
dist_dir: './ui-dist',
// App related
app_title: 'Moonfire NVR',
// Where is the server to be found
moonfire: {
server: 'localhost',
port: 8080,
},
/*
* In settings override file you can add sections like below on this level.
* After processing, anything defined in mode.production or mode.development,
* as appropriate based on --mode argument to webpack, will be merged
* into the top level of this settings module. This allows you to add to, or
* override anything listed above.
*
* webpack_mode: {
* production: {},
* development: {},
},
*/
};

View File

@ -2,16 +2,14 @@
<!-- vim: set et: --> <!-- vim: set et: -->
<html lang="en"> <html lang="en">
<head> <head>
<title>moonfire ui</title> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<script src="bundle.js"></script> <title><%= htmlWebpackPlugin.options.title %></title>
<style type="text/css"> <style type="text/css">
#nav { #nav {
position: fixed; float: left;
left: 0px;
top: 0px;
width: 17em; width: 17em;
} }
.ui-datepicker { width: 100%; } #nav .ui-datepicker { width: 100%; }
#videos { #videos {
margin-left: 18em; margin-left: 18em;

51
webpack/NVRSettings.js Normal file
View File

@ -0,0 +1,51 @@
// vim: set et ts=2 sw=2:
//
const path = require('path');
const Settings = require('./parts/Settings');
/**
* Exports a sub-class of Settings specifically for the Moonfire NVR project.
*
* Gives us a simpler constructor that encapsulates the names of the expected
* settings files.
*
* Provide some convenience member variables:
* config {object} Map of the original settings configuration
* values {object} The values map of the settings that were configured
*
* @type {NVRSettings}
*/
module.exports = class NVRSettings extends Settings {
/**
* Construct an NVRSettings object.
*
* This object will be a subclass of Settings, with some extra functionality.
*
* Initializes the super Settings object with the proper project root
* and named settings files.
*
* @param {object} env "env" object passed to webpack config function
* @param {object} args "args" object passed to webpack config function
* @param {String} projectRoot Project root, defaults to '.' which is
* usually the directory from which you run
* npm or yarn.
*/
constructor(env, args, projectRoot = './') {
super({
projectRoot: path.resolve(projectRoot),
primaryFile: 'settings-nvr.js',
secondaryFile: 'settings-nvr-local.js',
env: env,
args: args,
});
const config = this.settings_config;
// Add some absolute paths that might be relevant
this.settings = Object.assign(this.settings, {
_paths: {
project_root: config.projectRoot,
app_src_dir: path.join(config.projectRoot, this.settings.app_src_dir),
dist_dir: path.join(config.projectRoot, this.settings.dist_dir),
},
});
}
};

View File

@ -1,42 +1,52 @@
// vim: set et ts=2 sw=2:
//
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const NVRSettings = require('./NVRSettings');
module.exports = (env, args) => {
const nvrSettings = new NVRSettings(env, args).settings;
const project_root = path.join(__dirname, '../'); return {
const src_dir = path.join(project_root, 'ui-src'); entry: {
const dist_dir = path.join(project_root, 'ui-dist'); nvr: path.join(nvrSettings._paths.app_src_dir, 'index.js'),
},
module.exports = { output: {
entry: { filename: '[name].bundle.js',
nvr: path.join(src_dir, 'index.js'), path: nvrSettings._paths.dist_dir,
}, },
output: { module: {
filename: 'bundle.js', rules: [{
path: path.resolve(dist_dir), test: /\.js$/,
}, loader: 'babel-loader',
module: { query: {
rules: [{ 'presets': ['env'],
test: /\.js$/, },
loader: 'babel', exclude: /(node_modules|bower_components)/,
query: { include: [ './ui-src'],
'presets': ['env', {}], }, {
}, test: /\.png$/,
include: [path.resolve(__dirname, './ui-src'), path.resolve(__dirname, './ui-src/lib')], use: ['file-loader'],
}, { }, {
test: /\.png$/, // Load css and then in-line in head
use: ['file-loader'], test: /\.css$/,
}, { loader: 'style-loader!css-loader',
test: /\.css$/, }],
loader: 'style-loader!css-loader', },
}], plugins: [
}, new webpack.IgnorePlugin(/\.\/locale$/),
plugins: [ new HtmlWebpackPlugin({
new webpack.IgnorePlugin(/\.\/locale$/), title: nvrSettings.app_title,
new webpack.NormalModuleReplacementPlugin( template: path.join(nvrSettings._paths.app_src_dir, 'index.html'),
/node_modules\/moment\/moment\.js$/, }),
'./min/moment.min.js'), new webpack.NormalModuleReplacementPlugin(
new webpack.NormalModuleReplacementPlugin( /node_modules\/moment\/moment\.js$/,
/node_modules\/moment-timezone\/index\.js$/, './min/moment.min.js'),
'./builds/moment-timezone-with-data-2012-2022.min.js'), new webpack.NormalModuleReplacementPlugin(
], /node_modules\/moment-timezone\/index\.js$/,
'./builds/moment-timezone-with-data-2012-2022.min.js'),
],
};
}; };

View File

@ -1,26 +1,35 @@
const path = require('path'); // vim: set et ts=2 sw=2:
const webpack = require('webpack'); //
const merge = require('webpack-merge');
const webpack = require('webpack');
const NVRSettings = require('./NVRSettings');
const baseConfig = require('./base.config.js'); const baseConfig = require('./base.config.js');
module.exports = merge(baseConfig, { module.exports = (env, args) => {
devtool: 'inline-source-map', const settingsObject = new NVRSettings(env, args);
devServer: { const nvrSettings = settingsObject.settings;
contentBase: './ui-src',
historyApiFallback: true, return settingsObject.webpackMerge(baseConfig, {
inline: true, stats: {
port: 3000, warnings: true,
hot: true, },
clientLogLevel: 'info', devtool: 'inline-source-map',
proxy: { devServer: {
'/api': 'http://localhost:8080' contentBase: nvrSettings.app_src_dir,
} historyApiFallback: true,
}, inline: true,
plugins: [ port: 3000,
new webpack.DefinePlugin({ hot: true,
'process.env.NODE_ENV': JSON.stringify('development'), clientLogLevel: 'info',
}), proxy: {
new webpack.HotModuleReplacementPlugin(), '/api': `http://${nvrSettings.moonfire.server}:${nvrSettings.moonfire.port}`,
], },
}); },
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),
new webpack.HotModuleReplacementPlugin(),
],
});
};

200
webpack/parts/Settings.js Normal file
View File

@ -0,0 +1,200 @@
// vim: set et ts=2 sw=2:
//
const path = require('path');
const merge = require('webpack-merge');
/**
* Helper function to require a file and catch errors so we can
* distinguish between failure to find the module and errors in the
* module.
*
* When a require results in errors (as opposed to the file not being
* found), we throw an exception.
*
* If the module that is require-d is a function, it will be executed,
* passing the "env" and "args" parameters from the settingsConfig to it.
* The function should return a map.
*
* @param {String} path Path to be passed to require()
* @param {object} settingsConfig Settings passed to new Settings()
* @param {Boolean} optional True file not to exist
* @return {object} The module, or {} if not found (optional)
*/
function requireHelper(path, settingsConfig, optional) {
let module = {};
try {
require.resolve(path); // Throws if not found
try {
module = require(path);
if (typeof(module) === 'function') {
module = module(settingsConfig.env, settingsConfig.args);
}
// Get owned properties only: now a literal map
module = Object.assign({}, require(path).settings);
} catch (e) {
throw new Error('Settings file (' + path + ') has errors.');
}
} catch (e) {
if (!optional) {
throw new Error('Settings file (' + path + ') not found.');
}
}
const args = settingsConfig.args;
const webpackMode = (args ? args.mode : null) || 'none';
const modes = module.webpack_mode || {};
delete module.webpack_mode; // Not modifying original module. We have a copy!
if (webpackMode && modes) {
module = merge(module, modes[webpackMode]);
}
return module;
}
/**
* General purpose settings loading class.
*
* The class first reads a specified file extracting a map object with
* settings. It then attempts to read a second file which, if successfull,
* will be merged to override values from the first.
*
* The module exported in each file must either be a map, in which case
* it is used directly, or a function with no arguments. In the latter case
* it will be called in order to obtain the map.
*
* The intended use is that the first file contains project level settings
* that are checked into a repository. The second file should be for local
* (development) overrides and should not be checked in.
*
* If the primary file is allowed optional and is not found, we still
* attempt to read the secondary, but it is never an error if that file
* does not exist.
*
* Both primary and secondary files may contain a property called webpack_mode
* that, in turn, may contain properties named "development" and
* "production". During loading, if these properties are present, the whole
* "webpack_mode" property is *NOT* delivered in the final result, but the
* sub-property corresponding to webpack's "--mode" argument is merged
* with the configuration object at the top-level. This allows either
* sub-property to override defaults in the settings.
*
* Provide some convenience member variables in the Settings object:
* settings_config {object} object with the arguments to the constructor
* settings {object} The values map of the settings that were configured
*
* In many cases a user of this class will only be intersted in the values
* component. A typical usage patterns would the be:
* <pre><code>
* const Settings = require('Settings');
* const settings = (new Settings()).values;
* </code></pre>
*
* This does make the "config" component of the Settings instance unavailable.
* That can be remedied:
* <pre><code>
* const Settings = require('Settings');
* const _settings = new Settings();
* const settings = _settings.values;
* </code></pre>
*
* Now the config is available as "_settings.config".
*
* @type {NVRSettings}
*/
class Settings {
/**
* Construct the settings object by attempting to read and merge
* both files.
*
* Settings file and alternate or specified as filenames only. They
* are always looked for in the project root directory.
*
* "env", and "args" options are intended to be passed in like so:
* <pre><code>
* const Settings = require('./Settings');
*
* module.exports = (env, args) => {
* const settingsObject = new Settings({ env: env, args: args });
* const settings = settingsObject.settings;
*
* return {
* ... webpack config here, using things like
* ... settings.app_title
* };
* }
* </code></pre>
*
* The Settings object inspects "args.mode" to determine how to overload
* some settings values, and defaults to 'none' if not present.
* Alternatively, null can be passed for "env", and you could pass
* <pre>{ mode: 'development' }</pre> for args (or use 'production').
* Both values will be available later from settingsObject.settings_config
* and using the values from webpack gives full access to everything webpack
* knows.
*
* @param {Boolean} options.optional True if main file is optional
* @param {String} options.projectRoot Path to project root
* @param {String} options.primaryFile Name of main settings file
* @param {String} options.secondaryFile Name of secondary settings file
* @param {String} options.env Environment variables (from webpack)
* @param {String} options.args Arguments (from webpack)
*/
constructor({
optional = false,
projectRoot = './',
primaryFile = 'settings.js',
secondaryFile = 'settings-local.js',
env = null,
args = null,
} = {}) {
if (!projectRoot) {
throw new Error('projectRoot argument for Settings is not set.');
}
// Remember settings, as provided
// eslint-disable-next-line prefer-rest-params
this.settings_config = arguments[0];
// Convert settings file names into absolute paths.
const primaryPath = path.resolve(projectRoot, primaryFile);
const secondaryPath = path.resolve(projectRoot, secondaryFile);
// Check if we can resolve the primary file and if we can, require it.
const _settings =
requireHelper(primaryPath, this.settings_config, optional);
// Merge secondary override file, if it exists
this.settings = merge(_settings,
requireHelper(secondaryPath, this.settings_config, true));
};
/**
* Take one or more webpack configurations and merge them.
*
* This uses the webpack-merge functionality, but each argument is subjected
* to some pre-processing.
* - If the argument is a string, a 'require' is performed with it first
* - If the remaining value is a function, it is expected to be like a
* webpack initialization function which gets passed "env" and "args"
* and it is called like that.
* - The remaining value is fed to webpack-merge.
*
* @param {[object]} webpackConfig1 Object representing the config
* @return {[type]} Merged configuration
*/
webpackMerge(...packs) {
const unpack = (webpackConfig) => {
if ((typeof(webpackConfig) === 'string') ||
(webpackConfig instanceof String)) {
webpackConfig = require(webpackConfig);
}
const config = this.settings_config;
if (typeof(webpackConfig) === 'function') {
return webpackConfig(config.env, config.args);
}
return webpackConfig;
};
return merge(packs.map((p) => unpack(p)));
}
}
module.exports = Settings;

View File

@ -1,15 +1,40 @@
const path = require('path'); // vim: set et ts=2 sw=2:
//
const webpack = require('webpack'); const webpack = require('webpack');
const merge = require('webpack-merge'); const NVRSettings = require('./NVRSettings');
const baseConfig = require('./base.config.js'); const baseConfig = require('./base.config.js');
const CleanWebpackPlugin = require('clean-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = merge(baseConfig, { module.exports = (env, args) => {
plugins: [ const settingsObject = new NVRSettings(env, args);
new webpack.DefinePlugin({ const nvrSettings = settingsObject.settings;
'process.env.NODE_ENV': JSON.stringify('production'),
}), return settingsObject.webpackMerge(baseConfig, {
new CleanWebpackPlugin(['ui-dist'], { root: path.resolve(__dirname, '../') }), optimization: {
], splitChunks: {
}); cacheGroups: {
default: {
minChunks: 2,
priority: -20,
},
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
priority: -10,
},
},
},
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
new CleanWebpackPlugin([nvrSettings.dist_dir], {
root: nvrSettings._paths.project_root,
}),
],
});
};

236
yarn.lock
View File

@ -1163,6 +1163,10 @@ bonjour@^3.5.0:
multicast-dns "^6.0.1" multicast-dns "^6.0.1"
multicast-dns-service-types "^1.1.0" multicast-dns-service-types "^1.1.0"
boolbase@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
boom@2.x.x: boom@2.x.x:
version "2.10.1" version "2.10.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
@ -1343,6 +1347,13 @@ cacheable-request@^2.1.1:
normalize-url "2.0.1" normalize-url "2.0.1"
responselike "1.0.2" responselike "1.0.2"
camel-case@3.0.x:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
dependencies:
no-case "^2.2.0"
upper-case "^1.1.1"
camelcase-keys@^2.0.0: camelcase-keys@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@ -1465,6 +1476,12 @@ class-utils@^0.3.5:
isobject "^3.0.0" isobject "^3.0.0"
static-extend "^0.1.1" static-extend "^0.1.1"
clean-css@4.1.x:
version "4.1.10"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.10.tgz#3dfc2c2569d5f03c14b41d875ad9bccae09cb89e"
dependencies:
source-map "0.5.x"
clean-webpack-plugin@^0.1.18: clean-webpack-plugin@^0.1.18:
version "0.1.18" version "0.1.18"
resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz#2e2173897c76646031bff047c14b9c22c80d8c4a" resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz#2e2173897c76646031bff047c14b9c22c80d8c4a"
@ -1627,6 +1644,10 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies: dependencies:
delayed-stream "~1.0.0" delayed-stream "~1.0.0"
commander@2.14.x, commander@~2.14.1:
version "2.14.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
commander@~2.13.0: commander@~2.13.0:
version "2.13.0" version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
@ -1823,6 +1844,15 @@ css-loader@^0.28.10:
postcss-value-parser "^3.3.0" postcss-value-parser "^3.3.0"
source-list-map "^2.0.0" source-list-map "^2.0.0"
css-select@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
dependencies:
boolbase "~1.0.0"
css-what "2.1"
domutils "1.5.1"
nth-check "~1.0.1"
css-selector-tokenizer@^0.7.0: css-selector-tokenizer@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
@ -1831,6 +1861,10 @@ css-selector-tokenizer@^0.7.0:
fastparse "^1.1.1" fastparse "^1.1.1"
regexpu-core "^1.0.0" regexpu-core "^1.0.0"
css-what@2.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
cssesc@^0.1.0: cssesc@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
@ -2060,6 +2094,19 @@ dns-txt@^2.0.2:
dependencies: dependencies:
buffer-indexof "^1.0.0" buffer-indexof "^1.0.0"
dom-converter@~0.1:
version "0.1.4"
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b"
dependencies:
utila "~0.3"
dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
dependencies:
domelementtype "~1.1.1"
entities "~1.1.1"
dom-walk@^0.1.0: dom-walk@^0.1.0:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
@ -2068,6 +2115,33 @@ domain-browser@^1.1.1:
version "1.1.7" version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
domelementtype@1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
domelementtype@~1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
domhandler@2.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594"
dependencies:
domelementtype "1"
domutils@1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485"
dependencies:
domelementtype "1"
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
dependencies:
dom-serializer "0"
domelementtype "1"
duplexer3@^0.1.4: duplexer3@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@ -2145,6 +2219,10 @@ enhanced-resolve@^4.0.0:
memory-fs "^0.4.0" memory-fs "^0.4.0"
tapable "^1.0.0" tapable "^1.0.0"
entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
errno@^0.1.3: errno@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
@ -2170,7 +2248,7 @@ error@^7.0.2:
string-template "~0.2.1" string-template "~0.2.1"
xtend "~4.0.0" xtend "~4.0.0"
es-abstract@^1.7.0: es-abstract@^1.5.1, es-abstract@^1.7.0:
version "1.10.0" version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
dependencies: dependencies:
@ -2907,6 +2985,10 @@ hawk@3.1.3, hawk@~3.1.3:
hoek "2.x.x" hoek "2.x.x"
sntp "1.x.x" sntp "1.x.x"
he@1.1.x:
version "1.1.1"
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
hmac-drbg@^1.0.0: hmac-drbg@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@ -2953,6 +3035,40 @@ html-entities@^1.2.0:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
html-minifier@^3.2.3:
version "3.5.10"
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.10.tgz#8522c772c388db81aa5c26f62033302d906ea1c7"
dependencies:
camel-case "3.0.x"
clean-css "4.1.x"
commander "2.14.x"
he "1.1.x"
ncname "1.0.x"
param-case "2.1.x"
relateurl "0.2.x"
uglify-js "3.3.x"
html-webpack-plugin@^3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.0.6.tgz#d35b0452aae129a8a9f3fac44a169a625d8cf3fa"
dependencies:
html-minifier "^3.2.3"
loader-utils "^0.2.16"
lodash "^4.17.3"
pretty-error "^2.0.2"
tapable "^1.0.0"
toposort "^1.0.0"
util.promisify "1.0.0"
htmlparser2@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe"
dependencies:
domelementtype "1"
domhandler "2.1"
domutils "1.1"
readable-stream "1.0"
http-cache-semantics@3.8.1: http-cache-semantics@3.8.1:
version "3.8.1" version "3.8.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
@ -3421,6 +3537,10 @@ is-wsl@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@ -3669,6 +3789,15 @@ loader-runner@^2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
dependencies:
big.js "^3.1.3"
emojis-list "^2.0.0"
json5 "^0.5.0"
object-assign "^4.0.1"
loader-utils@^1.0.2, loader-utils@^1.1.0: loader-utils@^1.0.2, loader-utils@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
@ -3704,7 +3833,7 @@ lodash.uniq@^4.5.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
lodash@^4.11.1, lodash@^4.13.1, lodash@^4.17.2, lodash@^4.17.5, lodash@^4.3.0: lodash@^4.11.1, lodash@^4.13.1, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.5, lodash@^4.3.0:
version "4.17.5" version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
@ -3752,6 +3881,10 @@ loud-rejection@^1.0.0, loud-rejection@^1.6.0:
currently-unhandled "^0.4.1" currently-unhandled "^0.4.1"
signal-exit "^3.0.0" signal-exit "^3.0.0"
lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
lowercase-keys@1.0.0, lowercase-keys@^1.0.0: lowercase-keys@1.0.0, lowercase-keys@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
@ -4074,6 +4207,12 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1" snapdragon "^0.8.1"
to-regex "^3.0.1" to-regex "^3.0.1"
ncname@1.0.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ncname/-/ncname-1.0.0.tgz#5b57ad18b1ca092864ef62b0b1ed8194f383b71c"
dependencies:
xml-char-classes "^1.0.0"
negotiator@0.6.1: negotiator@0.6.1:
version "0.6.1" version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@ -4086,6 +4225,12 @@ nice-try@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
no-case@^2.2.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
dependencies:
lower-case "^1.1.1"
node-dir@0.1.8: node-dir@0.1.8:
version "0.1.8" version "0.1.8"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
@ -4202,6 +4347,12 @@ npmlog@^4.0.2:
gauge "~2.7.3" gauge "~2.7.3"
set-blocking "~2.0.0" set-blocking "~2.0.0"
nth-check@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
dependencies:
boolbase "~1.0.0"
num2fraction@^1.2.2: num2fraction@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@ -4236,6 +4387,13 @@ object-visit@^1.0.0:
dependencies: dependencies:
isobject "^3.0.0" isobject "^3.0.0"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.5.1"
object.omit@^2.0.0: object.omit@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
@ -4395,6 +4553,12 @@ parallel-transform@^1.1.0:
inherits "^2.0.3" inherits "^2.0.3"
readable-stream "^2.1.5" readable-stream "^2.1.5"
param-case@2.1.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
dependencies:
no-case "^2.2.0"
parse-asn1@^5.0.0: parse-asn1@^5.0.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712"
@ -4800,6 +4964,13 @@ pretty-bytes@^4.0.2:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
pretty-error@^2.0.2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
dependencies:
renderkid "^2.0.1"
utila "~0.4"
private@^0.1.6, private@^0.1.7, private@~0.1.5: private@^0.1.6, private@^0.1.7, private@~0.1.5:
version "0.1.8" version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@ -5003,6 +5174,15 @@ read-pkg@^2.0.0:
string_decoder "~1.0.3" string_decoder "~1.0.3"
util-deprecate "~1.0.1" util-deprecate "~1.0.1"
readable-stream@1.0:
version "1.0.34"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.6: readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.6:
version "2.3.3" version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
@ -5125,10 +5305,24 @@ regjsparser@^0.1.4:
dependencies: dependencies:
jsesc "~0.5.0" jsesc "~0.5.0"
relateurl@0.2.x:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
remove-trailing-separator@^1.0.1: remove-trailing-separator@^1.0.1:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
renderkid@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.1.tgz#898cabfc8bede4b7b91135a3ffd323e58c0db319"
dependencies:
css-select "^1.1.0"
dom-converter "~0.1"
htmlparser2 "~3.3.0"
strip-ansi "^3.0.0"
utila "~0.3"
repeat-element@^1.1.2: repeat-element@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
@ -5554,7 +5748,7 @@ source-map-url@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.3: source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.3:
version "0.5.7" version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@ -5708,7 +5902,7 @@ string-width@^2.0.0, string-width@^2.1.0:
is-fullwidth-code-point "^2.0.0" is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0" strip-ansi "^4.0.0"
string_decoder@^0.10.25: string_decoder@^0.10.25, string_decoder@~0.10.x:
version "0.10.31" version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
@ -5925,6 +6119,10 @@ to-regex@^3.0.1:
regex-not "^1.0.2" regex-not "^1.0.2"
safe-regex "^1.1.0" safe-regex "^1.1.0"
toposort@^1.0.0:
version "1.0.6"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec"
tough-cookie@~2.3.0: tough-cookie@~2.3.0:
version "2.3.3" version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
@ -5971,6 +6169,13 @@ uglify-es@^3.3.4:
commander "~2.13.0" commander "~2.13.0"
source-map "~0.6.1" source-map "~0.6.1"
uglify-js@3.3.x:
version "3.3.13"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.13.tgz#8a1a89eeb16e2d6a66b0db2b04cb871af3c669cf"
dependencies:
commander "~2.14.1"
source-map "~0.6.1"
uglifyjs-webpack-plugin@^1.1.1, uglifyjs-webpack-plugin@^1.2.2: uglifyjs-webpack-plugin@^1.1.1, uglifyjs-webpack-plugin@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz#e7516d4367afdb715c3847841eb46f94c45ca2b9" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz#e7516d4367afdb715c3847841eb46f94c45ca2b9"
@ -6052,6 +6257,10 @@ upath@^1.0.0:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d" resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d"
upper-case@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
urix@^0.1.0: urix@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
@ -6113,12 +6322,27 @@ util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util.promisify@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
dependencies:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"
util@0.10.3, util@^0.10.3: util@0.10.3, util@^0.10.3:
version "0.10.3" version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
dependencies: dependencies:
inherits "2.0.1" inherits "2.0.1"
utila@~0.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/utila/-/utila-0.3.3.tgz#d7e8e7d7e309107092b05f8d9688824d633a4226"
utila@~0.4:
version "0.4.0"
resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
utils-merge@1.0.1: utils-merge@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@ -6403,6 +6627,10 @@ write-file-atomic@^1.2.0:
imurmurhash "^0.1.4" imurmurhash "^0.1.4"
slide "^1.1.5" slide "^1.1.5"
xml-char-classes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d"
xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"