build(web): 添加 ESLint 和 Prettier 配置文件

- 新增 .eslintrc.js 文件,配置 ESLint 规则和插件
- 新增 .prettierrc.json 文件,设置 Prettier 格式化选项
This commit is contained in:
zhoumengru
2025-08-29 14:57:13 +08:00
parent 390ea73d7d
commit 7aad6b6598
11 changed files with 3412 additions and 950 deletions

95
web/.eslintrc.js Normal file
View File

@@ -0,0 +1,95 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended', // Vue 项目
'prettier' // 必须放在最后
],
parser: 'vue-eslint-parser', // 解析 .vue 文件
globals: {
T: 'readonly' // 声明 T 是只读的全局变量
},
plugins: ['react', '@typescript-eslint', 'prettier'], // 添加 prettier 插件
rules: {
'vue/v-on-event-hyphenation': 'off',
'prettier/prettier': 'off',
'react/react-in-jsx-scope': 'off', // React 17+ 可关闭 JSX 运行时检查
// off=0, warn=1, error=2, 如果是数组, 第二项表示参数option
'vue/attributes-order': 0,
indent: [2, 2], // 控制缩进为2
eqeqeq: 0, // 警告使用全等
quotes: [0, 'single'], // 单引号
singleQuote: 0,
'no-console': 2, // 不禁用console
'no-debugger': 2, // 警告debugger
'no-var': 2, // 对var禁止
'no-eval': 0,
semi: 0, // 强制使用分号
'comma-dangle': 0,
'semi-spacing': [0, { before: false, after: false }], // 强制分号前后不允许空格
// 'no-irregular-whitespace': 0, // 不规则的空白不允许
// 'no-trailing-spaces': 1, // 一行结束后面有空格就发出警告
'eol-last': 0, // 文件以单一的换行符结束
'no-unused-vars': 0, // 不能有声明后未被使用的变量或参数
'no-underscore-dangle': 0, // 标识符不能以_开头或结尾
'no-alert': 2, // 禁止使用alert confirm prompt
'no-lone-blocks': 0, // 禁止不必要的嵌套块
'no-class-assign': 2, // 禁止给类赋值
'no-cond-assign': 2, // 禁止在条件表达式中使用赋值语句
'no-const-assign': 2, // 禁止修改const声明的变量
'no-delete-var': 2, // 不能对var声明的变量使用delete操作符
'no-dupe-keys': 2, // 在创建对象字面量时不允许键重复
'no-duplicate-case': 2, // switch中的case标签不能重复
'no-dupe-args': 2, // 函数参数不能重复
'no-empty': 2, // 块语句中的内容不能为空
'no-func-assign': 2, // 禁止重复的函数声明
'no-invalid-this': 0, // 禁止无效的this只能用在构造器对象字面量
'no-redeclare': 2, // 禁止重复声明变量
'no-spaced-func': 2, // 函数调用时 函数名与()之间不能有空格
'no-this-before-super': 0, // 在调用super()之前不能使用this或super
'no-undef': 2, // 不能有未定义的变量
'no-use-before-define': 2, // 未定义前不能使用
camelcase: 2, // 强制驼峰法命名
'vue/multi-word-component-names': 0,
'jsx-quotes': [2, 'prefer-double'], // 强制在JSX属性jsx-quotes中一致使用双引号
// 'react/sort-comp': 2, // 强制组件方法顺序
'no-extra-boolean-cast': 0, // 禁止不必要的bool转换
// 'react/no-array-index-key': 0, // 防止在数组中遍历中使用数组key做索引
'no-unreachable': 1, // 不能有无法执行的代码
'no-mixed-spaces-and-tabs': 0, // 禁止混用tab和空格
'prefer-arrow-callback': 0, // 比较喜欢箭头回调
'arrow-parens': 2, // 箭头函数用小括号括起来
'arrow-spacing': 0, // = >的前/后括号
'prefer-const': 0,
'prefer-destructuring': [
'error',
{
VariableDeclarator: {
array: false,
object: true
},
AssignmentExpression: {
array: false,
object: false
}
},
{
enforceForRenamedProperties: false
}
],
'use-isnan': 2, // 禁止比较时使用NaN只能用isNaN()
'vue/no-multiple-template-root': 0,
'space-before-function-paren': 0,
'vue/no-v-model-argument': 0,
'promise/param-names': 0,
'no-case-declarations': 0,
'vue/valid-v-for': 0,
'prefer-promise-reject-errors': 0,
'vue/no-v-for-template-key': 0
}
}

8
web/.prettierrc.json Normal file
View File

@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}

3724
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,9 +3,10 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve && webpack-dev-server",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint",
"show-webpack-version": "webpack --version"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^4.2.6", "ant-design-vue": "^4.2.6",
@@ -19,18 +20,24 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.16", "@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16", "@babel/eslint-parser": "^7.12.16",
"@typescript-eslint/eslint-plugin": "^8.41.0",
"@typescript-eslint/parser": "^8.41.0",
"@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0", "@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0", "@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0", "eslint": "^8.57.1",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.10.2",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.0.3", "eslint-plugin-react": "^7.37.5",
"prettier": "^2.4.1", "eslint-plugin-vue": "^8.7.1",
"prettier": "^2.8.8",
"sass": "^1.32.7", "sass": "^1.32.7",
"sass-loader": "^12.0.0" "sass-loader": "^12.0.0",
"vue-eslint-parser": "^10.2.0",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.2"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@@ -4,23 +4,12 @@
<style lang="scss"> <style lang="scss">
#app { #app {
font-family: Avenir, Helvetica, Arial, sans-serif; position: absolute;
-webkit-font-smoothing: antialiased; top: 0;
-moz-osx-font-smoothing: grayscale; left: 0;
text-align: center; bottom: 0;
color: #2c3e50; right: 0;
} min-width: 1440px;
min-height: 900px;
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
} }
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@@ -1,28 +1,25 @@
import { createRouter, createWebHistory } from "vue-router"; import { createRouter, createWebHistory } from 'vue-router'
const routes = [ const routes = [
{ {
path: "/", path: '/',
name: "home", redirect: '/login'
redirect: "/login",
}, },
{ {
path: "/login", path: '/login',
name: "login", name: 'login',
component: () => component: () => import(/* webpackChunkName: "login" */ '@/views/LoginView.vue')
import(/* webpackChunkName: "login" */ "@/views/LoginView.vue"),
}, },
{ {
path: "/main", path: '/main',
name: "main", name: 'main',
component: () => component: () => import(/* webpackChunkName: "login" */ '@/views/MainView.vue')
import(/* webpackChunkName: "login" */ "@/views/MainView.vue"), }
}, ]
];
const router = createRouter({ const router = createRouter({
history: createWebHistory(""), history: createWebHistory(''),
routes, routes
}); })
export default router; export default router

View File

@@ -2,8 +2,8 @@
<a-config-provider <a-config-provider
:theme="{ :theme="{
token: { token: {
colorPrimary: '#065758', colorPrimary: '#143d7d'
}, }
}" }"
> >
<div class="login"> <div class="login">
@@ -12,337 +12,143 @@
<div class="title" style="">账号登录</div> <div class="title" style="">账号登录</div>
<a-form ref="ruleForm" :model="form" :rules="rules"> <a-form ref="ruleForm" :model="form" :rules="rules">
<a-form-item label="" name="user"> <a-form-item label="" name="user">
<a-input <a-input v-model:value="form.user" placeholder="请输入账号" autocomplete>
:bordered="false"
v-model:value="form.user"
placeholder="请输入账号"
autocomplete
>
<template #prefix> <template #prefix>
<span class="iconfont icon-a-xingzhuangjiehe1x"></span> <user-outlined />
</template> </template>
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item label="" name="passwd"> <a-form-item label="" name="passwd">
<a-input-password <a-input-password
:bordered="false"
v-model:value="form.passwd" v-model:value="form.passwd"
placeholder="请输入密码" placeholder="请输入密码"
autocomplete autocomplete
@pressEnter="login" @pressEnter="login"
style="background-color: #fff; margin-top: 6px"
> >
<template #prefix> <template #prefix>
<span class="iconfont icon-a-xingzhuangjiehe1x1"></span> <LockOutlined />
</template> </template>
</a-input-password> </a-input-password>
</a-form-item> </a-form-item>
</a-form> </a-form>
<a-button class="login-btn" @click="login" :loading="loading" <a-button class="login-btn" @click="login" :loading="loading">登录 </a-button>
>登录
</a-button>
</div> </div>
</div> </div>
</a-config-provider> </a-config-provider>
</template> </template>
<script> <script>
import { getReq, postReq } from "@/request/api.js"; import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
// import { sm2Encrypt, sm2Decrypt } from "@c/utils/sm2Utils.js";
// import { getSysConfig } from "@/utils/index.js";
// import { copyRight } from "@c/utils/config.js";
import // EyeInvisibleOutlined,
// EyeTwoTone,
// LockOutlined,
// UserOutlined,
"@ant-design/icons-vue";
// import moment from "moment";
// import { themeColor } from "@c/utils/config.js";
export default { export default {
name: "loginView", name: 'LoginView',
// components: { EyeTwoTone, EyeInvisibleOutlined }, components: {
props: {}, UserOutlined,
LockOutlined
},
data() { data() {
return { return {
copyRight: "", form: {
loading: false, user: 'admin',
companyName: "", passwd: '123456'
publickey: "",
form: {},
rules: {
user: [{ required: true, message: "请输入用户名", trigger: "blur" }],
passwd: [
{ required: true, message: "请输入登录密码", trigger: "blur" },
],
code: [{ required: true, message: "请输入验证码", trigger: "blur" }],
}, },
// rules: { rules: {
// user: [{ validator: this.checkUser, trigger: 'blur' }], user: [
// passwd: [{ validator: this.checkPasswd, trigger: 'blur' }], {
// code: [ required: true,
// { required: true, message: '请输入验证码', trigger: 'blur' }, message: '请输入账号'
// // { validator: this.asynCheckRandom, }, }
],
// ] passwd: [
// }, {
codeId: Math.random(), required: true,
codeString: "", // 验证码字符串 message: '请输入密码'
}; }
]
},
loading: false
}
}, },
async mounted() {
// await this.getRandom();
// this.companyName = await getSysConfig("app-name");
// this.copyRight = await getSysConfig("app-version");
// this.publickey = await getSysConfig("secret-pub-key");
document.title = this.companyName;
},
methods: { methods: {
// 验证码校验
async asynCheckRandom(code) {
const res = await getReq({ id: this.codeId, code }, "/user/checkRandom");
if (res.code == 200 && res.data) {
return Promise.resolve({ success: true, msg: "" });
} else {
return Promise.resolve({ success: false, msg: "验证码输入错误" });
}
},
// })
// 登录后首次判断主题色
// async changeTheme() {
// const res = await getSysConfig("app-map-center");
// const theme = localStorage.getItem("theme");
// if (!theme) {
// const { sunriseSunset } = JSON.parse(res).weather;
// const sunrise = sunriseSunset.sunrise.trim().split(/\s+/)[1] || "04:00";
// const sunset = sunriseSunset.sunset.trim().split(/\s+/)[1] || "20:00";
// const current = moment().locale("zh-cn").format("HH:mm");
// if (sunrise < current && current < sunset) {
// localStorage.setItem("theme", "light");
// Object.keys(themeColor).forEach((key) => {
// document.documentElement.style.setProperty(
// key,
// themeColor[key].light
// );
// });
// } else {
// localStorage.setItem("theme", "dark");
// Object.keys(themeColor).forEach((key) => {
// document.documentElement.style.setProperty(
// key,
// themeColor[key].dark
// );
// });
// }
// } else {
// Object.keys(themeColor).forEach((key) => {
// document.documentElement.style.setProperty(
// key,
// themeColor[key][theme]
// );
// });
// }
// },
// 填充密码
async fillPassword() {
let userName = localStorage.getItem("userName");
if (userName) {
// this.form.user = localStorage.getItem('userName')
// const key = await getSysConfig('secret-pub-key')
// this.form.passwd = sm2Decrypt(localStorage.getItem('passwd'), key)
this.form.remember = true;
}
},
// 获取验证码
async getRandom() {
const res = await getReq({ id: this.codeId }, "/user/getRandom");
if (res.code == 200) {
this.codeString = res.data;
} else {
this.codeString = "获取失败";
}
},
async login() { async login() {
this.$refs.ruleForm this.$refs.ruleForm.validate(async (valid) => {
.validate() if (valid) {
.then((res) => { this.loading = true
if (res) { try {
this.asynCheckRandom(res.code).then((res) => { const res = await this.$http.post('/login', this.form)
if (!res.success) { this.loading = false
this.$openNotification({ if (res.code === 200) {
name: "", this.$message.success('登录成功')
type: "", localStorage.setItem('token', res.token)
status: "error", this.$router.push('/main')
desc: res.msg, } else {
}); this.$message.error(res.message || '登录失败')
this.form.code = ""; }
} else { } catch (error) {
this.submitLoginForm(); this.loading = false
} this.$message.error('请求失败,请稍后重试')
});
} }
})
.catch((err) => {
console.log(err);
});
},
async submitLoginForm() {
// let newPsdSM2 = sm2Encrypt(this.form.passwd, this.publickey);
// if (newPsdSM2) {
let paramsDate = {
user: this.form.user,
// passwd: newPsdSM2,
};
if (this.form.remember) {
localStorage.setItem("userName", this.form.user);
// localStorage.setItem("passwd", newPsdSM2);
}
try {
const res = await postReq(paramsDate, "/user/login");
// 记住密码
if (res.code == 200) {
const { token, user } = res.data;
this.$openNotification({
name: "",
type: "",
status: "success",
desc: "登录成功",
});
localStorage.setItem("token", token);
localStorage.setItem("showNotice", true);
// this.changeTheme();
this.getUserRoute(user);
} else { } else {
this.loading = false; // console.log("表单验证失败");
throw new Error(res);
} }
} catch (error) { })
this.loading = false; }
this.form.code = ""; }
this.getRandom(); }
}
// }
},
async getUserRoute(user) {
const { userExtend } = user;
const { role } = userExtend;
localStorage.setItem("user", JSON.stringify(user));
if (role && role.permissionList.length > 0) {
const allMenus = [];
role.permissionList.forEach((item) => {
allMenus.push(...item.menusList);
});
const uniqueArray = [
...new Map(allMenus.map((item) => [item.id, item])).values(),
];
const treeMunes = this.buildTree(uniqueArray);
const pcMunes = treeMunes.filter((item) => item.type == 0);
localStorage.setItem("menuList", JSON.stringify(pcMunes));
}
setTimeout(() => {
this.loading = false;
this.$router.push("/");
}, 1000);
this.loading = false;
},
buildTree(items, parentId = null) {
const result = [];
const itemMap = {}; // 用于存储id和对应节点的映射方便快速查找父节点
items.forEach((item) => {
if (!itemMap[item.id]) {
itemMap[item.id] = { ...item, children: [] };
}
const node = itemMap[item.id];
if (item.parentId === parentId || item.parentId == 0) {
result.push(node);
} else {
if (!itemMap[item.parentId]) {
itemMap[item.parentId] = { children: [] };
}
itemMap[item.parentId].children.push(node);
}
});
result.sort((a, b) => a.seq - b.seq);
result.forEach((item) => {
if (item.children.length == 0) {
delete item.children;
}
});
return result;
},
onChange() {},
forgetPassword() {
this.$openNotification({
name: "",
type: "",
status: "warning",
desc: "请联系平台管理员",
});
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.login { .login {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-width: 1440px; min-width: 1440px;
min-height: 900px; min-height: 900px;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url("@/assets/images/loginBg.png"); background-image: url('@/assets/images/loginBg.png');
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
.main-title { .main-title {
background: linear-gradient( background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(40, 235, 231, 1) 100%);
180deg,
rgba(255, 255, 255, 1) 0%,
rgba(40, 235, 231, 1) 100%
);
color: transparent; color: transparent;
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
font-size: 50px; font-size: 50px;
font-weight: 400; font-weight: 600;
letter-spacing: 5px; letter-spacing: 5px;
line-height: 53px; line-height: 53px;
} }
.login-content { .login-content {
width: 390px; width: 540px;
height: 370px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center;
padding: 0 40px; padding: 0 40px;
margin-top: 120px;
background-image: url('@/assets/images/loginFrom.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
.ant-form {
margin-top: 30px;
width: 330px;
}
.title { .title {
margin-bottom: 10px; // margin-bottom: 10px;
margin-top: 60px;
color: #fff; color: #fff;
font-size: 20px; font-size: 20px;
font-weight: 700;
} }
:deep(.ant-input-prefix) { :deep(.ant-input-prefix) {
color: #217575; color: #fff;
} }
:deep(.ant-form-item) { :deep(.ant-form-item) {
margin-bottom: 20px !important; margin-bottom: 20px !important;
@@ -373,22 +179,21 @@ export default {
cursor: pointer; cursor: pointer;
} }
.ant-checkbox-wrapper:hover { .ant-checkbox-wrapper:hover {
color: #065758; color: #143d7d;
} }
span:hover { span:hover {
color: #065758; color: #143d7d;
} }
} }
.login-btn { .login-btn {
width: 335px; width: 335px;
height: 45px; height: 40px;
border-radius: 4px; border-radius: 4px;
background: #2a82e4; background: #2a82e4;
border: none !important;
font-size: 16px; font-size: 16px;
margin-top: 20px; margin-top: 20px;
.btn-text { color: #fff;
}
} }
.copyright { .copyright {
position: absolute; position: absolute;
@@ -400,42 +205,18 @@ export default {
font-size: 20px; font-size: 20px;
} }
} }
:deep(.ant-input) { .ant-input-affix-wrapper {
&::placeholder { background: none !important;
// font-size: 12px !important; height: 40px;
// line-height: 12px; :deep(.ant-input) {
// line-height: 100px !important; background: none !important;
// height: 40px !important; color: #fff;
// line-height: 40px !important; &::placeholder {
color: var(--theme-text6) !important;
} }
}
:deep(span.ant-input-affix-wrapper) {
height: 40px !important;
background: #eceff4 !important;
color: #065758 !important;
border: none !important;
border-radius: 8px !important;
.ant-input {
// height: 40px !important;
border-radius: 0 !important;
background: #eceff4 !important;
} }
:deep(.anticon){
&:hover { color: #fff ;
border-color: #0caf60 !important;
} }
&:focus {
border: none !important;
background-color: #eceff4;
}
}
:deep(.ant-input-affix-wrapper) {
padding: 0 10px !important;
}
// 输入框自动填充后的背景改色
input:-internal-autofill-previewed,
input:-internal-autofill-selected {
-webkit-text-fill-color: #000000 !important;
transition: background-color 500s ease-out 0.5s;
} }
</style> </style>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="home"> <div class="main">
<img alt="Vue logo" src="../assets/logo.png" /> <div class="header"></div>
<HelloWorld msg="Welcome to Your Vue.js App" /> <div class="menu"></div>
</div> </div>
</template> </template>
@@ -9,7 +9,7 @@
// @ is an alias to /src // @ is an alias to /src
export default { export default {
name: "HomeView", name: "MainView",
components: {}, components: {},
}; };
</script> </script>

View File

@@ -1,52 +1,53 @@
const { defineConfig } = require("@vue/cli-service"); const { defineConfig } = require('@vue/cli-service')
const path = require("path"); const path = require('path')
module.exports = defineConfig({ module.exports = defineConfig({
transpileDependencies: true, transpileDependencies: true,
publicPath: process.env.NODE_ENV === "production" ? "/your-project/" : "/", publicPath: '/',
// 输出文件目录 // 输出文件目录
outputDir: "dist", outputDir: 'dist',
// 静态资源目录 // 静态资源目录
assetsDir: "static", assetsDir: 'static',
devServer: { devServer: {
hot: true,
compress: true,
allowedHosts: 'all',
headers: { headers: {
// 1. 允许开发环境跨域 // 1. 允许开发环境跨域
"Access-Control-Allow-Origin": "*", 'Access-Control-Allow-Origin': '*'
}, },
historyApiFallback: true, historyApiFallback: true,
open: true, open: false,
port: 8080, port: 8080,
client: { client: {
overlay: { overlay: {
runtimeErrors: (error) => { runtimeErrors: (error) => {
const ignoreErrors = [ const ignoreErrors = [
"ResizeObserver loop limit exceeded", 'ResizeObserver loop limit exceeded',
"ResizeObserver loop completed with undelivered notifications.", 'ResizeObserver loop completed with undelivered notifications.'
]; ]
if (ignoreErrors.includes(error.message)) { if (ignoreErrors.includes(error.message)) {
return false; return false
} }
return true; return true
}, }
}, }
}, }
}, },
css: { css: {
loaderOptions: { loaderOptions: {
scss: { scss: {
additionalData: `@use "~@/style/color.scss";`, additionalData: `@use "~@/style/color.scss";`
}, }
}, },
extract: { extract: {
filename: `css/.[contenthash:8].css`, filename: `css/.[contenthash:8].css`,
chunkFilename: `css/.[contenthash:8].chunk.css`, chunkFilename: `css/.[contenthash:8].chunk.css`
}, }
}, },
// webpack相关配置 // webpack相关配置
configureWebpack: { configureWebpack: {
// 自定义打包入口 // 自定义打包入口
entry: "./src/main.js",
// 扩展 webpack 配置 // 扩展 webpack 配置
plugins: [ plugins: [
@@ -54,13 +55,13 @@ module.exports = defineConfig({
], ],
resolve: { resolve: {
alias: { alias: {
"@": path.join(__dirname, "src"), '@': path.join(__dirname, 'src')
}, }
}, }
}, },
// 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码 // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
lintOnSave: process.env.NODE_ENV !== "production", lintOnSave: process.env.NODE_ENV !== 'production',
// 是否使用包含运行时编译器的 Vue 构建版本 // 是否使用包含运行时编译器的 Vue 构建版本
runtimeCompiler: false, runtimeCompiler: false,
@@ -71,5 +72,5 @@ module.exports = defineConfig({
// 第三方插件配置 // 第三方插件配置
pluginOptions: { pluginOptions: {
// ... // ...
}, }
}); })