chunks markup, lazy imports, minimizer for imgs

This commit is contained in:
Kawanaao 2023-12-03 13:18:25 +02:00
parent bea605b17c
commit b1492acaea
No known key found for this signature in database
GPG key ID: 5B7A8DDCE861E7DC
12 changed files with 4009 additions and 1205 deletions

View file

@ -1,20 +0,0 @@
{
"presets": [
"@babel/env",
"@babel/react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-runtime",
[
"babel-plugin-direct-import",
{
"modules": [
"@mui/lab",
"@mui/material",
"@mui/x-date-pickers"
]
}
]
]
}

17
.babelrc.js Normal file
View file

@ -0,0 +1,17 @@
module.exports = {
compact: false,
presets: [
"@babel/env",
"@babel/react",
"@babel/preset-typescript"
],
plugins: [
"@babel/plugin-transform-runtime",
["import", {
libraryName: "redux",
libraryDirectory: "src",
camel2DashComponentName: false,
transformToDefaultImport: true
}, "redux"]
]
}

View file

@ -1,12 +1,12 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useState } from 'react'; import { useState, lazy } from 'react';
// material-ui // material-ui
import { Box, CardActions, Collapse, Divider, IconButton, Tooltip } from '@mui/material'; import { Box, CardActions, Collapse, Divider, IconButton, Tooltip } from '@mui/material';
// third-party // third-party
import { CopyToClipboard } from 'react-copy-to-clipboard'; import { CopyToClipboard } from 'react-copy-to-clipboard';
import reactElementToJSXString from 'react-element-to-jsx-string'; const reactElementToJSXString = lazy(() => import('react-element-to-jsx-string'));
// project import // project import
import SyntaxHighlight from '../../utils/SyntaxHighlight'; import SyntaxHighlight from '../../utils/SyntaxHighlight';

View file

@ -5,7 +5,7 @@ import { Stack, Chip, useTheme } from '@mui/material';
// project import // project import
import DrawerHeaderStyled from './DrawerHeaderStyled'; import DrawerHeaderStyled from './DrawerHeaderStyled';
import Logo from '../../../../components/Logo'; import Logo from '../../../../components/Logo';
import {version} from '../../../../../../package.json'; import packageInfo from '../../../../../../package.json';
// ==============================|| DRAWER HEADER ||============================== // // ==============================|| DRAWER HEADER ||============================== //
@ -17,7 +17,7 @@ const DrawerHeader = ({ open }) => {
<Stack direction="row" spacing={1} alignItems="center"> <Stack direction="row" spacing={1} alignItems="center">
<Logo /> <Logo />
<Chip <Chip
label={version.replace('unstable', '')} label={packageInfo.version.replace('unstable', '')}
size="small" size="small"
sx={{ height: 16, '& .MuiChip-label': { fontSize: '0.55rem', py: 0.25 } }} sx={{ height: 16, '& .MuiChip-label': { fontSize: '0.55rem', py: 0.25 } }}
component="a" component="a"

View file

@ -23,8 +23,8 @@ import {
import MainCard from '../../../components/MainCard'; import MainCard from '../../../components/MainCard';
// third-party // third-party
const ReactApexChart = lazy(() => import('react-apexcharts'));
import { FormaterForMetric, formatDate, toUTC } from './utils'; import { FormaterForMetric, formatDate, toUTC } from './utils';
const ReactApexChart = lazy(() => import('react-apexcharts'));
import * as API from '../../../api'; import * as API from '../../../api';

View file

@ -14,7 +14,7 @@ import { ServAppIcon } from "../../utils/servapp-icon";
import { useClientInfos } from "../../utils/hooks"; import { useClientInfos } from "../../utils/hooks";
import { FormaterForMetric, formatDate } from "../dashboard/components/utils"; import { FormaterForMetric, formatDate } from "../dashboard/components/utils";
import MiniPlotComponent from "../dashboard/components/mini-plot"; import MiniPlotComponent from "../dashboard/components/mini-plot";
const ReactApexChart = lazy(() => import('react-apexcharts')); const Chart = lazy(() => import('react-apexcharts'));
export const HomeBackground = () => { export const HomeBackground = () => {
@ -394,7 +394,7 @@ const HomePage = () => {
<div>{coStatus.AVX ? "AVX Supported" : "No AVX Support"}</div> <div>{coStatus.AVX ? "AVX Supported" : "No AVX Support"}</div>
</Stack> </Stack>
<div style={{height: '97px'}}> <div style={{height: '97px'}}>
<ReactApexChart <Chart
options={optionsRadial} options={optionsRadial}
// series={[parseInt( // series={[parseInt(
// coStatus.resources.ram / (coStatus.resources.ram + coStatus.resources.ramFree) * 100 // coStatus.resources.ram / (coStatus.resources.ram + coStatus.resources.ramFree) * 100
@ -417,7 +417,7 @@ const HomePage = () => {
<div>used: <strong>{latestRAM}</strong></div> <div>used: <strong>{latestRAM}</strong></div>
</Stack> </Stack>
<div style={{height: '97px'}}> <div style={{height: '97px'}}>
<ReactApexChart <Chart
options={optionsRadial} options={optionsRadial}
// series={[parseInt( // series={[parseInt(
// coStatus.resources.ram / (coStatus.resources.ram + coStatus.resources.ramFree) * 100 // coStatus.resources.ram / (coStatus.resources.ram + coStatus.resources.ramFree) * 100

View file

@ -30,7 +30,7 @@ import { CosmosCollapse, CosmosFormDivider, CosmosInputPassword, CosmosInputText
import VolumeContainerSetup from './volumes'; import VolumeContainerSetup from './volumes';
import DockerContainerSetup from './setup'; import DockerContainerSetup from './setup';
import whiskers from 'whiskers'; import whiskers from 'whiskers';
import {version} from '../../../../../package.json'; import packageInfo from '../../../../../package.json';
import cmp from 'semver-compare'; import cmp from 'semver-compare';
import { HostnameChecker, getHostnameFromName } from '../../../utils/routes'; import { HostnameChecker, getHostnameFromName } from '../../../utils/routes';
import { CosmosContainerPicker } from '../../config/users/containerPicker'; import { CosmosContainerPicker } from '../../config/users/containerPicker';
@ -73,7 +73,7 @@ const preStyle = {
} }
const isNewerVersion = (minver) => { const isNewerVersion = (minver) => {
return cmp(version, minver) === -1; return cmp(packageInfo.version, minver) === -1;
} }
const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaultName }) => { const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaultName }) => {

4953
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -17,17 +17,15 @@
"@mui/material": "^5.14.19", "@mui/material": "^5.14.19",
"@mui/x-date-pickers": "^6.18.0", "@mui/x-date-pickers": "^6.18.0",
"@reduxjs/toolkit": "^1.8.5", "@reduxjs/toolkit": "^1.8.5",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@vitejs/plugin-react": "^3.1.0",
"apexcharts": "^3.35.5", "apexcharts": "^3.35.5",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"express": "^4.18.2", "express": "^4.18.2",
"formik": "^2.2.9", "formik": "^2.2.9",
"framer-motion": "^7.3.6", "framer-motion": "^4.1.17",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"lodash.merge": "^4.6.2", "lodash.merge": "^4.6.2",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
@ -51,7 +49,6 @@
"simplebar": "^5.3.8", "simplebar": "^5.3.8",
"simplebar-react": "^2.4.1", "simplebar-react": "^2.4.1",
"timeago.js": "^4.0.2", "timeago.js": "^4.0.2",
"vite": "^4.2.0",
"web-vitals": "^3.0.2", "web-vitals": "^3.0.2",
"whiskers": "^0.4.0", "whiskers": "^0.4.0",
"yup": "^0.32.11" "yup": "^0.32.11"
@ -107,22 +104,37 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.23.4",
"@babel/core": "^7.23.5", "@babel/core": "^7.23.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.23.4", "@babel/plugin-transform-runtime": "^7.23.4",
"@babel/preset-env": "^7.23.5", "@babel/preset-env": "^7.23.5",
"@babel/preset-flow": "^7.23.3",
"@babel/preset-react": "^7.23.3", "@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "^7.23.3", "@babel/preset-typescript": "^7.23.3",
"@swc/core": "^1.3.100", "@swc/core": "^1.3.100",
"@testing-library/jest-dom": "^6.1.5",
"@testing-library/react": "^14.1.2",
"@types/js-yaml": "^4.0.9",
"@types/lodash.merge": "^4.6.9", "@types/lodash.merge": "^4.6.9",
"@types/react-color": "^3.0.10", "@types/react-color": "^3.0.10",
"@types/webpack-bundle-analyzer": "^4.6.3",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"babel-plugin-direct-import": "^1.0.0", "babel-plugin-direct-import": "^1.0.0",
"babel-plugin-import": "^1.13.8",
"babel-plugin-transform-runtime": "^6.23.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
"css-loader": "^6.8.1", "css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1", "css-minimizer-webpack-plugin": "^5.0.1",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.3", "html-webpack-plugin": "^5.5.3",
"image-minimizer-webpack-plugin": "^3.8.3",
"imagemin": "^8.0.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-svgo": "^10.0.1",
"inspectpack": "^4.7.1", "inspectpack": "^4.7.1",
"mini-css-extract-plugin": "^2.7.6", "mini-css-extract-plugin": "^2.7.6",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
@ -132,7 +144,7 @@
"sass-loader": "^13.3.2", "sass-loader": "^13.3.2",
"stream-browserify": "^3.0.0", "stream-browserify": "^3.0.0",
"style-loader": "^3.3.3", "style-loader": "^3.3.3",
"typescript": "^5.3.2", "svgo": "^3.0.5",
"util": "^0.12.5", "util": "^0.12.5",
"webpack": "^5.89.0", "webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.10.1", "webpack-bundle-analyzer": "^4.10.1",

View file

@ -14,7 +14,8 @@
"moduleResolution": "node", "moduleResolution": "node",
"rootDir": "client/src", "rootDir": "client/src",
"resolveJsonModule": true, "resolveJsonModule": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true,
"esModuleInterop": true
}, },
"include": ["client/src/**/*"], "include": ["client/src/**/*"],
"exclude": ["client/**/*.demo*"] "exclude": ["client/**/*.demo*"]

View file

@ -1,20 +0,0 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
root: 'client',
build: {
outDir: '../static',
},
server: {
proxy: {
'/cosmos/api': {
target: 'https://localhost:8443',
secure: false,
ws: true,
}
}
}
})

View file

@ -1,23 +1,47 @@
const { IgnorePlugin } = require('webpack') const { dependencies, peerDependencies } = require("./package.json")
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') const { IgnorePlugin } = require("webpack")
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer")
const { DuplicatesPlugin } = require("inspectpack/plugin"); const { DuplicatesPlugin } = require("inspectpack/plugin");
const TerserPlugin = require('terser-webpack-plugin'); const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const path = require("path")
const path = require('path'); const dependenciesList = Object.keys(dependencies).concat(Object.keys(peerDependencies))
const cacheGroups = {
react: listNodeModulesRegExp(
dependenciesList.filter(dependency => dependency.includes("react"))
.filter(dependency => ![
"react-syntax-highlighter",
"react-element-to-jsx-string",
"react-intersection-observer",
"react-device-detect",
"react-apexcharts",
"react-copy-to-clipboard"
].includes(dependency))
),
highlighter: listNodeModulesRegExp(["react-syntax-highlighter", "react-element-to-jsx-string", "react-copy-to-clipboard"]),
plot: listNodeModulesRegExp(["react-intersection-observer"]),
simpleBar: listNodeModulesRegExp(["react-device-detect"]),
charts: listNodeModulesRegExp(["react-apexcharts", "apexcharts"]),
mui: listNodeModulesRegExp(dependenciesList.filter(dependency => dependency.includes("mui")))
};
module.exports = { module.exports = {
entry: './client/src/index', entry: "./client/src/index",
performance: {
hints: false
},
module: { module: {
rules: [ rules: [
{ {
test: /\.(ts|tsx|js|jsx|mjs|cjs)$/i, test: /\.(ts|ts|js|js|mjs|cjs)x?$/i,
use: { use: {
loader: 'babel-loader', loader: "babel-loader",
options: { options: {
cacheCompression: true cacheCompression: true,
} }
}, },
exclude: /node_modules/, exclude: /node_modules/,
@ -25,59 +49,75 @@ module.exports = {
{ {
test: /\.s[ac]ss$/i, test: /\.s[ac]ss$/i,
use: [ use: [
"sass-loader",
MiniCssExtractPlugin.loader, MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { modules: true } }, {
'sass-loader', loader: "css-loader", options: {
importLoaders: 1,
modules: true
}
}
], ],
}, },
{ {
test: /\.css$/i, test: /\.css$/i,
use: ['style-loader', { loader: 'css-loader', options: { modules: true } },], use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader", options: {
importLoaders: 1,
modules: true
}
},
],
}, },
{ {
test: /\.(jpe?g|png|gif|svg)$/i, test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader', type: "asset",
} }
], ],
}, },
resolve: { resolve: {
extensions: ['.*', '.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'], extensions: [".*", ".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"],
fallback: { fallback: {
'stream': require.resolve('stream-browserify'), "stream": require.resolve("stream-browserify"),
'crypto': require.resolve('crypto-browserify'), "crypto": require.resolve("crypto-browserify"),
'path': require.resolve('path-browserify'), "path": require.resolve("path-browserify"),
'buffer': require.resolve('buffer/'), "buffer": require.resolve("buffer/"),
'util': require.resolve('util/'), "util": require.resolve("util/"),
'fs': false "fs": false
}, },
alias: { alias: {
'bn.js': require.resolve('bn.js'), "bn.js": require.resolve("bn.js"),
'isarray': require.resolve('isarray'), "isarray": require.resolve("isarray"),
'level-fix-range': require.resolve('level-fix-range'), "level-fix-range": require.resolve("level-fix-range"),
'object-keys': require.resolve('object-keys'), "object-keys": require.resolve("object-keys"),
'prr': require.resolve('prr'), "prr": require.resolve("prr"),
'react-is': require.resolve('react-is'), "react-is": require.resolve("react-is"),
'safe-buffer': require.resolve('safe-buffer'), "safe-buffer": require.resolve("safe-buffer"),
'string_decoder': require.resolve('string_decoder'), "string_decoder": require.resolve("string_decoder"),
'xtend': require.resolve('xtend') "xtend": require.resolve("xtend"),
"framer-motion": require.resolve("framer-motion")
} }
}, },
plugins: [ plugins: [
new MiniCssExtractPlugin(),
new IgnorePlugin({ new IgnorePlugin({
resourceRegExp: /[\d\D]*.demo[\d\D]*/ resourceRegExp: /[\d\D]*.demo[\d\D]*/
}), }),
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: path.join(__dirname, 'client', 'index.html'), template: path.join(__dirname, "client", "index.html"),
filename: 'index.[contenthash].html' filename: "index.[contenthash].html"
}), }),
new BundleAnalyzerPlugin(), new BundleAnalyzerPlugin(),
new DuplicatesPlugin({ new DuplicatesPlugin({
emitErrors: false, emitErrors: true,
verbose: false verbose: true
}) })
], ],
output: { output: {
path: path.resolve(__dirname, 'client/dist'), path: path.resolve(__dirname, "client/dist"),
clean: true
}, },
optimization: { optimization: {
chunkIds: 'total-size', chunkIds: 'total-size',
@ -85,10 +125,13 @@ module.exports = {
mergeDuplicateChunks: true, mergeDuplicateChunks: true,
portableRecords: true, portableRecords: true,
sideEffects: true, sideEffects: true,
concatenateModules: true,
splitChunks: { splitChunks: {
chunks: 'all', chunks: "all",
cacheGroups
}, },
usedExports: true, usedExports: true,
minimize: true,
minimizer: [ minimizer: [
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
new TerserPlugin({ new TerserPlugin({
@ -96,19 +139,37 @@ module.exports = {
terserOptions: { terserOptions: {
mangle: true, mangle: true,
compress: true, compress: true,
sourceMap: false, format: {
comments: false
},
sourceMap: false
} }
}), }),
new TerserPlugin({ new ImageMinimizerPlugin({
minify: TerserPlugin.uglifyJsMinify minimizer: {
}), implementation: ImageMinimizerPlugin.imageminMinify,
new TerserPlugin({ options: {
minify: TerserPlugin.esbuildMinify plugins: [
}), ["gifsicle", { interlaced: true }],
new TerserPlugin({ ["jpegtran", { progressive: true }],
minify: TerserPlugin.terserMinify ["optipng", { optimizationLevel: 5 }],
}), [
"svgo",
{
multipass: true,
plugins: [
"preset-default"
],
},
],
]
}
}
})
] ]
} }
}; };
function listNodeModulesRegExp(deps) {
return new RegExp(`[\\/]node_modules[\\/]${deps.join("|")}`);
};