mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2024-12-25 14:45:54 -05:00
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:
commit
84ce24b7f6
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,9 +1,11 @@
|
||||
cameras.sql
|
||||
.DS_Store
|
||||
.project
|
||||
.settings
|
||||
*.swp
|
||||
node_modules
|
||||
prep.config
|
||||
settings-nvr-local.js
|
||||
target
|
||||
ui-dist
|
||||
yarn-error.log
|
||||
|
@ -56,6 +56,7 @@ make this possible:
|
||||
|
||||
* [License](LICENSE.txt) — GPLv3
|
||||
* [Building and installing](guide/install.md)
|
||||
* [UI Development](guide/developing-ui.md)
|
||||
* [Troubleshooting](guide/troubleshooting.md)
|
||||
|
||||
# <a name="help"></a> Getting help and getting involved
|
||||
|
146
guide/developing-ui.md
Normal file
146
guide/developing-ui.md
Normal 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'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
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.
|
||||
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
|
||||
|
||||
@ -55,12 +55,12 @@ hard disk.
|
||||
|
||||
Start by executing the setup script:
|
||||
|
||||
$ cd moonfire-nr
|
||||
$ cd moonfire-nvr
|
||||
$ scripts/setup-ubuntu.sh
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
and the necessary version of ffmpeg will be installed.
|
||||
|
||||
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
|
||||
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
|
||||
warnings. This, while undesirable, is a direct result of the original
|
||||
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.
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
start of this configuration.
|
||||
|
||||
|
@ -5,13 +5,12 @@
|
||||
},
|
||||
"scripts": {
|
||||
"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": {
|
||||
"jquery": "^3.2.1",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"moment-timezone": "^0.5.13",
|
||||
"webpack-merge": "^4.1.2"
|
||||
"moment-timezone": "^0.5.13"
|
||||
},
|
||||
"homepage": "https://github.com/scottlamb/moonfire-nvr",
|
||||
"license": "GPL-3.0",
|
||||
@ -26,9 +25,11 @@
|
||||
"clean-webpack-plugin": "^0.1.18",
|
||||
"css-loader": "^0.28.10",
|
||||
"file-loader": "^1.1.11",
|
||||
"html-webpack-plugin": "^3.0.6",
|
||||
"style-loader": "^0.19.0",
|
||||
"webpack": "^4.0.1",
|
||||
"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
37
settings-nvr.js
Normal 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: {},
|
||||
},
|
||||
*/
|
||||
};
|
@ -2,16 +2,14 @@
|
||||
<!-- vim: set et: -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>moonfire ui</title>
|
||||
<script src="bundle.js"></script>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<style type="text/css">
|
||||
#nav {
|
||||
position: fixed;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
float: left;
|
||||
width: 17em;
|
||||
}
|
||||
.ui-datepicker { width: 100%; }
|
||||
#nav .ui-datepicker { width: 100%; }
|
||||
|
||||
#videos {
|
||||
margin-left: 18em;
|
||||
|
51
webpack/NVRSettings.js
Normal file
51
webpack/NVRSettings.js
Normal 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),
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
@ -1,42 +1,52 @@
|
||||
// vim: set et ts=2 sw=2:
|
||||
//
|
||||
|
||||
const path = require('path');
|
||||
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, '../');
|
||||
const src_dir = path.join(project_root, 'ui-src');
|
||||
const dist_dir = path.join(project_root, 'ui-dist');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
nvr: path.join(src_dir, 'index.js'),
|
||||
},
|
||||
output: {
|
||||
filename: 'bundle.js',
|
||||
path: path.resolve(dist_dir),
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.js$/,
|
||||
loader: 'babel',
|
||||
query: {
|
||||
'presets': ['env', {}],
|
||||
},
|
||||
include: [path.resolve(__dirname, './ui-src'), path.resolve(__dirname, './ui-src/lib')],
|
||||
}, {
|
||||
test: /\.png$/,
|
||||
use: ['file-loader'],
|
||||
}, {
|
||||
test: /\.css$/,
|
||||
loader: 'style-loader!css-loader',
|
||||
}],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.IgnorePlugin(/\.\/locale$/),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/node_modules\/moment\/moment\.js$/,
|
||||
'./min/moment.min.js'),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/node_modules\/moment-timezone\/index\.js$/,
|
||||
'./builds/moment-timezone-with-data-2012-2022.min.js'),
|
||||
],
|
||||
return {
|
||||
entry: {
|
||||
nvr: path.join(nvrSettings._paths.app_src_dir, 'index.js'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].bundle.js',
|
||||
path: nvrSettings._paths.dist_dir,
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
'presets': ['env'],
|
||||
},
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
include: [ './ui-src'],
|
||||
}, {
|
||||
test: /\.png$/,
|
||||
use: ['file-loader'],
|
||||
}, {
|
||||
// Load css and then in-line in head
|
||||
test: /\.css$/,
|
||||
loader: 'style-loader!css-loader',
|
||||
}],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.IgnorePlugin(/\.\/locale$/),
|
||||
new HtmlWebpackPlugin({
|
||||
title: nvrSettings.app_title,
|
||||
template: path.join(nvrSettings._paths.app_src_dir, 'index.html'),
|
||||
}),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/node_modules\/moment\/moment\.js$/,
|
||||
'./min/moment.min.js'),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/node_modules\/moment-timezone\/index\.js$/,
|
||||
'./builds/moment-timezone-with-data-2012-2022.min.js'),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
@ -1,26 +1,35 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
// vim: set et ts=2 sw=2:
|
||||
//
|
||||
|
||||
const webpack = require('webpack');
|
||||
const NVRSettings = require('./NVRSettings');
|
||||
const baseConfig = require('./base.config.js');
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
devtool: 'inline-source-map',
|
||||
devServer: {
|
||||
contentBase: './ui-src',
|
||||
historyApiFallback: true,
|
||||
inline: true,
|
||||
port: 3000,
|
||||
hot: true,
|
||||
clientLogLevel: 'info',
|
||||
proxy: {
|
||||
'/api': 'http://localhost:8080'
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('development'),
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
],
|
||||
});
|
||||
module.exports = (env, args) => {
|
||||
const settingsObject = new NVRSettings(env, args);
|
||||
const nvrSettings = settingsObject.settings;
|
||||
|
||||
return settingsObject.webpackMerge(baseConfig, {
|
||||
stats: {
|
||||
warnings: true,
|
||||
},
|
||||
devtool: 'inline-source-map',
|
||||
devServer: {
|
||||
contentBase: nvrSettings.app_src_dir,
|
||||
historyApiFallback: true,
|
||||
inline: true,
|
||||
port: 3000,
|
||||
hot: true,
|
||||
clientLogLevel: 'info',
|
||||
proxy: {
|
||||
'/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
200
webpack/parts/Settings.js
Normal 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;
|
@ -1,15 +1,40 @@
|
||||
const path = require('path');
|
||||
// vim: set et ts=2 sw=2:
|
||||
//
|
||||
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
const NVRSettings = require('./NVRSettings');
|
||||
const baseConfig = require('./base.config.js');
|
||||
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
}),
|
||||
new CleanWebpackPlugin(['ui-dist'], { root: path.resolve(__dirname, '../') }),
|
||||
],
|
||||
});
|
||||
module.exports = (env, args) => {
|
||||
const settingsObject = new NVRSettings(env, args);
|
||||
const nvrSettings = settingsObject.settings;
|
||||
|
||||
return settingsObject.webpackMerge(baseConfig, {
|
||||
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
236
yarn.lock
@ -1163,6 +1163,10 @@ bonjour@^3.5.0:
|
||||
multicast-dns "^6.0.1"
|
||||
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:
|
||||
version "2.10.1"
|
||||
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"
|
||||
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:
|
||||
version "2.1.0"
|
||||
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"
|
||||
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:
|
||||
version "0.1.18"
|
||||
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:
|
||||
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:
|
||||
version "2.13.0"
|
||||
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"
|
||||
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:
|
||||
version "0.7.0"
|
||||
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"
|
||||
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:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
|
||||
@ -2060,6 +2094,19 @@ dns-txt@^2.0.2:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.1.1"
|
||||
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"
|
||||
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:
|
||||
version "0.1.4"
|
||||
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"
|
||||
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:
|
||||
version "0.1.4"
|
||||
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"
|
||||
xtend "~4.0.0"
|
||||
|
||||
es-abstract@^1.7.0:
|
||||
es-abstract@^1.5.1, es-abstract@^1.7.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
|
||||
dependencies:
|
||||
@ -2907,6 +2985,10 @@ hawk@3.1.3, hawk@~3.1.3:
|
||||
hoek "2.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:
|
||||
version "1.0.1"
|
||||
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"
|
||||
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:
|
||||
version "3.8.1"
|
||||
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"
|
||||
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:
|
||||
version "1.0.0"
|
||||
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"
|
||||
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:
|
||||
version "1.1.0"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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:
|
||||
version "1.0.0"
|
||||
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"
|
||||
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:
|
||||
version "0.6.1"
|
||||
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"
|
||||
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:
|
||||
version "0.1.8"
|
||||
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"
|
||||
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:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||
@ -4236,6 +4387,13 @@ object-visit@^1.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "2.0.1"
|
||||
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"
|
||||
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:
|
||||
version "5.1.0"
|
||||
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"
|
||||
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:
|
||||
version "0.1.8"
|
||||
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"
|
||||
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:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
|
||||
@ -5125,10 +5305,24 @@ regjsparser@^0.1.4:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.1.0"
|
||||
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:
|
||||
version "1.1.2"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string_decoder@^0.10.25:
|
||||
string_decoder@^0.10.25, string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
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"
|
||||
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:
|
||||
version "2.3.3"
|
||||
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"
|
||||
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:
|
||||
version "1.2.2"
|
||||
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"
|
||||
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:
|
||||
version "0.1.0"
|
||||
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"
|
||||
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:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.1"
|
||||
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"
|
||||
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:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
|
Loading…
Reference in New Issue
Block a user