A little more UI refactor, cleanup, eslint more strict (#54)

* A little more UI refactor, cleanup, eslint more strict

* Split out imports for jQuery components and put them where needed.
* No longer do all of it in application module.
* Prepares better for code splitting.
* Split out video player dialog
* Simplifies jquery-ui dependencies for code splitting
* Simplifies code
* Configure to generate more, but smaller bundles.
* Setup some more strict eslint settings
* Fix css to import rather than require
* Change settings to correctly support tree shaking in production build

Signed-off-by: Dolf Starreveld <dolf@starreveld.com>

* Remove “old” code from TimeFormatter

* Accidentally left behind due to overlapping PRs

Signed-off-by: Dolf Starreveld <dolf@starreveld.com>
This commit is contained in:
Dolf Starreveld
2018-03-25 22:18:56 -07:00
committed by Scott Lamb
parent eaae640703
commit f5aa0080bb
21 changed files with 434 additions and 186 deletions

View File

@@ -48,32 +48,41 @@ module.exports = (env, args) => {
publicPath: '/',
},
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
query: {
'presets': ['env'],
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['env', {modules: false}],
},
exclude: /(node_modules|bower_components)/,
include: ['./ui-src'],
},
exclude: /(node_modules|bower_components)/,
include: ['./ui-src'],
}, {
test: /\.png$/,
use: ['file-loader'],
}, {
test: /\.ico$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
]
}, {
// Load css and then in-line in head
test: /\.css$/,
loader: 'style-loader!css-loader',
}],
{
test: /\.png$/,
use: ['file-loader'],
},
{
test: /\.ico$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
{
test: /\.png$/,
use: ['file-loader'],
},
{
// Load css and then in-line in head
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new webpack.DefinePlugin({
@@ -83,14 +92,20 @@ module.exports = (env, args) => {
new HtmlWebpackPlugin({
title: nvrSettings.app_title,
filename: 'index.html',
template: path.join(nvrSettings._paths.app_src_dir, 'assets', 'index.html'),
template: path.join(
nvrSettings._paths.app_src_dir,
'assets',
'index.html'
),
}),
new webpack.NormalModuleReplacementPlugin(
/node_modules\/moment\/moment\.js$/,
'./min/moment.min.js'),
'./min/moment.min.js'
),
new webpack.NormalModuleReplacementPlugin(
/node_modules\/moment-timezone\/index\.js$/,
'./builds/moment-timezone-with-data-2012-2022.min.js'),
'./builds/moment-timezone-with-data-2012-2022.min.js'
),
],
};
};

View File

@@ -44,6 +44,7 @@ module.exports = (env, args) => {
},
devtool: 'inline-source-map',
optimization: {
minimize: false,
namedChunks: true,
},
devServer: {
@@ -54,11 +55,11 @@ module.exports = (env, args) => {
hot: true,
clientLogLevel: 'info',
proxy: {
'/api': `http://${nvrSettings.moonfire.server}:${nvrSettings.moonfire.port}`,
'/api': `http://${nvrSettings.moonfire.server}:${
nvrSettings.moonfire.port
}`,
},
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
plugins: [new webpack.HotModuleReplacementPlugin()],
});
};

View File

@@ -42,34 +42,34 @@ const merge = require('webpack-merge');
* 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.
* passing the "env" and "args" parameters 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 {String} requiredPath Path to be passed to require()
* @param {object} env webpack's "env" on invocation
* @param {object} args webpack's "args" on invocation (options)
* @param {Boolean} optional True file not to exist
* @return {object} The module, or {} if not found (optional)
*/
function requireHelper(path, settingsConfig, optional) {
function requireHelper(requiredPath, env, args, optional) {
let module = {};
try {
require.resolve(path); // Throws if not found
require.resolve(requiredPath); // Throws if not found
try {
module = require(path);
if (typeof(module) === 'function') {
module = module(settingsConfig.env, settingsConfig.args);
module = require(requiredPath);
if (typeof module === 'function') {
module = module(env, args);
}
// Get owned properties only: now a literal map
module = Object.assign({}, require(path).settings);
module = Object.assign({}, require(requiredPath).settings);
} catch (e) {
throw new Error('Settings file (' + path + ') has errors.');
throw new Error('Settings file (' + requiredPath + ') has errors.');
}
} catch (e) {
if (!optional) {
throw new Error('Settings file (' + path + ') not found.');
throw new Error('Settings file (' + requiredPath + ') 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!
@@ -188,13 +188,14 @@ class Settings {
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);
const _settings = requireHelper(primaryPath, env, args, optional);
// Merge secondary override file, if it exists
this.settings = merge(_settings,
requireHelper(secondaryPath, this.settings_config, true));
};
this.settings = merge(
_settings,
requireHelper(secondaryPath, env, args, true)
);
}
/**
* Take one or more webpack configurations and merge them.
@@ -212,12 +213,14 @@ class Settings {
*/
webpackMerge(...packs) {
const unpack = (webpackConfig) => {
if ((typeof(webpackConfig) === 'string') ||
(webpackConfig instanceof String)) {
if (
typeof webpackConfig === 'string' ||
webpackConfig instanceof String
) {
webpackConfig = require(webpackConfig);
}
const config = this.settings_config;
if (typeof(webpackConfig) === 'function') {
if (typeof webpackConfig === 'function') {
return webpackConfig(config.env, config.args);
}
return webpackConfig;

View File

@@ -42,34 +42,76 @@ module.exports = (env, args) => {
const nvrSettings = settingsObject.settings;
return settingsObject.webpackMerge(baseConfig, {
//devtool: 'cheap-module-source-map',
devtool: 'cheap-module-source-map',
module: {
rules: [{
test: /\.html$/,
loader: 'html-loader',
query: {
minimize: true,
rules: [
{
test: /\.html$/,
loader: 'html-loader',
query: {
minimize: true,
},
},
}],
],
},
optimization: {
minimize: true,
minimizer: [
{
apply: (compiler) => {
/**
* Setup the UglifyJsPlugin as webpack4 does, plus options
* we decide to override.
*/
// Lazy load the uglifyjs plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
new UglifyJsPlugin({
cache: true, // webpack4: default
parallel: true, // webpack4: default
sourceMap:
(args.devtool && /source-?map/.test(args.devtool)) ||
(args.plugins &&
args.plugins.some(
(p) => p instanceof webpack.SourceMapDevToolPlugin
)),
uglifyOptions: {
compress: {
drop_console: true, // Remove all console.log etc.
keep_infinity: true, // Do not change to 1/0
warnings: false, // Do not warn when dropping
},
output: {
// Eliminate most comments, but not marked ones
comments: 'some',
},
},
}).apply(compiler);
},
},
],
splitChunks: {
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
maxInitialRequests: 4,
cacheGroups: {
default: {
'default': {
minChunks: 2,
priority: -20,
},
commons: {
name: 'commons',
'jquery-ui': {
test: /[\\/]node_modules[\\/]jquery-ui[\\/]/,
name: 'jquery-ui',
chunks: 'all',
minChunks: 2,
priority: -5,
},
vendors: {
'jquery': {
test: /[\\/]node_modules[\\/]jquery[\\/]/,
name: 'jquery',
chunks: 'all',
priority: -5,
},
'vendors': {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
@@ -89,9 +131,6 @@ module.exports = (env, args) => {
threshold: 10240,
minRatio: 0.8,
}),
new webpack.NormalModuleReplacementPlugin(
/node_modules\/jquery\/dist\/jquery\.js$/,
'./jquery.min.js'),
],
});
};