调整文件格式,删除系统监控

This commit is contained in:
icssoa 2021-03-12 21:46:15 +08:00
parent 790e1519cc
commit 59294ba61d
12 changed files with 18 additions and 1338 deletions

View File

@ -3,4 +3,4 @@
/node_modules/
/src/icons/svg/
/mock/
vue.config.js
vue.config.js

View File

@ -10,8 +10,8 @@
},
"dependencies": {
"axios": "^0.21.1",
"cl-admin": "^1.3.2",
"cl-admin-crud": "^1.4.4",
"cl-admin": "^1.3.3",
"cl-admin-crud": "^1.4.5",
"cl-admin-theme": "^0.0.3",
"clipboard": "^2.0.7",
"codemirror": "^5.59.4",

View File

@ -1,28 +0,0 @@
import VueEcharts from "vue-echarts";
function unit_size(v) {
if (v === 0) return "0 B";
let k = 1024;
let sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
let i = Math.floor(Math.log(v) / Math.log(k));
return (v / Math.pow(k, i)).toPrecision(3) + " " + sizes[i];
}
export default {
components: {
VueEcharts
},
filters: {
unit_size,
fixed2(v) {
return v ? parseFloat(parseFloat(v).toFixed(2)) : 0;
}
},
methods: {
conByte: unit_size
}
};

View File

@ -1,253 +0,0 @@
<template>
<div class="ct">
<el-row :gutter="20">
<el-col :lg="6" :md="12" :xs="24">
<div class="block">
<p class="label">负载状态</p>
<el-popover width="100" trigger="hover">
<div class="system-perf-progress-popover">
<ul>
<li>CPU{{ cpu.perc | fixed2 }} %</li>
<li>内存{{ mem.perc | fixed2 }} %</li>
</ul>
</div>
<el-progress
slot="reference"
type="circle"
:percentage="lb.perc | fixed2"
:color="lb.perc | status_color"
></el-progress>
</el-popover>
</div>
</el-col>
<el-col :lg="6" :md="12" :xs="24">
<div class="block">
<p class="label">CPU存使用率</p>
<el-progress
type="circle"
:percentage="cpu.perc | fixed2"
:color="cpu.perc | status_color"
></el-progress>
</div>
</el-col>
<el-col :lg="6" :md="12" :xs="24">
<div class="block">
<p class="label">内存使用率</p>
<el-popover width="100" trigger="hover">
<div class="system-perf-progress-popover">
<ul>
<li>总数{{ mem.total | unit_size }}</li>
<li>已使用{{ mem.used | unit_size }}</li>
</ul>
</div>
<el-progress
slot="reference"
type="circle"
:percentage="mem.perc | fixed2"
:color="mem.perc | status_color"
></el-progress>
</el-popover>
</div>
</el-col>
<el-col :lg="6" :md="12" :xs="24" v-for="(item, index) in disk.list" :key="index">
<div class="block">
<p class="label">{{ item.mount }}</p>
<el-popover width="100" trigger="hover">
<div class="system-perf-progress-popover">
<ul>
<li>总数{{ item.size | unit_size }}</li>
<li>已使用{{ item.used | unit_size }}</li>
</ul>
</div>
<el-progress
slot="reference"
type="circle"
:percentage="item.use | fixed2"
:color="item.use | status_color"
></el-progress>
</el-popover>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import Common from "./common";
export default {
filters: {
status_color(v) {
if (v < 50) {
return "#67C23A";
}
if (v < 70) {
return "#E6A23C";
}
if (v < 100) {
return "#F56C6C";
}
}
},
mixins: [Common],
data() {
return {
lb: {
perc: 0
},
redis: {
options: {},
perc: 0
},
mysql: {
options: {},
number: 0,
perc: 0
},
cpu: {
options: {},
perc: 0
},
mem: {
perc: 0,
total: 0,
used: 0
},
disk: {
list: [],
all: 0
}
};
},
methods: {
refresh(res) {
const { data } = res;
const item = data[data.length - 1];
this.toMysql(res, item.mysql);
this.toRedis(res, item.redis);
this.toCPU(res, item.server.cpu);
this.toDisk(item.server.disk.filter(e => e.size));
this.toMem(item.server.mem);
this.toLB();
},
toLB() {
let mem = this.mem.perc;
let cpu = this.cpu.perc;
if (mem >= 90) {
this.lb.perc = mem;
} else if (cpu >= 80) {
this.lb.perc = cpu;
} else {
this.lb.perc = mem * 0.4 + cpu * 0.6;
}
},
toCPU(undefined, cpu) {
this.cpu.perc = cpu.currentload;
},
toMem(mem) {
this.mem.perc = (mem.buffcache / mem.total) * 100;
this.mem.total = mem.total;
this.mem.used = mem.buffcache;
},
toDisk(disk) {
this.disk.all = disk.reduce((a, b) => a + b.size, 0);
this.disk.list = disk.map(e => {
e.use = e.use.toFixed(2);
return e;
});
},
toRedis(undefined, item) {
this.redis.perc = parseFloat(item.Memory.used_memory_dataset_perc);
},
toMysql(undefined, item) {
let free = 0;
let used = 0;
item.mysqlSize.forEach(e => {
free += parseFloat(e.data_free);
used += parseFloat(e.data_size);
});
this.mysql.number = item.mysqlSize.length;
this.mysql.perc = (used / (free + used)).toFixed(2);
}
}
};
</script>
<style lang="scss">
.system-perf-progress-popover {
ul {
li {
list-style: none;
line-height: 30px;
}
}
}
</style>
<style lang="scss" scoped>
.ct {
background-color: #fff;
.block {
background-color: #fff;
width: 100%;
border-radius: 3px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 20px;
box-sizing: border-box;
position: relative;
height: 220px;
cursor: pointer;
.label {
font-size: 16px;
height: 40px;
}
.perc {
position: absolute;
padding: 5px 10px;
background-color: #fff;
}
.c {
height: 50px;
.echarts {
height: 100%;
width: 100%;
}
}
}
}
</style>

View File

@ -1,275 +0,0 @@
<template>
<div class="perf-mysql">
<p class="title">Mysql</p>
<el-row class="fn">
<el-col :span="8">
<div class="block">
<div class="icon _disk">
<icon-svg name="perf-disk"></icon-svg>
</div>
<ul class="b">
<li>
<p>已使用</p>
<p>{{ data_size }}</p>
</li>
</ul>
</div>
</el-col>
<el-col :span="8">
<div class="block">
<div class="icon _cache">
<icon-svg name="perf-cache"></icon-svg>
</div>
<ul class="b">
<li>
<p>缓存数</p>
<p>{{ Threads_cached }}</p>
</li>
</ul>
</div>
</el-col>
<el-col :span="8">
<div class="block">
<div class="icon _connect">
<icon-svg name="perf-connect"></icon-svg>
</div>
<ul class="b">
<li>
<p>连接数</p>
<p>{{ Threads_connected }}</p>
</li>
</ul>
</div>
</el-col>
</el-row>
<vue-echarts ref="chart" :options="chartOptions" autoresize></vue-echarts>
</div>
</template>
<script>
import echarts from "echarts";
import Common from "./common";
export default {
mixins: [Common],
data() {
return {
chartOptions: {},
Threads_connected: 0,
Threads_cached: 0,
data_size: 0
};
},
methods: {
refresh({ data, time }) {
const item = data[data.length - 1];
const { mysqlConn, mysqlSize } = item.mysql;
this.Threads_cached = mysqlConn[0].Threads_cached;
this.Threads_connected = mysqlConn[1].Threads_connected;
this.data_size = mysqlSize.reduce((a, b) => a + parseFloat(b.data_size), 0) + "mb";
this.chartOptions = this.onChart(
time,
data.map(e => e.mysql.mysqlConn[3].Threads_running)
);
},
onChart(x, y) {
return {
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: {
color: "rgb(15, 75, 111)"
}
},
backgroundColor: "rgb(255,255,255)",
padding: [5, 10],
textStyle: {
color: "rgb(15, 75, 111)"
},
extraCssText: "box-shadow: 0 0 5px rgba(0, 0, 0, 0.3)",
formatter: arr => {
return `线程数:${arr[0].data}`;
}
},
grid: {
left: "10px",
right: "10px",
bottom: "10px",
top: "30px"
},
xAxis: {
type: "category",
show: false,
boundaryGap: false,
splitLine: {
interval: "auto"
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 12
}
},
data: x
},
yAxis: {
type: "value",
show: false,
splitLine: {
show: true
},
axisTick: {
show: false
},
axisLine: {
show: true
}
},
series: [
{
type: "line",
smooth: true,
showSymbol: false,
symbol: "circle",
symbolSize: 6,
data: y,
markPoint: {
symbolSize: 30,
data: [
{ type: "max", name: "最大值" },
{ type: "min", name: "最小值" }
]
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(15, 75, 111, 0.5)"
},
{
offset: 1,
color: "rgba(15, 75, 111, 0.1)"
}
],
false
)
}
},
itemStyle: {
normal: {
color: "rgb(15, 75, 111)"
}
},
lineStyle: {
normal: {
width: 1
}
}
}
]
};
}
}
};
</script>
<style lang="scss" scoped>
.perf-mysql {
background-color: #fff;
.title {
font-size: 16px;
padding: 15px;
border-bottom: 1px solid #f7f7f7;
}
.block {
display: flex;
flex-direction: column;
align-items: center;
height: 160px;
font-size: 13px;
.icon {
height: 60px;
width: 60px;
margin-bottom: 10px;
border: 1px dashed #eee;
display: flex;
justify-content: center;
align-items: center;
border-radius: 3px;
margin-top: 25px;
.icon-svg {
font-size: 40px;
}
&._disk {
color: #67c23a;
}
&._cache {
color: #409eff;
}
&._connect {
color: #e6a23c;
}
}
.a {
font-size: 13px;
}
.b {
display: flex;
text-align: center;
width: 150px;
li {
list-style: none;
flex: 1;
p {
&:first-child {
margin-bottom: 5px;
font-size: 12px;
color: #999;
}
}
}
}
}
.echarts {
height: 150px;
width: 100%;
margin-top: 10px;
}
}
</style>

View File

@ -1,345 +0,0 @@
<template>
<div class="network">
<p class="title">流量</p>
<ul>
<li
class="rx"
@click="change('上行')"
:class="[chartOptions.legend.selected['上行'] ? 'on' : 'off']"
>
<p>上行</p>
<p>{{ tx_sec | unit_size }}</p>
</li>
<li
class="tx"
@click="change('下载')"
:class="[chartOptions.legend.selected['下载'] ? 'on' : 'off']"
>
<p>下载</p>
<p>{{ rx_sec | unit_size }}</p>
</li>
<li class="send">
<p>总发送</p>
<p>{{ tx_bytes | unit_size }}</p>
</li>
<li class="receive">
<p>总接收</p>
<p>{{ rx_bytes | unit_size }}</p>
</li>
</ul>
<vue-echarts v-if="visible" autoresize :options="chartOptions"></vue-echarts>
</div>
</template>
<script>
import echarts from "echarts";
import Common from "./common";
export default {
mixins: [Common],
props: {
data: null
},
data() {
return {
visible: true,
chartOptions: {
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: {
color: "#ddd"
}
},
backgroundColor: "rgba(255,255,255,1)",
padding: [5, 10],
textStyle: {
color: "#7588E4"
},
extraCssText: "box-shadow: 0 0 5px rgba(0, 0, 0, 0.3)",
formatter: arr => {
return arr
.map((e, i) => (i == 0 ? "上行:" : "下载:") + this.conByte(e.value))
.join("<br>");
}
},
legend: {
data: ["上行", "下载"],
selected: {
上行: true,
下载: true
},
left: "1000%"
},
grid: {
bottom: "5%",
top: "10%",
left: "10px",
right: "10px",
containLabel: true
},
xAxis: {
type: "category",
data: [],
boundaryGap: false,
splitLine: {
show: true,
interval: "auto",
lineStyle: {
color: ["#D4DFF5"]
}
},
axisTick: {
show: false
},
axisLine: {
show: false,
lineStyle: {
color: "#609ee9"
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
}
},
yAxis: {
type: "value",
splitLine: {
show: true,
lineStyle: {
color: ["#D4DFF5"]
}
},
axisTick: {
show: false
},
axisLine: {
show: false,
lineStyle: {
color: "#609ee9"
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
},
formatter: value => {
return this.conByte(value);
}
}
},
series: [
{
type: "line",
showSymbol: false,
symbol: "circle",
symbolSize: 6,
data: [],
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(255, 202, 89, 0.5)"
},
{
offset: 1,
color: "rgba(255, 202, 89, 0.2)"
}
],
false
)
}
},
itemStyle: {
normal: {
color: "#f7b851"
}
},
lineStyle: {
normal: {
width: 1
}
}
},
{
type: "line",
showSymbol: false,
symbol: "circle",
symbolSize: 6,
data: [],
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(216, 244, 247, 1)"
},
{
offset: 1,
color: "rgba(216, 244, 247, 1)"
}
],
false
)
}
},
itemStyle: {
normal: {
color: "#58c8da"
}
},
lineStyle: {
normal: {
width: 1
}
}
}
]
},
rx_bytes: 0,
tx_bytes: 0,
rx_sec: 0,
tx_sec: 0
};
},
methods: {
change(n) {
this.chartOptions.legend.selected[n] = !this.chartOptions.legend.selected[n];
this.visible = false;
this.$nextTick(() => {
this.visible = true;
});
},
refresh(res) {
let { data = [], time } = res;
let network = data[data.length - 1].server.network;
this.rx_bytes = 0;
this.tx_bytes = 0;
network.forEach(e => {
this.rx_bytes += e.rx_bytes;
this.tx_bytes += e.tx_bytes;
});
this.rx_sec = network.reduce((a, b) => a + b.rx_sec, 0);
this.tx_sec = network.reduce((a, b) => a + b.tx_sec, 0);
this.chartOptions.xAxis.data = time;
this.chartOptions.series[0].name = "上行";
this.chartOptions.series[0].data = data.map(e =>
e.server.network.reduce((a, b) => a + b.tx_sec, 0)
);
this.chartOptions.series[1].name = "下载";
this.chartOptions.series[1].data = data.map(e =>
e.server.network.reduce((a, b) => a + b.rx_sec, 0)
);
}
}
};
</script>
<style lang="scss" scoped>
.network {
background-color: #fff;
padding: 15px;
.title {
font-size: 16px;
border-bottom: 1px solid #eee;
padding-bottom: 15px;
}
ul {
display: flex;
margin-top: 30px;
text-align: center;
li {
list-style: none;
flex: 1;
&.rx {
color: #f7b851;
}
&.tx {
color: #58c8da;
}
p {
&:first-child {
font-size: 12px;
color: #999;
}
&:last-child {
font-size: 15px;
margin-top: 10px;
}
}
}
li:nth-last-child(n + 3) p {
cursor: pointer;
position: relative;
&:hover {
opacity: 0.8;
}
}
li:nth-last-child(n + 3) p:first-child::before {
display: block;
content: "";
height: 8px;
width: 8px;
border-radius: 8px;
position: absolute;
left: calc(50% - 26px);
top: calc(50% - 4px);
background-color: #eee;
}
li:nth-child(1).on p:first-child::before {
background-color: #f7b851;
}
li:nth-child(2).on p:first-child::before {
background-color: #58c8da;
}
}
.echarts {
height: 350px;
width: 100%;
}
}
</style>

View File

@ -1,324 +0,0 @@
<template>
<div class="perf-redis">
<p class="title">Redis</p>
<el-row class="fn">
<el-col :span="8">
<div class="block">
<div class="icon _disk">
<icon-svg name="perf-disk"></icon-svg>
</div>
<ul class="b">
<li>
<p>已使用</p>
<p>{{ used_memory | unit_size }}</p>
</li>
</ul>
</div>
</el-col>
<el-col :span="8">
<div class="block">
<div class="icon _network">
<icon-svg name="perf-network"></icon-svg>
</div>
<ul class="b scroller1">
<li>
<p>输入</p>
<p>{{ total_net_input_bytes | unit_size }}</p>
</li>
<li>
<p>输出</p>
<p>{{ total_net_output_bytes | unit_size }}</p>
</li>
</ul>
</div>
</el-col>
<el-col :span="8">
<div class="block">
<div class="icon _db">
<icon-svg name="perf-db"></icon-svg>
</div>
<ul class="b scroller1">
<li v-for="(item, index) in dbList" :key="index">
<p>{{ item.label }}</p>
<p>{{ item.value }} key</p>
</li>
</ul>
</div>
</el-col>
</el-row>
<vue-echarts ref="chart" :options="chartOptions" autoresize></vue-echarts>
</div>
</template>
<script>
import echarts from "echarts";
import Common from "./common";
export default {
mixins: [Common],
data() {
return {
dbList: [],
chartOptions: {},
total_net_input_bytes: 0,
total_net_output_bytes: 0,
used_memory: 0
};
},
methods: {
refresh({ data, time }) {
const item = data[data.length - 1];
const { Keyspace, Stats, Memory } = item.redis;
let list = [];
for (let i in Keyspace) {
list.push({
label: i,
value: Keyspace[i].split(",")[0].split("=")[1]
});
}
this.total_net_input_bytes = Stats.total_net_input_bytes;
this.total_net_output_bytes = Stats.total_net_output_bytes;
this.used_memory = Memory.used_memory;
this.chartOptions = this.onChart(
time,
data.map(e => e.redis.Stats.instantaneous_ops_per_sec),
{
color: "204, 32, 20",
smooth: false
}
);
this.dbList = list;
},
onChart(x, y) {
return {
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: {
color: "#F56C6C"
}
},
backgroundColor: "rgb(255,255,255)",
padding: [5, 10],
textStyle: {
color: "#F56C6C"
},
extraCssText: "box-shadow: 0 0 5px rgba(0, 0, 0, 0.3)",
formatter: arr => {
return `${arr[0].data} / S每秒操作数`;
}
},
grid: {
left: "10px",
right: "10px",
bottom: "10px",
top: "30px"
},
xAxis: {
type: "category",
show: false,
boundaryGap: false,
splitLine: {
interval: "auto",
lineStyle: {
color: ["#D4DFF5"]
}
},
axisTick: {
show: false
},
axisLine: {
show: false,
lineStyle: {
color: "#609ee9"
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 12
}
},
data: x
},
yAxis: {
type: "value",
show: false,
splitLine: {
show: true,
lineStyle: {
color: ["#D4DFF5"]
}
},
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
color: ["#609ee9"]
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 12
}
}
},
series: [
{
type: "line",
smooth: true,
showSymbol: false,
symbol: "circle",
symbolSize: 6,
data: y,
markPoint: {
symbolSize: 30,
data: [
{ type: "max", name: "最大值" },
{ type: "min", name: "最小值" }
]
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(245, 108, 108, 0.5)"
},
{
offset: 1,
color: "rgba(245, 108, 108, 0.1)"
}
],
false
)
}
},
itemStyle: {
normal: {
color: "#F56C6C"
}
},
lineStyle: {
normal: {
width: 1
}
}
}
]
};
}
}
};
</script>
<style lang="scss" scoped>
.perf-redis {
background-color: #fff;
.title {
font-size: 16px;
padding: 15px;
border-bottom: 1px solid #f7f7f7;
}
.block {
display: flex;
flex-direction: column;
align-items: center;
height: 160px;
font-size: 13px;
margin: 0 10px;
.icon {
height: 60px;
width: 60px;
margin-bottom: 10px;
border: 1px dashed #eee;
display: flex;
justify-content: center;
align-items: center;
border-radius: 3px;
margin-top: 25px;
.icon-svg {
font-size: 40px;
}
&._disk {
color: #67c23a;
}
&._network {
color: #409eff;
}
&._db {
color: #e6a23c;
}
}
.a {
font-size: 13px;
}
.b {
display: flex;
text-align: center;
width: 100%;
overflow: auto hidden;
li {
list-style: none;
flex: 1;
margin: 0 8px;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
p {
&:first-child {
margin-bottom: 5px;
font-size: 12px;
color: #999;
}
}
}
}
}
.echarts {
height: 150px;
width: 100%;
margin-top: 10px;
}
}
</style>

View File

@ -4,7 +4,6 @@ import SysUser from "./system/user";
import SysMenu from "./system/menu";
import SysRole from "./system/role";
import SysDept from "./system/dept";
import SysInfo from "./system/info";
import SysParam from "./system/param";
import SysLog from "./system/log";
import PluginInfo from "./plugin/info";
@ -17,7 +16,6 @@ export default {
menu: new SysMenu(),
role: new SysRole(),
dept: new SysDept(),
info: new SysInfo(),
param: new SysParam(),
log: new SysLog()
},

View File

@ -1,13 +0,0 @@
import { BaseService, Service, Permission } from "cl-admin";
@Service("base/sys/info")
class SysInfo extends BaseService {
@Permission("record")
record() {
return this.request({
url: "/record"
});
}
}
export default SysInfo;

View File

@ -1,82 +0,0 @@
<template>
<cl-scrollbar>
<div class="system-perf">
<ct ref="ct"></ct>
<network ref="network"></network>
<el-row :gutter="20">
<el-col :lg="12" :xs="24" style="margin-top: 15px">
<redis ref="redis"></redis>
</el-col>
<el-col :lg="12" :xs="24" style="margin-top: 15px">
<mysql ref="mysql"></mysql>
</el-col>
</el-row>
</div>
</cl-scrollbar>
</template>
<script>
import Ct from "../components/perf/ct";
import Network from "../components/perf/network";
import Redis from "../components/perf/redis";
import Mysql from "../components/perf/mysql";
export default {
components: {
Network,
Ct,
Redis,
Mysql
},
beforeRouteLeave(to, from, next) {
clearTimeout(this.tiemr);
next();
},
data() {
return {
list: {},
tiemr: null
};
},
mounted() {
this.refresh();
this.tiemr = setInterval(this.refresh, 3000);
},
methods: {
refresh() {
this.$service.system.info.record().then(res => {
const { network, ct, redis, mysql } = this.$refs;
if (network) {
network.refresh(res);
}
if (ct) {
ct.refresh(res);
}
if (redis) {
redis.refresh(res);
}
if (mysql) {
mysql.refresh(res);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.system-perf {
}
</style>

View File

@ -76,7 +76,7 @@ export const TestService = {
info: d => {
console.log("GET[info]", d);
return new Promise(resolve => {
resolve(UserList.find(e.id == d.id));
resolve(UserList.find(e => e.id == d.id));
});
},
add: d => {

View File

@ -18,7 +18,7 @@ const PROXY_LIST = {
"^/pro": "/api"
}
}
}
};
module.exports = {
publicPath: "/",
@ -50,10 +50,10 @@ module.exports = {
chainWebpack: config => {
// 设置环境变量
config.plugin('define').tap(args => {
args[0]['process.env'].PROXY_LIST = JSON.stringify(PROXY_LIST)
return args
})
config.plugin("define").tap(args => {
args[0]["process.env"].PROXY_LIST = JSON.stringify(PROXY_LIST);
return args;
});
// 设置 svg
config.module.rule("svg").uses.clear();
@ -88,26 +88,28 @@ module.exports = {
// 移除 preload 插件,避免加载多余的资源
config.plugins.delete("preload-index");
config.optimization.minimizer('terser').tap((args) => {
config.optimization.minimizer("terser").tap(args => {
// 去掉注释
args[0].terserOptions.output = {
comments: false
};
return args
})
return args;
});
// 分割模块
config.optimization.splitChunks({
chunks: 'all',
chunks: "all",
maxInitialRequests: Infinity,
minSize: 300000,
automaticNameDelimiter: '-',
automaticNameDelimiter: "-",
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `chunk.${packageName.replace('@', '')}`;
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
return `chunk.${packageName.replace("@", "")}`;
},
priority: 10
}