mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-21 13:57:57 -05:00
Frontent dev env (#247)
* Added frontend development files/environment * More items-categories related removals * Improvements in pages templates (inc. static pages) * Improvements in video player * Added empty home page message + cta * Updates in media, playlist and management pages * Improvements in material icons font loading * Replaced media & playlists links in frontend dev-env * frontend package version update * chnaged frontend dev url port * static files update * Changed default position of theme switcher * enabled frontend docker container
This commit is contained in:
36
frontend/packages/scripts/.eslintrc.js
Executable file
36
frontend/packages/scripts/.eslintrc.js
Executable file
@@ -0,0 +1,36 @@
|
||||
module.exports = {
|
||||
"extends": ["eslint:recommended"],
|
||||
"env": { "es6": true, "browser": true, "node": true },
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"rules": {
|
||||
"indent": ["error", "tab"],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"quotes": ["error", "single"],
|
||||
"semi": ["error", "always"],
|
||||
'no-empty': ["error", { "allowEmptyCatch": true }],
|
||||
'no-constant-condition': ["error", { "checkLoops": false }],
|
||||
},
|
||||
"overrides": [{
|
||||
"plugins": [ "@typescript-eslint" ],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"files": ["**/*.ts", "**/*.tsx"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": { "jsx": true },
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
||||
"@typescript-eslint/no-var-requires": "off"
|
||||
},
|
||||
}]
|
||||
}
|
||||
1
frontend/packages/scripts/README.md
Normal file
1
frontend/packages/scripts/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# mediacms-scripts
|
||||
47
frontend/packages/scripts/cli.js
Executable file
47
frontend/packages/scripts/cli.js
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const spawn = require('cross-spawn');
|
||||
|
||||
('use strict');
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
const scriptIndex = args.findIndex(
|
||||
(x) => x === 'build' || x === 'development' || x === 'analyzer' || x === 'rimraf' // TODO
|
||||
);
|
||||
const script = scriptIndex === -1 ? args[0] : args[scriptIndex];
|
||||
const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : [];
|
||||
|
||||
if (['build', 'development', 'analyzer', 'rimraf'].includes(script)) {
|
||||
const result = spawn.sync(
|
||||
process.execPath,
|
||||
nodeArgs.concat(require.resolve('./scripts/' + script)).concat(args.slice(scriptIndex + 1)),
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
if (result.signal) {
|
||||
if (result.signal === 'SIGKILL') {
|
||||
console.log(
|
||||
'The build failed because the process exited too early. ' +
|
||||
'This probably means the system ran out of memory or someone called ' +
|
||||
'`kill -9` on the process.'
|
||||
);
|
||||
} else if (result.signal === 'SIGTERM') {
|
||||
console.log(
|
||||
'The build failed because the process exited too early. ' +
|
||||
'Someone might have called `kill` or `killall`, or the system could ' +
|
||||
'be shutting down.'
|
||||
);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit(result.status);
|
||||
} else {
|
||||
console.log('Unknown script "' + script + '".');
|
||||
}
|
||||
3
frontend/packages/scripts/config/build.config.js
Executable file
3
frontend/packages/scripts/config/build.config.js
Executable file
@@ -0,0 +1,3 @@
|
||||
import { buildCommonjs } from './helpers/buildCommonjs.js';
|
||||
|
||||
export default buildCommonjs('./src/index.ts', '.')('./dist/webpack-dev-env.js');
|
||||
24
frontend/packages/scripts/config/helpers/buildCommonjs.js
Executable file
24
frontend/packages/scripts/config/helpers/buildCommonjs.js
Executable file
@@ -0,0 +1,24 @@
|
||||
import typescript from 'rollup-plugin-typescript2';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import visualizer from 'rollup-plugin-visualizer';
|
||||
import cleanup from 'rollup-plugin-cleanup';
|
||||
|
||||
export function buildCommonjs(input_file, output_folder) {
|
||||
return function (filename, visualize) {
|
||||
const plugins = [
|
||||
resolve({ customResolveOptions: { moduleDirectories: 'node_modules' } }),
|
||||
typescript(),
|
||||
cleanup({ comments: 'none' }),
|
||||
];
|
||||
|
||||
if (visualize) {
|
||||
plugins.push(visualizer({ title: filename, filename: output_folder + filename + '.html' }));
|
||||
}
|
||||
|
||||
return {
|
||||
input: input_file,
|
||||
output: [{ format: 'cjs', file: filename }],
|
||||
plugins: plugins,
|
||||
};
|
||||
};
|
||||
}
|
||||
3
frontend/packages/scripts/config/visual.config.js
Executable file
3
frontend/packages/scripts/config/visual.config.js
Executable file
@@ -0,0 +1,3 @@
|
||||
import { buildCommonjs } from './helpers/buildCommonjs.js';
|
||||
|
||||
export default buildCommonjs('./src/index.ts', './visualizer/')('./dist/webpack-dev-env.js', true);
|
||||
3
frontend/packages/scripts/config/watch.config.js
Executable file
3
frontend/packages/scripts/config/watch.config.js
Executable file
@@ -0,0 +1,3 @@
|
||||
import { buildCommonjs } from './helpers/buildCommonjs.js';
|
||||
|
||||
export default buildCommonjs('./src/index.ts', '.')('./dist/webpack-dev-env.js');
|
||||
782
frontend/packages/scripts/dist/webpack-dev-env.js
vendored
Normal file
782
frontend/packages/scripts/dist/webpack-dev-env.js
vendored
Normal file
@@ -0,0 +1,782 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
function __spreadArray(to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || from);
|
||||
}
|
||||
|
||||
function bodySnippet(id) {
|
||||
return '<div id="' + id + '"></div>';
|
||||
}
|
||||
var homePage = {
|
||||
staticPage: true,
|
||||
buildExclude: false,
|
||||
title: 'Home',
|
||||
filename: 'index.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: bodySnippet('page-home'),
|
||||
}
|
||||
},
|
||||
window: {},
|
||||
render: 'import { renderPage } from \'./js/helpers\'; import { HomePage } from \'./js/pages/HomePage\'; renderPage( \'page-home\', HomePage );',
|
||||
};
|
||||
var errorPage = {
|
||||
staticPage: true,
|
||||
buildExclude: false,
|
||||
title: 'Error',
|
||||
filename: 'error.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: bodySnippet('page-error'),
|
||||
}
|
||||
},
|
||||
window: {},
|
||||
render: 'import { renderPage } from \'./js/helpers\'; import { ErrorPage } from \'./js/pages/ErrorPage\'; renderPage( \'page-error\', ErrorPage );',
|
||||
};
|
||||
var pages = {
|
||||
home: homePage,
|
||||
error: errorPage,
|
||||
};
|
||||
var htmlHead = {
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ content: 'ie=edge', 'http-equiv': 'x-ua-compatible' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
],
|
||||
links: [],
|
||||
scripts: [],
|
||||
};
|
||||
var htmlBody = {
|
||||
scripts: [],
|
||||
snippet: '',
|
||||
};
|
||||
var html = {
|
||||
head: htmlHead,
|
||||
body: htmlBody,
|
||||
};
|
||||
var config$3 = {
|
||||
src: '',
|
||||
build: '',
|
||||
pages: pages,
|
||||
html: html,
|
||||
window: {},
|
||||
postcssConfigFile: '',
|
||||
};
|
||||
|
||||
/*const chunksCacheGroups_0 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
/*const chunksCacheGroups_1 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
// priority: -10,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](!MediaCmsPlayer)[\\/]/,
|
||||
name: "_vendors",
|
||||
// priority: -20,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
// reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
/*const chunksCacheGroups_2 = {
|
||||
commons: {
|
||||
minChunks: 2,
|
||||
// maxInitialRequests: 8, // @note: Tested values from 0 to 10, and changes applied with values 0, 4, 5, 6, 7, 8.
|
||||
// minSize: 0,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
/*const chunksCacheGroups_3 = {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
};*/
|
||||
var config$2 = {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
optimization: {
|
||||
runtimeChunk: false,
|
||||
/*splitChunks: {
|
||||
// minSize: 1000000,
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
// minSize: 1000000,
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_0,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_1,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_2,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_3,
|
||||
},*/
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/*const chunksCacheGroups_0 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_1 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
// priority: -10,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](!MediaCmsPlayer)[\\/]/,
|
||||
name: "_vendors",
|
||||
// priority: -20,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
// reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_2 = {
|
||||
commons: {
|
||||
minChunks: 2,
|
||||
// maxInitialRequests: 8, // @note: Tested values from 0 to 10, and changes applied with values 0, 4, 5, 6, 7, 8.
|
||||
// minSize: 0,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_3 = {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
};*/
|
||||
var config$1 = {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
minimize: true,
|
||||
runtimeChunk: false,
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see {link: https://github.com/seeyoulater/html-beautify-webpack-plugin/blob/master/index.js}
|
||||
*/
|
||||
var prettify = require('html-prettify');
|
||||
var HtmlWebpackPlugin$1 = require('html-webpack-plugin');
|
||||
require('webpack/lib/WebpackError.js');
|
||||
function htmlPluginDataFunction(pluginData, options, callback) {
|
||||
pluginData.html = prettify(options.replace.reduce(function (res, item) { return res.replace(item instanceof RegExp ? new RegExp(item, 'gi') : item, ''); }, pluginData.html) /*,
|
||||
options.config*/);
|
||||
callback(null, pluginData);
|
||||
}
|
||||
var MyHtmlBeautifyWebpackPlugin = /** @class */ (function () {
|
||||
function MyHtmlBeautifyWebpackPlugin() {
|
||||
}
|
||||
MyHtmlBeautifyWebpackPlugin.prototype.apply = function (compiler) {
|
||||
var options = {
|
||||
config: {
|
||||
indent_size: 4,
|
||||
indent_with_tabs: false,
|
||||
html: {
|
||||
end_with_newline: true,
|
||||
indent_inner_html: true,
|
||||
preserve_newlines: true,
|
||||
max_preserve_newlines: 0,
|
||||
}
|
||||
},
|
||||
replace: []
|
||||
};
|
||||
function tapAsyncCallback(pluginData, callback) {
|
||||
return htmlPluginDataFunction(pluginData, options, callback);
|
||||
}
|
||||
function tapHookCallback(compilation) {
|
||||
return HtmlWebpackPlugin$1.getHooks(compilation).beforeEmit.tapAsync('MyHtmlBeautifyWebpackPlugin', tapAsyncCallback);
|
||||
}
|
||||
compiler.hooks.compilation.tap('MyHtmlBeautifyWebpackPlugin', tapHookCallback);
|
||||
};
|
||||
return MyHtmlBeautifyWebpackPlugin;
|
||||
}());
|
||||
|
||||
var fs = require('fs');
|
||||
var path$1 = require('path');
|
||||
var ejs = require('ejs');
|
||||
var templatePath = path$1.join(__dirname, '../templates');
|
||||
var sitemapTemplatePath = path$1.join(templatePath, 'sitemap.ejs');
|
||||
var sitemapTemplate = ejs.compile(fs.readFileSync(sitemapTemplatePath, 'utf8'), { root: [templatePath], filename: sitemapTemplatePath, outputFunctionName: 'echo' });
|
||||
function pagesConfig(pagesKeys) {
|
||||
var pages = {};
|
||||
if (-1 === pagesKeys.indexOf('sitemap')) {
|
||||
pages.sitemap = {
|
||||
staticPage: true,
|
||||
buildExclude: true,
|
||||
title: 'Sitemap',
|
||||
filename: 'sitemap.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: sitemapTemplate({ pages: __spreadArray(__spreadArray([], pagesKeys), Object.keys(pages)) }),
|
||||
},
|
||||
},
|
||||
window: {},
|
||||
render: ''
|
||||
};
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
||||
var merge = require('lodash.merge');
|
||||
function validateBoolean(value, defaultValue) {
|
||||
if (defaultValue === void 0) { defaultValue = false; }
|
||||
if (true === value || false === value) {
|
||||
return value;
|
||||
}
|
||||
if (0 === value || 1 === value) {
|
||||
return !!value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
function validateString(value, defaultValue) {
|
||||
if (defaultValue === void 0) { defaultValue = ''; }
|
||||
return value ? value : defaultValue;
|
||||
}
|
||||
function getArrayType(sourcesArr, pageArr) {
|
||||
if (pageArr === void 0) { pageArr = []; }
|
||||
if ((!sourcesArr || !sourcesArr.length) && (!pageArr || !pageArr.length)) {
|
||||
return [];
|
||||
}
|
||||
if (sourcesArr && sourcesArr.length && pageArr && pageArr.length) {
|
||||
return sourcesArr.concat(pageArr);
|
||||
}
|
||||
if (sourcesArr && sourcesArr.length) {
|
||||
return sourcesArr;
|
||||
}
|
||||
return pageArr;
|
||||
}
|
||||
function formatPagesConfig(sources, pages) {
|
||||
var ret = {};
|
||||
for (var pk in pages) {
|
||||
ret[pk] = {
|
||||
staticPage: validateBoolean(pages[pk].staticPage, false),
|
||||
buildExclude: validateBoolean(pages[pk].buildExclude, false),
|
||||
title: validateString(pages[pk].title, sources.title),
|
||||
filename: validateString(pages[pk].filename, sources.filename),
|
||||
html: {
|
||||
head: {
|
||||
meta: getArrayType(sources.html.head.meta, pages[pk].html.head.meta),
|
||||
links: getArrayType(sources.html.head.links, pages[pk].html.head.links),
|
||||
scripts: getArrayType(sources.html.head.scripts, pages[pk].html.head.scripts),
|
||||
},
|
||||
body: {
|
||||
scripts: getArrayType(sources.html.body.scripts, pages[pk].html.body.scripts),
|
||||
snippet: validateString(pages[pk].html.body.snippet, sources.html.body.snippet),
|
||||
},
|
||||
},
|
||||
window: merge({}, sources.window, pages[pk].window),
|
||||
render: validateString(sources.render, pages[pk].render),
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
var path = require('path');
|
||||
var NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
|
||||
// Webpack plugins.
|
||||
var DefinePlugin = require('webpack').DefinePlugin;
|
||||
var LimitChunkCountPlugin = require('webpack').optimize.LimitChunkCountPlugin;
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
var VirtualModulesPlugin = require('webpack-virtual-modules');
|
||||
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
var ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
var CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
var CopyPlugin = require("copy-webpack-plugin");
|
||||
var dotenv = require('dotenv').config({ path: path.resolve(__dirname + '../../../../.env') });
|
||||
function webpackEntry(env, srcDir, pages) {
|
||||
var ret = {};
|
||||
for (var p in pages) {
|
||||
if ('development' === env || !pages[p].buildExclude) {
|
||||
ret[p] = path.resolve(srcDir + '/' + p + '.js');
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function webpackOutput(env, destinationDir, buildDir, chunkhash, hash) {
|
||||
var ret = {
|
||||
path: destinationDir,
|
||||
filename: '',
|
||||
};
|
||||
var prefix = 'development' === env ? '' : buildDir;
|
||||
var tmp;
|
||||
if (undefined !== chunkhash) {
|
||||
tmp = chunkhash.trim();
|
||||
if ('' === tmp) {
|
||||
throw Error('Invalid chunkhash argument value: ' + chunkhash);
|
||||
}
|
||||
ret.filename = (prefix || '') + '[name]-[chunkhash].js';
|
||||
}
|
||||
else if (undefined !== hash) {
|
||||
tmp = hash.trim();
|
||||
if ('' === tmp) {
|
||||
throw Error('Invalid hash argument value: ' + hash);
|
||||
}
|
||||
ret.filename = (prefix || '') + '[name]-[hash].js';
|
||||
}
|
||||
else {
|
||||
ret.filename = (prefix || '') + '[name].js';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function webpackAlias() {
|
||||
return {
|
||||
// modernizr$: path.resolve(__dirname, "../../.modernizrrc"), // TODO: Enable this?
|
||||
};
|
||||
}
|
||||
function webpackRules(env, srcDir, postcssConfigFile) {
|
||||
return [{
|
||||
test: /\.(jsx|js)?$/,
|
||||
use: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(tsx|ts)?$/,
|
||||
use: 'ts-loader',
|
||||
// exclude: /node_modules/,
|
||||
// options: {
|
||||
// compilerOptions: {
|
||||
// "sourceMap": !isProduction,
|
||||
// },
|
||||
// },
|
||||
},
|
||||
{
|
||||
test: /\.ejs$/,
|
||||
use: {
|
||||
loader: 'ejs-compiled-loader',
|
||||
options: {
|
||||
// beautify: true,
|
||||
htmlmin: true,
|
||||
// htmlminOptions: {
|
||||
// removeComments: true,
|
||||
// collapseWhitespace: true,
|
||||
// preserveLineBreaks: true
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{ loader: MiniCssExtractPlugin.loader },
|
||||
// { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
|
||||
{ loader: 'css-loader', options: { importLoaders: 1 } },
|
||||
{ loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
|
||||
{ loader: 'sass-loader' },
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.module\.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{ loader: MiniCssExtractPlugin.loader },
|
||||
// { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
|
||||
{ loader: 'css-loader', options: { importLoaders: 1, modules: true, onlyLocals: false } },
|
||||
{ loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
|
||||
{ loader: 'sass-loader' },
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif)(\?\S*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 1024,
|
||||
fallback: 'file-loader',
|
||||
name: function (file) {
|
||||
return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
|
||||
/*issuer: {
|
||||
test: /\.jsx?$/
|
||||
},*/
|
||||
use: ['babel-loader', '@svgr/webpack', 'url-loader']
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
|
||||
loader: 'url-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: function (file) {
|
||||
return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
|
||||
},
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.modernizrrc.js$/,
|
||||
use: 'modernizr-loader',
|
||||
},
|
||||
{
|
||||
test: /\.modernizrrc(\.json)?$/,
|
||||
use: ['modernizr-loader', 'json-loader'],
|
||||
}];
|
||||
}
|
||||
function webpackPlugins(env, srcDir, pages, cssSrc) {
|
||||
var ret = [
|
||||
new DefinePlugin({ "process.env": JSON.stringify(dotenv.parsed) }),
|
||||
new NodePolyfillPlugin(),
|
||||
new MyHtmlBeautifyWebpackPlugin(),
|
||||
];
|
||||
if ('development' !== env) {
|
||||
ret.push(new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/lib'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/lib'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/images'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/images'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/favicons'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/favicons'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/css/_extra.css'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/css/_extra.css'),
|
||||
},
|
||||
],
|
||||
}));
|
||||
}
|
||||
var virtualPages = {};
|
||||
var file;
|
||||
for (var k in pages) {
|
||||
if ('production' !== env || !pages[k].buildExclude) {
|
||||
file = path.resolve(srcDir + '/' + k + '.js');
|
||||
if ((void 0 !== pages[k].staticPage && pages[k].staticPage) || void 0 === pages[k].render) {
|
||||
virtualPages[file] = '';
|
||||
}
|
||||
else {
|
||||
virtualPages[file] = pages[k].render;
|
||||
}
|
||||
}
|
||||
if ('development' === env) {
|
||||
// Export pages HTML files.
|
||||
ret.push(new HtmlWebpackPlugin(__assign({ template: path.resolve(__dirname, '../templates/index.ejs'), hash: false, chunks: [k] }, pages[k])));
|
||||
}
|
||||
}
|
||||
ret.push(new VirtualModulesPlugin(virtualPages));
|
||||
ret.push(new MiniCssExtractPlugin({
|
||||
ignoreOrder: true,
|
||||
// filename: ! is_build ? '[name].css' : '[name].[hash].css',
|
||||
// chunkFilename: ! is_build ? '[id].css' : '[id].[hash].css',
|
||||
filename: cssSrc + '[name].css',
|
||||
// chunkFilename: "../css/[id].css",
|
||||
}));
|
||||
if ('development' !== env) {
|
||||
ret.push(new LimitChunkCountPlugin({ maxChunks: 1 }));
|
||||
ret.push(new ProgressBarPlugin({
|
||||
clear: false,
|
||||
}));
|
||||
}
|
||||
if ('production' === env) {
|
||||
ret.push(new CssMinimizerPlugin({
|
||||
cache: true,
|
||||
minimizerOptions: {
|
||||
preset: [
|
||||
'default',
|
||||
{
|
||||
discardComments: { removeAll: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function generateConfig(env, config) {
|
||||
var srcDir = config.src;
|
||||
var buildDir = config.build + '/' + env + ('development' === env ? '' : '/static');
|
||||
var cssbuild = './css/';
|
||||
var jsbuild = './js/';
|
||||
var configPages = config.pages;
|
||||
var configPagesKeys = config.pages ? Object.keys(configPages) : [];
|
||||
var defPages = pagesConfig(configPagesKeys);
|
||||
var pages = formatPagesConfig({ title: '', filename: '', render: '', html: config.html, window: config.window }, __assign(__assign({}, configPages), defPages));
|
||||
var ret = {
|
||||
entry: webpackEntry(env, srcDir, pages),
|
||||
output: 'development' === env ? webpackOutput(env, srcDir, void 0, void 0, void 0) : webpackOutput(env, buildDir, jsbuild, void 0, void 0),
|
||||
plugins: webpackPlugins(env, srcDir, pages, cssbuild),
|
||||
module: {
|
||||
rules: webpackRules(env, srcDir, config.postcssConfigFile),
|
||||
},
|
||||
resolve: {
|
||||
alias: webpackAlias(),
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
||||
},
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
var isAbsolutePath$2 = require('path').isAbsolute;
|
||||
var webpack$2 = require('webpack');
|
||||
var webpackFormatMessages$1 = require('webpack-format-messages');
|
||||
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
var defaultOptions$2 = {
|
||||
env: 'production',
|
||||
host: '127.0.0.1',
|
||||
port: 8888,
|
||||
mode: 'static',
|
||||
config: config$3,
|
||||
};
|
||||
function analyzer(analyzerOptions) {
|
||||
if (analyzerOptions === void 0) { analyzerOptions = defaultOptions$2; }
|
||||
var options = __assign(__assign({}, defaultOptions$2), analyzerOptions);
|
||||
options.config = __assign(__assign({}, defaultOptions$2.config), analyzerOptions.config);
|
||||
var config = generateConfig(options.env, options.config);
|
||||
if (!isAbsolutePath$2(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath$2(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath$2(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
var analyzerConfig = {
|
||||
analyzerMode: options.mode,
|
||||
analyzerHost: options.host,
|
||||
analyzerPort: options.port,
|
||||
generateStatsFile: 'server' !== options.mode,
|
||||
startAnalyzer: 'server' === options.mode,
|
||||
statsFilename: 'analyzer-stats.json',
|
||||
reportFilename: 'analyzer-report.html',
|
||||
};
|
||||
var compiler = 'dist' === options.env ? webpack$2(__assign(__assign({}, config$1), config)) : webpack$2(__assign(__assign({}, config$2), config));
|
||||
var analyzer = new BundleAnalyzerPlugin(analyzerConfig);
|
||||
analyzer.apply(compiler);
|
||||
compiler.run(function (err, stats) {
|
||||
if (err)
|
||||
throw err;
|
||||
var messages = webpackFormatMessages$1(stats);
|
||||
if (!messages.errors.length && !messages.warnings.length) {
|
||||
console.log('Compiled successfully!', '\n');
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
console.log('Failed to compile.', '\n');
|
||||
for (var _i = 0, _a = messages.errors; _i < _a.length; _i++) {
|
||||
var m = _a[_i];
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
else if (messages.warnings.length) {
|
||||
console.log('Compiled with warnings.', '\n');
|
||||
for (var _b = 0, _c = messages.warnings; _b < _c.length; _b++) {
|
||||
var m = _c[_b];
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var isAbsolutePath$1 = require('path').isAbsolute;
|
||||
var webpack$1 = require('webpack');
|
||||
var webpackFormatMessages = require('webpack-format-messages');
|
||||
var defaultOptions$1 = {
|
||||
env: 'production',
|
||||
config: config$3,
|
||||
};
|
||||
function build(buildOptions) {
|
||||
if (buildOptions === void 0) { buildOptions = defaultOptions$1; }
|
||||
var options = __assign(__assign({}, defaultOptions$1), buildOptions);
|
||||
options.config = __assign(__assign({}, defaultOptions$1.config), buildOptions.config);
|
||||
if (!isAbsolutePath$1(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath$1(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath$1(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
var config = generateConfig(options.env, options.config);
|
||||
var compiler = 'dist' === options.env ? webpack$1(__assign(__assign({}, config$1), config)) : webpack$1(__assign(__assign({}, config$2), config));
|
||||
compiler.run(function (err, stats) {
|
||||
if (err)
|
||||
throw err;
|
||||
var messages = webpackFormatMessages(stats);
|
||||
if (!messages.errors.length && !messages.warnings.length) {
|
||||
console.log('Compiled successfully!', '\n');
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
console.log('Failed to compile.', '\n');
|
||||
for (var _i = 0, _a = messages.errors; _i < _a.length; _i++) {
|
||||
var m = _a[_i];
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
else if (messages.warnings.length) {
|
||||
console.log('Compiled with warnings.', '\n');
|
||||
for (var _b = 0, _c = messages.warnings; _b < _c.length; _b++) {
|
||||
var m = _c[_b];
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var config = {
|
||||
mode: 'development',
|
||||
// devtool: 'eval',
|
||||
// devtool: 'source-map',
|
||||
// devtool: 'eval-cheap-source-map',
|
||||
optimization: {
|
||||
minimize: false
|
||||
}
|
||||
};
|
||||
|
||||
function configFunc(contentBase) {
|
||||
return {
|
||||
watchOptions: {
|
||||
poll: true,
|
||||
},
|
||||
contentBase: contentBase,
|
||||
compress: true,
|
||||
hot: true
|
||||
};
|
||||
}
|
||||
|
||||
var isAbsolutePath = require('path').isAbsolute;
|
||||
var webpack = require('webpack');
|
||||
var WebpackDevServer = require('webpack-dev-server');
|
||||
var defaultOptions = {
|
||||
env: 'development',
|
||||
host: '0.0.0.0',
|
||||
port: 8080,
|
||||
config: config$3,
|
||||
};
|
||||
function dev(devOptions) {
|
||||
if (devOptions === void 0) { devOptions = defaultOptions; }
|
||||
var options = __assign(__assign({}, defaultOptions), devOptions);
|
||||
options.config = __assign(__assign({}, defaultOptions.config), devOptions.config);
|
||||
var config$1 = generateConfig(options.env, options.config);
|
||||
if (!isAbsolutePath(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
if (!isAbsolutePath(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
var compilerConfig = __assign(__assign({}, config), config$1);
|
||||
var serverOptions = configFunc(options.config.src);
|
||||
WebpackDevServer.addDevServerEntrypoints(compilerConfig, serverOptions);
|
||||
var compiler = webpack(compilerConfig);
|
||||
var server = new WebpackDevServer(compiler, serverOptions);
|
||||
server.listen(options.port, options.host, function (err) {
|
||||
if (err)
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
exports.analyzer = analyzer;
|
||||
exports.build = build;
|
||||
exports.dev = dev;
|
||||
99
frontend/packages/scripts/lib/.webpack/build.config.ts
Executable file
99
frontend/packages/scripts/lib/.webpack/build.config.ts
Executable file
@@ -0,0 +1,99 @@
|
||||
import { Configuration } from 'webpack';
|
||||
|
||||
/*const chunksCacheGroups_0 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
|
||||
/*const chunksCacheGroups_1 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
// priority: -10,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](!MediaCmsPlayer)[\\/]/,
|
||||
name: "_vendors",
|
||||
// priority: -20,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
// reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
|
||||
/*const chunksCacheGroups_2 = {
|
||||
commons: {
|
||||
minChunks: 2,
|
||||
// maxInitialRequests: 8, // @note: Tested values from 0 to 10, and changes applied with values 0, 4, 5, 6, 7, 8.
|
||||
// minSize: 0,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};*/
|
||||
|
||||
/*const chunksCacheGroups_3 = {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
};*/
|
||||
|
||||
export const config: Configuration = {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
optimization: {
|
||||
runtimeChunk: false,
|
||||
/*splitChunks: {
|
||||
// minSize: 1000000,
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
// minSize: 1000000,
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_0,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_1,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_2,
|
||||
},*/
|
||||
/*splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: chunksCacheGroups_3,
|
||||
},*/
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: '_commons',
|
||||
priority: 1,
|
||||
chunks: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
12
frontend/packages/scripts/lib/.webpack/dev-server.config.ts
Executable file
12
frontend/packages/scripts/lib/.webpack/dev-server.config.ts
Executable file
@@ -0,0 +1,12 @@
|
||||
import { Configuration } from 'webpack-dev-server';
|
||||
|
||||
export function configFunc(contentBase: string): Configuration {
|
||||
return {
|
||||
watchOptions: {
|
||||
poll: true,
|
||||
},
|
||||
contentBase: contentBase,
|
||||
compress: true,
|
||||
hot: true,
|
||||
};
|
||||
}
|
||||
11
frontend/packages/scripts/lib/.webpack/dev.config.ts
Executable file
11
frontend/packages/scripts/lib/.webpack/dev.config.ts
Executable file
@@ -0,0 +1,11 @@
|
||||
import { Configuration } from 'webpack';
|
||||
|
||||
export const config: Configuration = {
|
||||
mode: 'development',
|
||||
// devtool: 'eval',
|
||||
// devtool: 'source-map',
|
||||
// devtool: 'eval-cheap-source-map',
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
};
|
||||
73
frontend/packages/scripts/lib/.webpack/dist.config.ts
Executable file
73
frontend/packages/scripts/lib/.webpack/dist.config.ts
Executable file
@@ -0,0 +1,73 @@
|
||||
import { Configuration } from 'webpack';
|
||||
|
||||
/*const chunksCacheGroups_0 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_1 = {
|
||||
commons: {
|
||||
test: /[\\/]src[\\/]/,
|
||||
name: "_commons",
|
||||
// priority: -10,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
|
||||
// test: /[\\/]node_modules[\\/](!MediaCmsPlayer)[\\/]/,
|
||||
name: "_vendors",
|
||||
// priority: -20,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
// reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_2 = {
|
||||
commons: {
|
||||
minChunks: 2,
|
||||
// maxInitialRequests: 8, // @note: Tested values from 0 to 10, and changes applied with values 0, 4, 5, 6, 7, 8.
|
||||
// minSize: 0,
|
||||
name: "_commons",
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
};
|
||||
|
||||
const chunksCacheGroups_3 = {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "_commons",
|
||||
priority: 1,
|
||||
chunks: "initial",
|
||||
},
|
||||
};*/
|
||||
|
||||
export const config: Configuration = {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
minimize: true,
|
||||
runtimeChunk: false,
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: '_commons',
|
||||
priority: 1,
|
||||
chunks: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
114
frontend/packages/scripts/lib/config.ts
Executable file
114
frontend/packages/scripts/lib/config.ts
Executable file
@@ -0,0 +1,114 @@
|
||||
function bodySnippet(id:string) {
|
||||
return '<div id="' + id + '"></div>';
|
||||
}
|
||||
|
||||
interface ConfigHtmlHead{
|
||||
meta?: { [key: string]: string }[],
|
||||
links?: { [key: string]: string }[],
|
||||
scripts?: { [key: string]: string }[],
|
||||
}
|
||||
|
||||
interface ConfigHtmlBody{
|
||||
scripts: { [key: string]: string }[],
|
||||
snippet: string,
|
||||
}
|
||||
|
||||
export interface ConfigHtml{
|
||||
head: ConfigHtmlHead,
|
||||
body: ConfigHtmlBody,
|
||||
}
|
||||
|
||||
export interface ConfigPages{
|
||||
[key: string]: ConfigPage
|
||||
}
|
||||
|
||||
export interface ConfigWindow{
|
||||
[key: string ]: unknown
|
||||
}
|
||||
|
||||
export interface ConfigType {
|
||||
src: string,
|
||||
build: string,
|
||||
html: ConfigHtml,
|
||||
pages: ConfigPages,
|
||||
window: ConfigWindow,
|
||||
postcssConfigFile: string,
|
||||
}
|
||||
|
||||
export interface ConfigPage{
|
||||
staticPage: boolean,
|
||||
buildExclude: boolean,
|
||||
title: string,
|
||||
filename: string,
|
||||
html: ConfigHtml,
|
||||
window: ConfigWindow,
|
||||
render: string,
|
||||
}
|
||||
|
||||
const homePage: ConfigPage = {
|
||||
staticPage: true,
|
||||
buildExclude: false,
|
||||
title: 'Home',
|
||||
filename: 'index.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: bodySnippet('page-home'),
|
||||
}
|
||||
},
|
||||
window: {},
|
||||
render: 'import { renderPage } from \'./js/helpers\'; import { HomePage } from \'./js/pages/HomePage\'; renderPage( \'page-home\', HomePage );',
|
||||
};
|
||||
|
||||
const errorPage: ConfigPage = {
|
||||
staticPage: true,
|
||||
buildExclude: false,
|
||||
title: 'Error',
|
||||
filename: 'error.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: bodySnippet('page-error'),
|
||||
}
|
||||
},
|
||||
window: {},
|
||||
render: 'import { renderPage } from \'./js/helpers\'; import { ErrorPage } from \'./js/pages/ErrorPage\'; renderPage( \'page-error\', ErrorPage );',
|
||||
};
|
||||
|
||||
const pages: { [key: string]: ConfigPage } = {
|
||||
home: homePage,
|
||||
error: errorPage,
|
||||
};
|
||||
|
||||
const htmlHead: ConfigHtmlHead = {
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ content: 'ie=edge', 'http-equiv': 'x-ua-compatible' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
],
|
||||
links: [],
|
||||
scripts: [],
|
||||
};
|
||||
|
||||
const htmlBody: ConfigHtmlBody = {
|
||||
scripts: [],
|
||||
snippet: '',
|
||||
};
|
||||
|
||||
const html: ConfigHtml = {
|
||||
head: htmlHead,
|
||||
body: htmlBody,
|
||||
};
|
||||
|
||||
export const config : ConfigType = {
|
||||
src: '',
|
||||
build: '',
|
||||
pages,
|
||||
html,
|
||||
window: {},
|
||||
postcssConfigFile: '',
|
||||
};
|
||||
|
||||
export default config;
|
||||
21
frontend/packages/scripts/lib/interfaces/OptionsTypes.ts
Executable file
21
frontend/packages/scripts/lib/interfaces/OptionsTypes.ts
Executable file
@@ -0,0 +1,21 @@
|
||||
import { ConfigType } from '../config';
|
||||
|
||||
export interface DevOptionsType {
|
||||
env: string,
|
||||
host: string,
|
||||
port: number,
|
||||
config: ConfigType,
|
||||
}
|
||||
|
||||
export interface BuildOptionsType {
|
||||
env: string,
|
||||
config: ConfigType,
|
||||
}
|
||||
|
||||
export interface AnalyzerOptionsType {
|
||||
env: string,
|
||||
host: string,
|
||||
port: number,
|
||||
mode: string,
|
||||
config: ConfigType,
|
||||
}
|
||||
69
frontend/packages/scripts/lib/webpack-helpers/formatPagesConfig.ts
Executable file
69
frontend/packages/scripts/lib/webpack-helpers/formatPagesConfig.ts
Executable file
@@ -0,0 +1,69 @@
|
||||
const merge = require('lodash.merge');
|
||||
|
||||
import { ConfigHtml, ConfigPages, ConfigWindow } from '../config';
|
||||
|
||||
function validateBoolean(value?: boolean | 0 | 1, defaultValue = false): boolean {
|
||||
|
||||
if (true === value || false === value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (0 === value || 1 === value) {
|
||||
return !!value;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
function validateString(value?: string, defaultValue = ''): string {
|
||||
return value ? value : defaultValue;
|
||||
}
|
||||
|
||||
function getArrayType(sourcesArr?: Array<{ [key: string]: string }>, pageArr: Array<{ [key: string]: string }> = []): Array<{ [key: string]: string }> {
|
||||
|
||||
if ((!sourcesArr || !sourcesArr.length) && (!pageArr || !pageArr.length)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (sourcesArr && sourcesArr.length && pageArr && pageArr.length) {
|
||||
return sourcesArr.concat(pageArr);
|
||||
}
|
||||
|
||||
if (sourcesArr && sourcesArr.length) {
|
||||
return sourcesArr;
|
||||
}
|
||||
|
||||
return pageArr;
|
||||
}
|
||||
|
||||
function formatPagesConfig(sources: { title: string, filename: string, render: string, html: ConfigHtml, window: ConfigWindow }, pages: ConfigPages): ConfigPages {
|
||||
|
||||
const ret: ConfigPages = {};
|
||||
|
||||
for (const pk in pages) {
|
||||
|
||||
ret[pk] = {
|
||||
staticPage: validateBoolean(pages[pk].staticPage, false),
|
||||
buildExclude: validateBoolean(pages[pk].buildExclude, false),
|
||||
title: validateString(pages[pk].title, sources.title),
|
||||
filename: validateString(pages[pk].filename, sources.filename),
|
||||
html: {
|
||||
head: {
|
||||
meta: getArrayType(sources.html.head.meta, pages[pk].html.head.meta),
|
||||
links: getArrayType(sources.html.head.links, pages[pk].html.head.links),
|
||||
scripts: getArrayType(sources.html.head.scripts, pages[pk].html.head.scripts),
|
||||
},
|
||||
body: {
|
||||
scripts: getArrayType(sources.html.body.scripts, pages[pk].html.body.scripts),
|
||||
snippet: validateString(pages[pk].html.body.snippet, sources.html.body.snippet),
|
||||
},
|
||||
},
|
||||
window: merge({}, sources.window, pages[pk].window),
|
||||
render: validateString(sources.render, pages[pk].render),
|
||||
};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export default formatPagesConfig;
|
||||
308
frontend/packages/scripts/lib/webpack-helpers/generateConfig.ts
Executable file
308
frontend/packages/scripts/lib/webpack-helpers/generateConfig.ts
Executable file
@@ -0,0 +1,308 @@
|
||||
const path = require('path');
|
||||
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
|
||||
|
||||
// Webpack plugins.
|
||||
const { DefinePlugin } = require('webpack');
|
||||
const { LimitChunkCountPlugin } = require('webpack').optimize;
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const VirtualModulesPlugin = require('webpack-virtual-modules');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
|
||||
var dotenv = require('dotenv').config({ path: path.resolve(__dirname + '../../../../.env') });
|
||||
|
||||
import MyHtmlBeautifyWebpackPlugin from '../webpack-plugins/MyHtmlBeautifyWebpackPlugin';
|
||||
|
||||
import { ConfigType, ConfigPages } from '../config';
|
||||
|
||||
import defaultPages from './pagesConfig';
|
||||
|
||||
import formatPagesConfig from './formatPagesConfig';
|
||||
|
||||
function webpackEntry(env: string, srcDir: string, pages: ConfigPages) {
|
||||
|
||||
const ret: { [key: string]: string } = {};
|
||||
|
||||
for (const p in pages) {
|
||||
|
||||
if ('development' === env || !pages[p].buildExclude) {
|
||||
ret[p] = path.resolve(srcDir + '/' + p + '.js');
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function webpackOutput(env: string, destinationDir: string, buildDir?: string, chunkhash?: string, hash?: string) {
|
||||
|
||||
const ret = {
|
||||
path: destinationDir,
|
||||
filename: '',
|
||||
};
|
||||
|
||||
const prefix = 'development' === env ? '' : buildDir;
|
||||
|
||||
let tmp;
|
||||
|
||||
if (undefined !== chunkhash) {
|
||||
|
||||
tmp = chunkhash.trim();
|
||||
|
||||
if ('' === tmp) {
|
||||
throw Error('Invalid chunkhash argument value: ' + chunkhash);
|
||||
}
|
||||
|
||||
ret.filename = (prefix || '') + '[name]-[chunkhash].js';
|
||||
}
|
||||
else if (undefined !== hash) {
|
||||
|
||||
tmp = hash.trim();
|
||||
|
||||
if ('' === tmp) {
|
||||
throw Error('Invalid hash argument value: ' + hash);
|
||||
}
|
||||
|
||||
ret.filename = (prefix || '') + '[name]-[hash].js';
|
||||
}
|
||||
else {
|
||||
ret.filename = (prefix || '') + '[name].js';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function webpackAlias() {
|
||||
|
||||
return {
|
||||
// modernizr$: path.resolve(__dirname, "../../.modernizrrc"), // TODO: Enable this?
|
||||
};
|
||||
}
|
||||
|
||||
function webpackRules(env: string, srcDir: string, postcssConfigFile: string): any[] {
|
||||
|
||||
return [{
|
||||
test: /\.(jsx|js)?$/,
|
||||
use: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(tsx|ts)?$/,
|
||||
use: 'ts-loader',
|
||||
// exclude: /node_modules/,
|
||||
// options: {
|
||||
// compilerOptions: {
|
||||
// "sourceMap": !isProduction,
|
||||
// },
|
||||
// },
|
||||
},
|
||||
{
|
||||
test: /\.ejs$/,
|
||||
use: {
|
||||
loader: 'ejs-compiled-loader',
|
||||
options: {
|
||||
// beautify: true,
|
||||
htmlmin: true,
|
||||
// htmlminOptions: {
|
||||
// removeComments: true,
|
||||
// collapseWhitespace: true,
|
||||
// preserveLineBreaks: true
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{ loader: MiniCssExtractPlugin.loader },
|
||||
// { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
|
||||
{ loader: 'css-loader', options: { importLoaders: 1 } },
|
||||
{ loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
|
||||
{ loader: 'sass-loader' },
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.module\.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{ loader: MiniCssExtractPlugin.loader },
|
||||
// { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
|
||||
{ loader: 'css-loader', options: { importLoaders: 1, modules: true, onlyLocals: false } },
|
||||
{ loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
|
||||
{ loader: 'sass-loader' },
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif)(\?\S*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 1024,
|
||||
fallback: 'file-loader',
|
||||
name: (file: string) => {
|
||||
return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
|
||||
/*issuer: {
|
||||
test: /\.jsx?$/
|
||||
},*/
|
||||
use: ['babel-loader', '@svgr/webpack', 'url-loader']
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
|
||||
loader: 'url-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: (file: string) => {
|
||||
return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
|
||||
},
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.modernizrrc.js$/,
|
||||
use: 'modernizr-loader',
|
||||
},
|
||||
{
|
||||
test: /\.modernizrrc(\.json)?$/,
|
||||
use: ['modernizr-loader', 'json-loader'],
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function webpackPlugins(env: string, srcDir: string, pages: ConfigPages, cssSrc: string) {
|
||||
|
||||
const ret = [
|
||||
new DefinePlugin({ "process.env": JSON.stringify(dotenv.parsed) }),
|
||||
new NodePolyfillPlugin(),
|
||||
new MyHtmlBeautifyWebpackPlugin(),
|
||||
];
|
||||
|
||||
if ('development' !== env) {
|
||||
ret.push(
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/lib'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/lib'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/images'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/images'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/favicons'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/favicons'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(__dirname, '../../../src/static/css/_extra.css'),
|
||||
to: path.resolve(__dirname, '../../../' + env + '/static/css/_extra.css'),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const virtualPages: { [key: string]: string } = {};
|
||||
|
||||
let file: string;
|
||||
|
||||
for (const k in pages) {
|
||||
|
||||
if ('production' !== env || !pages[k].buildExclude) {
|
||||
|
||||
file = path.resolve(srcDir + '/' + k + '.js');
|
||||
|
||||
if ((void 0 !== pages[k].staticPage && pages[k].staticPage) || void 0 === pages[k].render) {
|
||||
virtualPages[file] = '';
|
||||
} else {
|
||||
virtualPages[file] = pages[k].render;
|
||||
}
|
||||
}
|
||||
|
||||
if ('development' === env) {
|
||||
// Export pages HTML files.
|
||||
ret.push(new HtmlWebpackPlugin({
|
||||
template: path.resolve(__dirname, '../templates/index.ejs'),
|
||||
hash: false,
|
||||
chunks: [k],
|
||||
...pages[k],
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
ret.push(new VirtualModulesPlugin(virtualPages));
|
||||
|
||||
ret.push(new MiniCssExtractPlugin({
|
||||
ignoreOrder: true, // TODO: Remove it...
|
||||
// filename: ! is_build ? '[name].css' : '[name].[hash].css',
|
||||
// chunkFilename: ! is_build ? '[id].css' : '[id].[hash].css',
|
||||
filename: cssSrc + '[name].css',
|
||||
// chunkFilename: "../css/[id].css",
|
||||
}));
|
||||
|
||||
if ('development' !== env) {
|
||||
ret.push(new LimitChunkCountPlugin({ maxChunks: 1 }));
|
||||
ret.push(
|
||||
new ProgressBarPlugin({
|
||||
clear: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if ('production' === env) {
|
||||
ret.push(new CssMinimizerPlugin({
|
||||
cache: true, // TODO: Ignore in Webpack 5. Use https://webpack.js.org/configuration/other-options/#cache.
|
||||
minimizerOptions: {
|
||||
preset: [
|
||||
'default',
|
||||
{
|
||||
discardComments: { removeAll: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export default function generateConfig(env: string, config: ConfigType) {
|
||||
|
||||
const srcDir = config.src;
|
||||
const buildDir = config.build + '/' + env + ('development' === env ? '' : '/static');
|
||||
|
||||
const cssbuild = './css/';
|
||||
const jsbuild = './js/';
|
||||
|
||||
const configPages = config.pages;
|
||||
const configPagesKeys = config.pages ? Object.keys(configPages) : [];
|
||||
const defPages = defaultPages(configPagesKeys);
|
||||
|
||||
const pages = formatPagesConfig(
|
||||
{ title: '', filename: '', render: '', html: config.html, window: config.window },
|
||||
{ ...configPages, ...defPages }
|
||||
);
|
||||
|
||||
const ret = {
|
||||
entry: webpackEntry(env, srcDir, pages),
|
||||
output: 'development' === env ? webpackOutput(env, srcDir, void 0, void 0, void 0) : webpackOutput(env, buildDir, jsbuild, void 0, void 0),
|
||||
plugins: webpackPlugins(env, srcDir, pages, cssbuild),
|
||||
module: {
|
||||
rules: webpackRules(env, srcDir, config.postcssConfigFile),
|
||||
},
|
||||
resolve: {
|
||||
alias: webpackAlias(),
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
||||
},
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
37
frontend/packages/scripts/lib/webpack-helpers/pagesConfig.ts
Executable file
37
frontend/packages/scripts/lib/webpack-helpers/pagesConfig.ts
Executable file
@@ -0,0 +1,37 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ejs = require('ejs');
|
||||
|
||||
const templatePath = path.join(__dirname, '../templates');
|
||||
const sitemapTemplatePath = path.join(templatePath, 'sitemap.ejs');
|
||||
|
||||
const sitemapTemplate = ejs.compile(fs.readFileSync(sitemapTemplatePath, 'utf8'), { root: [templatePath], filename: sitemapTemplatePath, outputFunctionName: 'echo' });
|
||||
|
||||
import { ConfigPages } from '../config';
|
||||
|
||||
export default function pagesConfig(pagesKeys: string[]): ConfigPages {
|
||||
|
||||
const pages: ConfigPages = {};
|
||||
|
||||
if (-1 === pagesKeys.indexOf('sitemap')) {
|
||||
|
||||
pages.sitemap = {
|
||||
staticPage: true,
|
||||
buildExclude: true,
|
||||
title: 'Sitemap',
|
||||
filename: 'sitemap.html',
|
||||
html: {
|
||||
head: {},
|
||||
body: {
|
||||
scripts: [],
|
||||
snippet: sitemapTemplate({ pages: [...pagesKeys, ...Object.keys(pages)] }),
|
||||
},
|
||||
},
|
||||
window: {},
|
||||
render: ''
|
||||
};
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
74
frontend/packages/scripts/lib/webpack-plugins/MyHtmlBeautifyWebpackPlugin.ts
Executable file
74
frontend/packages/scripts/lib/webpack-plugins/MyHtmlBeautifyWebpackPlugin.ts
Executable file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @see {link: https://github.com/seeyoulater/html-beautify-webpack-plugin/blob/master/index.js}
|
||||
*/
|
||||
|
||||
const prettify = require('html-prettify');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
const WebpackError = require( 'webpack/lib/WebpackError.js' );
|
||||
|
||||
import { Compiler, Compilation } from 'webpack';
|
||||
|
||||
interface OptionsConfigHtml {
|
||||
end_with_newline: boolean,
|
||||
indent_inner_html: boolean,
|
||||
preserve_newlines: boolean,
|
||||
max_preserve_newlines: number,
|
||||
}
|
||||
|
||||
interface OptionsConfig {
|
||||
indent_size: number,
|
||||
indent_with_tabs: boolean,
|
||||
html: OptionsConfigHtml
|
||||
}
|
||||
|
||||
interface Options{
|
||||
config: OptionsConfig,
|
||||
replace: Array<string|RegExp>
|
||||
}
|
||||
|
||||
interface HtmlWebpackPluginArgs{
|
||||
html: string,
|
||||
plugin: typeof HtmlWebpackPlugin,
|
||||
outputName: string
|
||||
}
|
||||
|
||||
function htmlPluginDataFunction (pluginData: HtmlWebpackPluginArgs, options: Options, callback: (err:typeof WebpackError, arg1: HtmlWebpackPluginArgs) => void) {
|
||||
|
||||
pluginData.html = prettify(
|
||||
options.replace.reduce( (res:string, item: string | RegExp) => res.replace( item instanceof RegExp ? new RegExp(item, 'gi') : item, '' ), pluginData.html )/*,
|
||||
options.config*/
|
||||
);
|
||||
|
||||
callback(null, pluginData);
|
||||
}
|
||||
|
||||
export default class MyHtmlBeautifyWebpackPlugin {
|
||||
|
||||
apply(compiler: Compiler): void {
|
||||
|
||||
const options: Options = {
|
||||
config: { // TODO: Remove it.
|
||||
indent_size: 4,
|
||||
indent_with_tabs: false,
|
||||
html: {
|
||||
end_with_newline: true,
|
||||
indent_inner_html: true,
|
||||
preserve_newlines: true,
|
||||
max_preserve_newlines: 0,
|
||||
}
|
||||
},
|
||||
replace: []
|
||||
};
|
||||
|
||||
function tapAsyncCallback(pluginData: HtmlWebpackPluginArgs, callback: (err:typeof WebpackError, arg1: HtmlWebpackPluginArgs) => void ){
|
||||
return htmlPluginDataFunction (pluginData, options, callback);
|
||||
}
|
||||
|
||||
function tapHookCallback(compilation: Compilation){
|
||||
return HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync( 'MyHtmlBeautifyWebpackPlugin', tapAsyncCallback );
|
||||
}
|
||||
|
||||
compiler.hooks.compilation.tap( 'MyHtmlBeautifyWebpackPlugin', tapHookCallback );
|
||||
}
|
||||
}
|
||||
10148
frontend/packages/scripts/package-lock.json
generated
Normal file
10148
frontend/packages/scripts/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
86
frontend/packages/scripts/package.json
Normal file
86
frontend/packages/scripts/package.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"name": "mediacms-scripts",
|
||||
"version": "0.9.0",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"license": "",
|
||||
"engines": {
|
||||
"node": ">=14.17.0"
|
||||
},
|
||||
"files": [
|
||||
"scripts",
|
||||
"cli.js"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "npx rollup -w -c ./config/watch.config.js",
|
||||
"build": "npx rollup -c ./config/build.config.js",
|
||||
"visual": "npx rollup -c ./config/visual.config.js"
|
||||
},
|
||||
"bin": {
|
||||
"mediacms-scripts": "./cli.js"
|
||||
},
|
||||
"types": "",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.5",
|
||||
"@babel/preset-env": "^7.14.5",
|
||||
"@babel/preset-typescript": "^7.14.5",
|
||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/react": "^17.0.11",
|
||||
"@types/react-dom": "^17.0.7",
|
||||
"axios": "^0.21.1",
|
||||
"babel-core": "^6.26.3",
|
||||
"copy-webpack-plugin": "^9.0.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.51.2",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-typescript2": "^0.30.0",
|
||||
"rollup-plugin-visualizer": "^5.5.0",
|
||||
"serialize-javascript": "^5.0.1",
|
||||
"source-map-loader": "^3.0.0",
|
||||
"ts-loader": "^9.2.3",
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@types/webpack-bundle-analyzer": "^4.4.0",
|
||||
"@types/webpack-dev-server": "^3.11.4",
|
||||
"autoprefixer": "^10.2.6",
|
||||
"babel-loader": "^8.2.2",
|
||||
"css-loader": "^5.2.6",
|
||||
"css-minimizer-webpack-plugin": "^3.0.1",
|
||||
"ejs": "^3.1.6",
|
||||
"ejs-compiled-loader": "^3.1.0",
|
||||
"ejs-loader": "^0.5.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-prettify": "^1.0.3",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"json-loader": "^0.5.7",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"mini-css-extract-plugin": "^1.6.0",
|
||||
"node-polyfill-webpack-plugin": "^1.1.2",
|
||||
"node-sass": "^6.0.0",
|
||||
"postcss": "^8.3.2",
|
||||
"postcss-import": "^14.0.2",
|
||||
"postcss-loader": "^6.1.0",
|
||||
"postcss-modules": "^4.1.3",
|
||||
"postcss-nested": "^5.0.5",
|
||||
"postcss-scss": "^3.0.5",
|
||||
"progress-bar-webpack-plugin": "^2.1.0",
|
||||
"sass-loader": "^12.1.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-format-messages": "^2.0.6",
|
||||
"webpack-virtual-modules": "^0.4.3"
|
||||
},
|
||||
"peerDependenciesMeta": {},
|
||||
"browserslist": {}
|
||||
}
|
||||
5
frontend/packages/scripts/scripts/analyzer.js
Normal file
5
frontend/packages/scripts/scripts/analyzer.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const { analyzer } = require('../dist/webpack-dev-env.js');
|
||||
const parseCliArgs = require('./utils/parseCliArgs.js');
|
||||
const { validateAnalyzerOptions } = require('./utils/validateOptions.js');
|
||||
const options = validateAnalyzerOptions(parseCliArgs(process.argv.slice(2)));
|
||||
analyzer(options);
|
||||
5
frontend/packages/scripts/scripts/build.js
Normal file
5
frontend/packages/scripts/scripts/build.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const { build } = require('../dist/webpack-dev-env.js');
|
||||
const parseCliArgs = require('./utils/parseCliArgs.js');
|
||||
const { validateBuildOptions } = require('./utils/validateOptions.js');
|
||||
const options = validateBuildOptions(parseCliArgs(process.argv.slice(2)));
|
||||
build(options);
|
||||
5
frontend/packages/scripts/scripts/development.js
Normal file
5
frontend/packages/scripts/scripts/development.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const { dev } = require('../dist/webpack-dev-env.js');
|
||||
const parseCliArgs = require('./utils/parseCliArgs.js');
|
||||
const { validateDevOptions } = require('./utils/validateOptions.js');
|
||||
const options = validateDevOptions(parseCliArgs(process.argv.slice(2)));
|
||||
dev(options);
|
||||
20
frontend/packages/scripts/scripts/mkdir.js
Executable file
20
frontend/packages/scripts/scripts/mkdir.js
Executable file
@@ -0,0 +1,20 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var cliArgs = process.argv.slice(2);
|
||||
|
||||
function mkdir_callback(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
var i, dir;
|
||||
|
||||
for (i = 0; i < cliArgs.length; i++) {
|
||||
dir = path.resolve(cliArgs[i]);
|
||||
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, mkdir_callback);
|
||||
}
|
||||
}
|
||||
21
frontend/packages/scripts/scripts/rimraf.js
Normal file
21
frontend/packages/scripts/scripts/rimraf.js
Normal file
@@ -0,0 +1,21 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var rimraf = require('rimraf');
|
||||
|
||||
var cliArgs = process.argv.slice(2);
|
||||
|
||||
function rmdir_callback(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
var i, dir;
|
||||
|
||||
for (i = 0; i < cliArgs.length; i++) {
|
||||
dir = path.resolve(cliArgs[i]);
|
||||
|
||||
if (fs.existsSync(dir)) {
|
||||
rimraf.sync(dir, {}, rmdir_callback);
|
||||
}
|
||||
}
|
||||
21
frontend/packages/scripts/scripts/utils/parseCliArgs.js
Normal file
21
frontend/packages/scripts/scripts/utils/parseCliArgs.js
Normal file
@@ -0,0 +1,21 @@
|
||||
function parseCliArgsFn(cliArgs) {
|
||||
const ret = {};
|
||||
|
||||
let arr;
|
||||
|
||||
for (let arg of cliArgs) {
|
||||
arr = arg.split('--');
|
||||
|
||||
if (2 === arr.length) {
|
||||
arr = arr[1].split('=');
|
||||
|
||||
if (2 === arr.length) {
|
||||
ret[arr[0]] = arr[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
module.exports = parseCliArgsFn;
|
||||
94
frontend/packages/scripts/scripts/utils/validateOptions.js
Normal file
94
frontend/packages/scripts/scripts/utils/validateOptions.js
Normal file
@@ -0,0 +1,94 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function validateDevOptions(options) {
|
||||
if (void 0 !== options.config) {
|
||||
if ('string' !== typeof options.config) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = path.resolve(options.config);
|
||||
|
||||
if (!fs.existsSync(options.config)) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = require(path.resolve(options.config));
|
||||
}
|
||||
|
||||
if (void 0 !== options.env) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
if (void 0 !== options.host) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
if (void 0 !== options.port) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function validateBuildOptions(options) {
|
||||
if (void 0 !== options.config) {
|
||||
if ('string' !== typeof options.config) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = path.resolve(options.config);
|
||||
|
||||
if (!fs.existsSync(options.config)) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = require(path.resolve(options.config));
|
||||
}
|
||||
|
||||
if (void 0 !== options.env) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function validateAnalyzerOptions(options) {
|
||||
if (void 0 !== options.config) {
|
||||
if ('string' !== typeof options.config) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = path.resolve(options.config);
|
||||
|
||||
if (!fs.existsSync(options.config)) {
|
||||
throw Error('Invalid configuration file: ' + options.config);
|
||||
}
|
||||
|
||||
options.config = require(path.resolve(options.config));
|
||||
}
|
||||
|
||||
if (void 0 !== options.env) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
if (void 0 !== options.host) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
if (void 0 !== options.port) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
if (void 0 !== options.mode) {
|
||||
// TODO!
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateDevOptions,
|
||||
validateBuildOptions,
|
||||
validateAnalyzerOptions,
|
||||
};
|
||||
84
frontend/packages/scripts/src/analyzer.ts
Executable file
84
frontend/packages/scripts/src/analyzer.ts
Executable file
@@ -0,0 +1,84 @@
|
||||
const isAbsolutePath = require('path').isAbsolute;
|
||||
|
||||
const webpack = require('webpack');
|
||||
const webpackFormatMessages = require('webpack-format-messages');
|
||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||
|
||||
import { config as defaultConfig } from '../lib/config';
|
||||
|
||||
import { AnalyzerOptionsType } from '../lib/interfaces/OptionsTypes';
|
||||
|
||||
import { config as buildWebpackConfig } from '../lib/.webpack/build.config';
|
||||
import { config as distWebpackConfig } from '../lib/.webpack/dist.config';
|
||||
|
||||
import generateConfig from '../lib/webpack-helpers/generateConfig';
|
||||
|
||||
const defaultOptions: AnalyzerOptionsType = {
|
||||
env: 'production',
|
||||
host: '127.0.0.1',
|
||||
port: 8888,
|
||||
mode: 'static',
|
||||
config: defaultConfig,
|
||||
};
|
||||
|
||||
export function analyzer(analyzerOptions: AnalyzerOptionsType = defaultOptions): void {
|
||||
const options: AnalyzerOptionsType = { ...defaultOptions, ...analyzerOptions };
|
||||
|
||||
options.config = { ...defaultOptions.config, ...analyzerOptions.config };
|
||||
|
||||
const config = generateConfig(options.env, options.config);
|
||||
|
||||
if (!isAbsolutePath(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
|
||||
const analyzerConfig = {
|
||||
analyzerMode: options.mode,
|
||||
analyzerHost: options.host,
|
||||
analyzerPort: options.port,
|
||||
generateStatsFile: 'server' !== options.mode,
|
||||
startAnalyzer: 'server' === options.mode,
|
||||
statsFilename: 'analyzer-stats.json',
|
||||
reportFilename: 'analyzer-report.html',
|
||||
};
|
||||
|
||||
const compiler =
|
||||
'dist' === options.env
|
||||
? webpack({ ...distWebpackConfig, ...config })
|
||||
: webpack({ ...buildWebpackConfig, ...config });
|
||||
const analyzer = new BundleAnalyzerPlugin(analyzerConfig);
|
||||
|
||||
analyzer.apply(compiler);
|
||||
|
||||
compiler.run((err?: Error, stats?: any) => {
|
||||
if (err) throw err;
|
||||
|
||||
const messages = webpackFormatMessages(stats);
|
||||
|
||||
if (!messages.errors.length && !messages.warnings.length) {
|
||||
console.log('Compiled successfully!', '\n');
|
||||
}
|
||||
|
||||
if (messages.errors.length) {
|
||||
console.log('Failed to compile.', '\n');
|
||||
|
||||
for (const m of messages.errors) {
|
||||
console.log(m);
|
||||
}
|
||||
} else if (messages.warnings.length) {
|
||||
console.log('Compiled with warnings.', '\n');
|
||||
|
||||
for (const m of messages.warnings) {
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
67
frontend/packages/scripts/src/build.ts
Executable file
67
frontend/packages/scripts/src/build.ts
Executable file
@@ -0,0 +1,67 @@
|
||||
const isAbsolutePath = require('path').isAbsolute;
|
||||
|
||||
const webpack = require('webpack');
|
||||
const webpackFormatMessages = require('webpack-format-messages');
|
||||
|
||||
import { config as defaultConfig } from '../lib/config';
|
||||
|
||||
import { BuildOptionsType } from '../lib/interfaces/OptionsTypes';
|
||||
|
||||
import { config as buildWebpackConfig } from '../lib/.webpack/build.config';
|
||||
import { config as distWebpackConfig } from '../lib/.webpack/dist.config';
|
||||
|
||||
import generateConfig from '../lib/webpack-helpers/generateConfig';
|
||||
|
||||
const defaultOptions: BuildOptionsType = {
|
||||
env: 'production',
|
||||
config: defaultConfig,
|
||||
};
|
||||
|
||||
export function build(buildOptions: BuildOptionsType = defaultOptions): void {
|
||||
const options: BuildOptionsType = { ...defaultOptions, ...buildOptions };
|
||||
|
||||
options.config = { ...defaultOptions.config, ...buildOptions.config };
|
||||
|
||||
if (!isAbsolutePath(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
|
||||
const config = generateConfig(options.env, options.config);
|
||||
|
||||
const compiler =
|
||||
'dist' === options.env
|
||||
? webpack({ ...distWebpackConfig, ...config })
|
||||
: webpack({ ...buildWebpackConfig, ...config });
|
||||
|
||||
compiler.run((err?: Error, stats?: any) => {
|
||||
if (err) throw err;
|
||||
|
||||
const messages = webpackFormatMessages(stats);
|
||||
|
||||
if (!messages.errors.length && !messages.warnings.length) {
|
||||
console.log('Compiled successfully!', '\n');
|
||||
}
|
||||
|
||||
if (messages.errors.length) {
|
||||
console.log('Failed to compile.', '\n');
|
||||
|
||||
for (const m of messages.errors) {
|
||||
console.log(m);
|
||||
}
|
||||
} else if (messages.warnings.length) {
|
||||
console.log('Compiled with warnings.', '\n');
|
||||
|
||||
for (const m of messages.warnings) {
|
||||
console.log(m);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
52
frontend/packages/scripts/src/dev.ts
Executable file
52
frontend/packages/scripts/src/dev.ts
Executable file
@@ -0,0 +1,52 @@
|
||||
const isAbsolutePath = require('path').isAbsolute;
|
||||
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
|
||||
import { config as defaultConfig } from '../lib/config';
|
||||
|
||||
import { DevOptionsType } from '../lib/interfaces/OptionsTypes';
|
||||
|
||||
import { config as webpackDefaultConfig } from '../lib/.webpack/dev.config';
|
||||
import { configFunc as webpackDefaultServerConfig } from '../lib/.webpack/dev-server.config';
|
||||
|
||||
import generateConfig from '../lib/webpack-helpers/generateConfig';
|
||||
|
||||
const defaultOptions: DevOptionsType = {
|
||||
env: 'development',
|
||||
host: '0.0.0.0',
|
||||
port: 8080,
|
||||
config: defaultConfig,
|
||||
};
|
||||
|
||||
export function dev(devOptions: DevOptionsType = defaultOptions): void {
|
||||
const options: DevOptionsType = { ...defaultOptions, ...devOptions };
|
||||
|
||||
options.config = { ...defaultOptions.config, ...devOptions.config };
|
||||
|
||||
const config = generateConfig(options.env, options.config);
|
||||
|
||||
if (!isAbsolutePath(options.config.src)) {
|
||||
throw Error('"src" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.build)) {
|
||||
throw Error('"build" is not an absolute path');
|
||||
}
|
||||
|
||||
if (!isAbsolutePath(options.config.postcssConfigFile)) {
|
||||
throw Error('"postcssConfigFile" is not an absolute path');
|
||||
}
|
||||
|
||||
const compilerConfig = { ...webpackDefaultConfig, ...config };
|
||||
const serverOptions = webpackDefaultServerConfig(options.config.src);
|
||||
|
||||
WebpackDevServer.addDevServerEntrypoints(compilerConfig, serverOptions);
|
||||
|
||||
const compiler = webpack(compilerConfig);
|
||||
const server = new WebpackDevServer(compiler, serverOptions);
|
||||
|
||||
server.listen(options.port, options.host, (err?: Error) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
3
frontend/packages/scripts/src/index.ts
Executable file
3
frontend/packages/scripts/src/index.ts
Executable file
@@ -0,0 +1,3 @@
|
||||
export * from './analyzer';
|
||||
export * from './build';
|
||||
export * from './dev';
|
||||
6
frontend/packages/scripts/templates/index.ejs
Executable file
6
frontend/packages/scripts/templates/index.ejs
Executable file
@@ -0,0 +1,6 @@
|
||||
<%- include ./partials/variables %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= htmlWebpackPlugin.options.lang %>">
|
||||
<%- include ./partials/head %>
|
||||
<%- include ./partials/body %>
|
||||
</html>
|
||||
92
frontend/packages/scripts/templates/partials/body.ejs
Executable file
92
frontend/packages/scripts/templates/partials/body.ejs
Executable file
@@ -0,0 +1,92 @@
|
||||
<% var item, key %>
|
||||
|
||||
<body>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.unsupportedBrowser) { %>
|
||||
<!-- Unsupported browser -->
|
||||
<style>.unsupported-browser { display: none; }</style>
|
||||
<div class="unsupported-browser">
|
||||
Sorry, your browser is not supported. Please upgrade to the latest version or switch your browser to use this
|
||||
site. See <a href="http://outdatedbrowser.com/">outdatedbrowser.com</a> for options.
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.appMountId) { %>
|
||||
<!-- App mount (single) -->
|
||||
<div id="<%= htmlWebpackPlugin.options.appMountId %>">
|
||||
<% if (htmlWebpackPlugin.options.appMountHtmlSnippet) { %>
|
||||
<%= htmlWebpackPlugin.options.appMountHtmlSnippet %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<% if (Array.isArray(htmlWebpackPlugin.options.appMountIds) && htmlWebpackPlugin.options.appMountIds.length ) { %>
|
||||
<!-- App mount ids (multiple) -->
|
||||
<% for (item of htmlWebpackPlugin.options.appMountIds) { %>
|
||||
<div id="<%= item %>"></div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.html.body.snippet && '' !== htmlWebpackPlugin.options.html.body.snippet ) { %>
|
||||
<!-- Body snippet -->
|
||||
<%- htmlWebpackPlugin.options.html.body.snippet %>
|
||||
<% } %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.window && Object.keys( htmlWebpackPlugin.options.window ).length) { %>
|
||||
<!-- Global object -->
|
||||
<script type="text/javascript">
|
||||
<% for (key in htmlWebpackPlugin.options.window) { %>
|
||||
window['<%= key %>'] = <%- JSON.stringify( htmlWebpackPlugin.options.window[key] ) %>;
|
||||
<% } %>
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
<% if (Array.isArray(htmlWebpackPlugin.options.html.body.scripts) && htmlWebpackPlugin.options.html.body.scripts.length ) { %>
|
||||
<!-- Scripts -->
|
||||
<% for (item of htmlWebpackPlugin.options.html.body.scripts) {
|
||||
%><script<% for (key in item) { %> <%= key %>="<%= item[key] %>"<% } %>></script><%
|
||||
}
|
||||
} %>
|
||||
|
||||
<% if ( Array.isArray(htmlWebpackPlugin.files.chunks) && htmlWebpackPlugin.files.chunks.length ) { %>
|
||||
<!-- Chunks -->
|
||||
<% for (key in htmlWebpackPlugin.files.chunks) {
|
||||
if (htmlWebpackPlugin.files.jsIntegrity) { %>
|
||||
<script
|
||||
src="<%= htmlWebpackPlugin.files.chunks[key].entry %>"
|
||||
type="text/javascript"
|
||||
integrity="<%= htmlWebpackPlugin.files.jsIntegrity[htmlWebpackPlugin.files.js.indexOf(htmlWebpackPlugin.files.chunks[key].entry)] %>"
|
||||
crossorigin="<%= webpackConfig.output.crossOriginLoading %>"></script>
|
||||
<% } else { %>
|
||||
<script src="<%= htmlWebpackPlugin.files.chunks[key].entry %>" type="text/javascript"></script>
|
||||
<% }
|
||||
}
|
||||
} %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.googleAnalytics) { %>
|
||||
|
||||
<!-- Google analytics script -->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
window.GoogleAnalyticsObject='ga';window.ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date;
|
||||
|
||||
<% if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
ga('create','<%= htmlWebpackPlugin.options.googleAnalytics.trackingId %>','auto');
|
||||
<% } else {
|
||||
throw new Error("html-webpack-template requires googleAnalytics.trackingId config");
|
||||
} %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.googleAnalytics.pageViewOnLoad) { %>
|
||||
ga('send','pageview');
|
||||
<% } %>
|
||||
|
||||
</script>
|
||||
|
||||
<script async defer src="https://www.google-analytics.com/analytics.js" type="text/javascript"></script>
|
||||
|
||||
<% } %>
|
||||
|
||||
<!---->
|
||||
|
||||
</body>
|
||||
32
frontend/packages/scripts/templates/partials/head.ejs
Executable file
32
frontend/packages/scripts/templates/partials/head.ejs
Executable file
@@ -0,0 +1,32 @@
|
||||
<% var item, key %>
|
||||
|
||||
<head>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.title) { %>
|
||||
<!-- Title -->
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<% } %>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.baseUrl) { %>
|
||||
<!-- Base -->
|
||||
<base href="<%= htmlWebpackPlugin.options.baseUrl %>">
|
||||
<% } %>
|
||||
|
||||
<% if (Array.isArray(htmlWebpackPlugin.options.html.head.meta) && htmlWebpackPlugin.options.html.head.meta.length ) { %>
|
||||
<!-- Meta -->
|
||||
<% for (item of htmlWebpackPlugin.options.html.head.meta) { %><meta<% for (key in item) { %> <%= key %>="<%= item[key] %>"<% } %> /><% }
|
||||
} %>
|
||||
|
||||
<% if (Array.isArray(htmlWebpackPlugin.options.html.head.links) && htmlWebpackPlugin.options.html.head.links.length ) { %>
|
||||
<!-- Links -->
|
||||
<% for (item of htmlWebpackPlugin.options.html.head.links) { %><link<% for (key in item) { %> <%= key %>="<%= item[key] %>"<% } %> /><% }
|
||||
} %>
|
||||
|
||||
<% if (Array.isArray(htmlWebpackPlugin.options.html.head.scripts) && htmlWebpackPlugin.options.html.head.scripts.length ) { %>
|
||||
<!-- Scripts -->
|
||||
<% for (item of htmlWebpackPlugin.options.html.head.scripts) { %>
|
||||
<script<% for (key in item) { %> <%= key %>="<%= item[key] %>"<% } %>></script><%
|
||||
}
|
||||
} %>
|
||||
|
||||
</head>
|
||||
25
frontend/packages/scripts/templates/partials/variables.ejs
Executable file
25
frontend/packages/scripts/templates/partials/variables.ejs
Executable file
@@ -0,0 +1,25 @@
|
||||
<% htmlWebpackPlugin.options.appMountId = htmlWebpackPlugin.options.appMountId || null %>
|
||||
<% htmlWebpackPlugin.options.appMountIds = htmlWebpackPlugin.options.appMountIds || [] %>
|
||||
|
||||
<% htmlWebpackPlugin.options.files = htmlWebpackPlugin.options.files || [] %>
|
||||
<% htmlWebpackPlugin.options.files.chunks = htmlWebpackPlugin.options.files.chunks || [] %>
|
||||
<% htmlWebpackPlugin.options.files.jsIntegrity = htmlWebpackPlugin.options.files.jsIntegrity || false %>
|
||||
|
||||
<% htmlWebpackPlugin.options.unsupportedBrowser = htmlWebpackPlugin.options.unsupportedBrowser || false %>
|
||||
|
||||
<% htmlWebpackPlugin.options.lang = htmlWebpackPlugin.options.lang || "en" %>
|
||||
|
||||
<% htmlWebpackPlugin.options.html = htmlWebpackPlugin.options.html || {} %>
|
||||
|
||||
<% htmlWebpackPlugin.options.html.head = htmlWebpackPlugin.options.html.head || {} %>
|
||||
<% htmlWebpackPlugin.options.html.head.meta = htmlWebpackPlugin.options.html.head.meta || [] %>
|
||||
<% htmlWebpackPlugin.options.html.head.links = htmlWebpackPlugin.options.html.head.links || [] %>
|
||||
<% htmlWebpackPlugin.options.html.head.scripts = htmlWebpackPlugin.options.html.head.scripts || [] %>
|
||||
|
||||
<% htmlWebpackPlugin.options.html.body = htmlWebpackPlugin.options.html.body || {} %>
|
||||
<% htmlWebpackPlugin.options.html.body.scripts = htmlWebpackPlugin.options.html.body.scripts || [] %>
|
||||
<% htmlWebpackPlugin.options.html.body.snippet = htmlWebpackPlugin.options.html.body.snippet || '' %>
|
||||
|
||||
<% htmlWebpackPlugin.options.window = htmlWebpackPlugin.options.window || {} %>
|
||||
|
||||
<% htmlWebpackPlugin.options.googleAnalytics = htmlWebpackPlugin.options.googleAnalytics || false %>
|
||||
23
frontend/packages/scripts/templates/sitemap.ejs
Executable file
23
frontend/packages/scripts/templates/sitemap.ejs
Executable file
@@ -0,0 +1,23 @@
|
||||
<% pages = pages || [] %>
|
||||
|
||||
<% if (pages.length) { %>
|
||||
|
||||
<div id="app-header"></div>
|
||||
<div id="app-sidebar"></div>
|
||||
|
||||
<div class="page-main-wrap">
|
||||
<div class="page-main-inner">
|
||||
<div class="custom-page-wrapper">
|
||||
<h2>Sitemap</h2>
|
||||
<hr>
|
||||
<h3>Pages</h3>
|
||||
<ol>
|
||||
<% for (p of pages) { %>
|
||||
<li><a href="./<%= p %>.html"><%= p %></a></li>
|
||||
<% } %>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% } %>
|
||||
71
frontend/packages/scripts/tsconfig.json
Executable file
71
frontend/packages/scripts/tsconfig.json
Executable file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"include":["lib/**/*", "src/**/*"],
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
"allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
//"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "declarationDir": "./dist/types",
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
// "outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user