Commit 617d1ede authored by 郭志伟's avatar 郭志伟

"build: 环境配置"

parent a75e28ab
module.exports = {
root: true,
env: {
node: true,
node: true
},
extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
parserOptions: {
parser: 'babel-eslint',
parser: "babel-eslint"
},
rules: {},
rules: {}
};
module.exports = {
printWidth: 200,
trailingComma: 'es5',
singleQuote: true,
};
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
presets: ["@vue/cli-plugin-babel/preset"]
};
......@@ -5,11 +5,17 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"release": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@qg/cherry-ui": "^1.1.0",
"@qg/qg-scroll": "^1.4.2",
"@qg/sys-sdk": "^1.0.13",
"amfe-flexible": "^2.2.1",
"core-js": "^3.6.5",
"normalize.css": "^8.0.1",
"vconsole": "^3.3.4",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
......@@ -25,10 +31,27 @@
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"husky": "^4.2.5",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"lint-staged": "^10.2.11",
"postcss-flexbugs-fixes": "^4.2.1",
"postcss-import": "^12.0.1",
"postcss-preset-env": "^6.7.0",
"postcss-px2rem": "^0.3.0",
"prettier": "^1.19.1",
"svg-sprite-loader": "^5.0.0",
"vue-template-compiler": "^2.6.11"
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
module.exports = {
plugins: {
"postcss-px2rem": {
remUnit: 37.5
}
}
};
import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon'; // svg component
import Vue from "vue";
import SvgIcon from "@/components/SvgIcon"; // svg component
// register globally
Vue.component('svg-icon', SvgIcon);
Vue.component("svg-icon", SvgIcon);
const req = require.context('./svg', false, /\.svg$/);
const req = require.context("./svg", false, /\.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
......@@ -8,10 +8,38 @@
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
target="_blank"
rel="noopener"
>babel</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
target="_blank"
rel="noopener"
>router</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
target="_blank"
rel="noopener"
>vuex</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
target="_blank"
rel="noopener"
>eslint</a
>
</li>
</ul>
<h3>Essential Links</h3>
<ul>
......@@ -25,19 +53,27 @@
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li>
<a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener"
>vue-devtools</a
>
</li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
<li>
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener"
>awesome-vue</a
>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
name: "HelloWorld",
props: {
msg: String,
},
msg: String
}
};
</script>
......
......@@ -6,16 +6,16 @@
<script>
export default {
name: 'SvgIcon',
name: "SvgIcon",
props: {
iconClass: {
type: String,
required: true,
required: true
},
className: {
type: String,
default: '',
},
default: ""
}
},
computed: {
iconName() {
......@@ -23,12 +23,12 @@ export default {
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className;
return "svg-icon " + this.className;
} else {
return 'svg-icon';
return "svg-icon";
}
},
},
}
}
};
</script>
......
export default {
basicHost: "https://talos-vcc.liangkebang.net"
};
import prod from "./prod.config";
import dev from "./dev.config";
export default process.env.NODE_ENV === "production" ? prod : dev;
export default {
basicHost: "https://talos-vcc.liangkebang.net"
};
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import '@/assets/icons/index.js';
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import "normalize.css";
import "amfe-flexible";
import vConsole from "vconsole";
import "@/assets/icons/index.js";
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
render: h => h(App)
}).$mount("#app");
if (process.env.NODE_ENV !== "development") {
new vConsole();
}
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: Home,
path: "/",
name: "Home",
component: Home
},
{
path: '/about',
name: 'About',
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
},
component: () => import(/* webpackChunkName: "about" */ "../views/About.vue")
}
];
const router = new VueRouter({
mode: 'history',
mode: "history",
base: process.env.BASE_URL,
routes,
routes
});
export default router;
/**
* 时间转换
* @param {String} time 需要转换的时间
* @param {String} cFormat 格式 {y}-{m}-{d} {h}:{i}:{s}
* @return: {String} timeStr 转换完成的时间
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return "-";
}
if (time == null) {
return "-";
}
const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
let date;
if (time == "") {
date = new Date();
} else if (typeof time === "object") {
date = time;
} else {
if (("" + time).length === 10) time = parseInt(time) * 1000;
if (String(time).indexOf("T") > -1) {
time = time.replace(/T/g, " ").replace(/\..*/g, "");
}
if (String(time).indexOf("-") > -1 && String(time).indexOf("T") == -1) {
time = time.replace(/-/g, "/");
}
date = new Date(time);
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
};
const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key];
if (key === "a") {
return ["", "", "", "", "", "", ""][value];
}
if (result.length > 0 && value < 10) {
value = "0" + value;
}
return value || 0;
});
return timeStr;
}
/**
* 时间显示效果显示
* @param {String} time 需要转换的时间
* @param {String} option 格式 {y}-{m}-{d} {h}:{i}:{s}
* @return: {String} 转换完成的时间
*/
export function formatTime(time, option) {
time = +time * 1000;
const d = new Date(time);
const now = Date.now();
const diff = (now - d) / 1000;
if (diff < 30) {
return "刚刚";
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + "分钟前";
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + "小时前";
} else if (diff < 3600 * 24 * 2) {
return "1天前";
}
if (option) {
return parseTime(time, option);
} else {
return (
d.getMonth() + 1 + "" + d.getDate() + "" + d.getHours() + "" + d.getMinutes() + ""
);
}
}
/**
* 延时函数
* @param {Function} func 方法
* @param {Number} wait 等待时间
* @param {Boolean} immediate 是否立即执行
* @return: {Function} result 方法执行
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result;
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp;
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function(...args) {
context = this;
timestamp = +new Date();
const callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
}
/**
* 替换邮箱字符
* @param {String} email 输入字符串
* @return: {Function} new_email 邮箱
*/
export function regEmail(email) {
if (String(email).indexOf("@") > 0) {
const str = email.split("@");
let _s = "";
if (str[0].length > 3) {
for (var i = 0; i < str[0].length - 3; i++) {
_s += "*";
}
}
var new_email = str[0].substr(0, 3) + _s + "@" + str[1];
}
return new_email;
}
/**
* 替换手机字符
* @param {String} mobile 输入字符串
* @return: {Function} new_email 邮箱
*/
export function regMobile(mobile) {
if (mobile.length > 7) {
var new_mobile = mobile.substr(0, 3) + "****" + mobile.substr(7);
}
return new_mobile;
}
/**
* 去除两侧空格
* @param {String} s 输入字符串
* @return: {Function} new_email 邮箱
*/
export function stringTrim(s) {
s = stringTrimLeft(s);
return stringTrimRight(s);
}
/**
* 去除左侧空格
* @param {String} s 输入字符串
* @return: {Function} new_email 邮箱
*/
export function stringTrimLeft(s) {
return s.replace(/^[\s\n\t]+/g, "");
}
/**
* 去除右侧空格
* @param {String} s 输入字符串
* @return: {Function} new_email 邮箱
*/
export function stringTrimRight(s) {
return s.replace(/[\s\n\t]+$/g, "");
}
/**
* 只能输入中文、英文、数字
* @param {String} str 输入字符串
* @return: {String} new_stremail 中文、英文、数字
*/
export function filterSc(str) {
// eslint-disable-next-line
return str.replace(/[^\a-\z\A-\Z0-9\u4E00-\u9FA5]/g, "");
}
/**
* 字符长度(中文)
* @param {String} str 输入字符串
* @return: {Number} len 长度
*/
export function strLen(str) {
var len = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
//单字节加1
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
len++;
} else {
len += 2;
}
}
return len;
}
/**
* 替换emoji表情
* @param {String} name 输入字符串
* @return: {String} str 字符串
*/
export function filterEmoji(name) {
// eslint-disable-next-line
let str = name.replace(
// eslint-disable-next-line
/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi,
""
);
return str;
}
/**
* xss处理
* @param {String} s 输入字符串
* @return: {String} str 字符串
*/
export function xssParse(str) {
return str
? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function(m) {
return {
"&lt;": "<",
"&amp;": "&",
"&quot;": '"',
"&gt;": ">",
"&#39;": "'",
"&nbsp;": " "
}[m];
})
: "";
}
/*eslint-disable*/
import { stringTrim } from './utils';
// 判断输入内容是否为空
export function isNull(str) {
return str === undefined || str.length === 0 || str === null;
}
// 判断输入内容去掉空格是否为空
export function isTrimNull(str) {
if (str === undefined || str.length === 0 || str === null) {
return true;
}
return stringTrim(str).length === 0;
}
// 判断日期类型是否为YYYY-MM-DD格式的类型
export function isDate(str) {
if (!isNull(str)) {
const reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
const r = str.match(reg);
return r !== null;
}
}
// 判断日期类型是否为YYYY-MM-DD hh:mm:ss格式的类型
export function isDateTime(str) {
if (!isNull(str)) {
const reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
const r = str.match(reg);
return r !== null;
}
return false;
}
// 判断日期类型是否为hh:mm:ss格式的类型
export function isTime(str) {
if (!isNull(str)) {
const reg = /^((20|21|22|23|[0-1]\d)\:[0-5][0-9])(\:[0-5][0-9])?$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为英文字母
export function isLetter(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z]+$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为整数
export function isInteger(str) {
if (!isNull(str)) {
const reg = /^[-+]?\d*$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否以数字开头
export function isStartWithInteger(str) {
if (!isNull(str)) {
const reg = /^[0-9].*$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为双精度
export function isDouble(str) {
if (!isNull(str)) {
const reg = /^[-\+]?\d+(\.\d+)?$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为:a-z,A-Z,0-9,_,并以字母开头
export function isProgramVar(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z][a-zA-Z0-9_]*$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为:a-z,A-Z,0-9,_,并以大写字母开头
export function isProgramClassName(str) {
if (!isNull(str)) {
const reg = /^[A-Z][a-zA-Z0-9_]*$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为中文
export function isChinese(str) {
if (!isNull(str)) {
const reg = /^[\u0391-\uFFE5]+$/;
return reg.test(str);
}
return false;
}
// 判断输入的EMAIL格式是否正确
export function isEmail(str) {
if (!isNull(str)) {
const reg = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/g;
return reg.test(str);
}
return false;
}
// 判断输入的邮编(只能为六位)是否正确
export function isZIP(str) {
if (!isNull(str)) {
const reg = /^\d{6}$/;
return reg.test(str);
}
}
// 判断字符串的长度是否满足条件
export function isLengthValidate(str, len) {
if (str) {
if (str.length <= len) {
return true;
} else {
return false;
}
} else {
return true;
}
}
// 判断输入的字符是否为:a-z,A-Z,0-9,_,汉字
export function isProgramName(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否为:a-z,A-Z,0-9,_,汉字
export function isProgramCode(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/;
return reg.test(str);
}
return false;
}
// 判断输入的字符是否以http://或者https://开头,且必须是个网址
export function isProgramWeb(str) {
if (!isNull(str)) {
let reg = /^((https|http)?:\/\/)[^\s]+/;
return reg.test(str);
}
return false;
}
export function isValueTypeMatched(type, value) {
switch (type) {
case 'Integer':
if (!/^\-?\d+$/.test(value)) {
return false;
}
break;
case 'Double':
if (!/^\-?\d+\.\d+$/.test(value)) {
return false;
}
break;
case 'Long':
if (!/^\-?\d+$/.test(value)) {
return false;
}
break;
case 'Boolean':
if (value !== 'true' && value !== 'false') {
return false;
}
break;
default:
return true;
}
return true;
}
export function isProperties(str) {
if (!isNull(str)) {
let reg = /^[a-zA-Z\u4e00-\u9fa5][a-zA-Z_0-9\u4e00-\u9fa5]*\s*=\s*[a-zA-Z_0-9\u4e00-\u9fa5]+/;
return reg.test(str);
}
return false;
}
// 拒绝码以大写字母开头,包含数字、大写字母、下划线,且为四段式
export function isUppercase(str) {
const reg = /^[A-Z]([A-Z0-9]*_){1}([A-Z0-9]+_){2}[A-Z0-9]+$/;
return reg.test(str);
}
//判断用户名
export function isUserName(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z\d_]{4,20}$/;
return reg.test(str);
}
return false;
}
//判断密码
export function isPassword(str) {
if (!isNull(str)) {
const reg = /^[a-zA-Z\d]{6,14}$/;
return reg.test(str);
}
return false;
}
//判断手机号
export function isPhone(str) {
if (!isNull(str)) {
const reg = /^1[3456789]\d{9}$/;
return reg.test(str);
}
return false;
}
// 判断税号
export function isTax(str) {
if (!isNull(str)) {
const reg = /^[A-Z0-9]{15}$|^[A-Z0-9]{17}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/;
return reg.test(str);
}
return false;
}
// 判断银行号
export function isBankNumber(str) {
if (!isNull(str)) {
const reg = /^[0-9]{16}$|^[0-9]{17}$|^[0-9]{19}$/;
return reg.test(str);
}
return false;
}
import Vue from 'vue';
import Vuex from 'vuex';
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
......@@ -7,5 +7,5 @@ export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {},
modules: {}
});
......@@ -9,12 +9,12 @@
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: 'Home',
name: "Home",
components: {
HelloWorld,
},
HelloWorld
}
};
</script>
const path = require('path');
const path = require("path");
const resolve = dir => path.join(__dirname, dir);
const IS_PROD = process.env.NODE_ENV === 'production';
const IS_PROD = process.env.NODE_ENV === "production";
module.exports = {
chainWebpack: config => {
......@@ -8,57 +8,59 @@ module.exports = {
config.resolve.symlinks(true);
// 移除 prefetch 插件(针对生产环境首屏请求数进行优化)
config.plugins.delete('prefetch');
config.plugins.delete("prefetch");
// 移除 preload 插件(针对生产环境首屏请求数进行优化) preload 插件的用途:https://cli.vuejs.org/zh/guide/html-and-static-assets.html#preload
config.plugins.delete('preload');
config.plugins.delete("preload");
// 添加别名
config.resolve.alias.set('@', resolve('src'));
// set svg-sprite-loader
config.resolve.alias.set("@", resolve("src"));
// svg-sprite
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.rule("svg")
.exclude.add(resolve("src/assets/icons"))
.end();
config.module
.rule('icons')
.rule("icons")
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.include.add(resolve("src/assets/icons"))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: 'icon-[name]',
symbolId: "icon-[name]"
})
.end();
// 分包优化
config.optimization.splitChunks({
chunks: 'all',
chunks: "all",
cacheGroups: {
libs: {
name: 'chunk-libs',
name: "chunk-libs",
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial', // only package third parties that are initially dependent
chunks: "initial" // only package third parties that are initially dependent
},
// TODO 🤨打包没用,emmmmmmmmmmm
cherryUI: {
name: 'chunk-cherryUI', // split cherryUI into a single package
name: "chunk-cherryUI", // split cherryUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?cherry-ui(.*)/, // in order to adapt to cnpm
test: /[\\/]node_modules[\\/]@qg[\\/]_?cherry-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
name: "chunk-commons",
test: resolve("src/components"), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true,
},
},
reuseExistingChunk: true
}
}
});
// https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
config.optimization.runtimeChunk('single');
config.optimization.runtimeChunk("single");
return config;
},
lintOnSave: true,
runtimeCompiler: false, // 是否使用包含运行时编译器的 Vue 构建版本
productionSourceMap: IS_PROD, // 生产环境的 source map
productionSourceMap: IS_PROD // 生产环境的 source map
};
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment