mirror of
https://github.com/iczer/vue-antd-admin
synced 2025-04-06 04:00:06 +08:00
Merge pull request #123 from guoranred/master
add nprogress and cdn assets
This commit is contained in:
commit
7b23be808f
@ -1,5 +1,13 @@
|
||||
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV)
|
||||
|
||||
const plugins = []
|
||||
if (IS_PROD) {
|
||||
plugins.push('transform-remove-console')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
],
|
||||
plugins
|
||||
}
|
||||
|
@ -29,7 +29,8 @@
|
||||
"vue-i18n": "^8.18.2",
|
||||
"vue-router": "^3.3.4",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuex": "^3.4.0"
|
||||
"vuex": "^3.4.0",
|
||||
"nprogress": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/colors": "^4.0.1",
|
||||
@ -50,7 +51,9 @@
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuepress": "^1.5.2",
|
||||
"webpack-theme-color-replacer": "^1.3.12",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
"compression-webpack-plugin": "^2.0.0",
|
||||
"babel-plugin-transform-remove-console": "^6.9.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
@ -6,12 +6,20 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<!-- require cdn assets css -->
|
||||
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
|
||||
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
|
||||
<% } %>
|
||||
</head>
|
||||
<body class="beauty-scroll">
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- require cdn assets js -->
|
||||
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
|
||||
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
|
||||
<% } %>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<a-icon type="search" class="search-icon" @click="enterSearchMode"/>
|
||||
<a-auto-complete
|
||||
ref="input"
|
||||
:getPopupContainer="e => {return e.parentNode || document.body}"
|
||||
:dataSource="dataSource"
|
||||
:class="['search-input', searchMode ? 'enter' : 'leave']"
|
||||
placeholder="站内搜索"
|
||||
|
@ -1,6 +1,23 @@
|
||||
import {hasAuthority} from '@/utils/authority-utils'
|
||||
import {loginIgnore} from '@/router/index'
|
||||
import {checkAuthorization} from '@/utils/request'
|
||||
import NProgress from 'nprogress'
|
||||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
/**
|
||||
* 进度条开始
|
||||
* @param to
|
||||
* @param form
|
||||
* @param next
|
||||
*/
|
||||
const progressStart = (to, from, next) => {
|
||||
// start progress bar
|
||||
if (!NProgress.isStarted()) {
|
||||
NProgress.start()
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录守卫
|
||||
@ -33,6 +50,7 @@ const authorityGuard = (to, from, next, options) => {
|
||||
if (!hasAuthority(to, permissions, roles)) {
|
||||
message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`)
|
||||
next({path: '/403'})
|
||||
NProgress.done()
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
@ -61,7 +79,18 @@ const redirectGuard = (to, from, next, options) => {
|
||||
next()
|
||||
}
|
||||
|
||||
export default {
|
||||
beforeEach: [loginGuard, authorityGuard, redirectGuard],
|
||||
afterEach: []
|
||||
/**
|
||||
* 进度条结束
|
||||
* @param to
|
||||
* @param form
|
||||
* @param options
|
||||
*/
|
||||
const progressDone = () => {
|
||||
// finish progress bar
|
||||
NProgress.done()
|
||||
}
|
||||
|
||||
export default {
|
||||
beforeEach: [progressStart, loginGuard, authorityGuard, redirectGuard],
|
||||
afterEach: [progressDone]
|
||||
}
|
||||
|
@ -1,2 +1,3 @@
|
||||
@import "color";
|
||||
@import "style";
|
||||
@import "nprogress";
|
||||
|
76
src/theme/default/nprogress.less
Normal file
76
src/theme/default/nprogress.less
Normal file
@ -0,0 +1,76 @@
|
||||
@import '~ant-design-vue/lib/style/themes/default';
|
||||
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: @primary-color;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#nprogress .peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color;
|
||||
opacity: 1.0;
|
||||
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
/* Remove these to get rid of the spinner */
|
||||
#nprogress .spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: @primary-color;
|
||||
border-left-color: @primary-color;
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-animation: nprogress-spinner 400ms linear infinite;
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% { -webkit-transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
@ -1,7 +1,39 @@
|
||||
let path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const ThemeColorReplacer = require('webpack-theme-color-replacer')
|
||||
const {getThemeColors, modifyVars} = require('./src/utils/themeUtil')
|
||||
const {resolveCss} = require('./src/utils/theme-color-replacer-extend')
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
const productionGzipExtensions = ['js', 'css']
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
|
||||
const assetsCDN = {
|
||||
// webpack build externals
|
||||
externals: {
|
||||
vue: 'Vue',
|
||||
'vue-router': 'VueRouter',
|
||||
vuex: 'Vuex',
|
||||
axios: 'axios',
|
||||
nprogress: 'NProgress',
|
||||
clipboard: 'ClipboardJS',
|
||||
'@antv/data-set': 'DataSet',
|
||||
'js-cookie': 'Cookies'
|
||||
},
|
||||
css: [
|
||||
],
|
||||
js: [
|
||||
'//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vue-router@3.3.4/dist/vue-router.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js',
|
||||
'//cdn.jsdelivr.net/npm/axios@0.19.2/dist/axios.min.js',
|
||||
'//cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js',
|
||||
'//cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js',
|
||||
'//cdn.jsdelivr.net/npm/@antv/data-set@0.11.4/build/data-set.min.js',
|
||||
'//cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js'
|
||||
]
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
devServer: {
|
||||
// proxy: {
|
||||
@ -22,6 +54,9 @@ module.exports = {
|
||||
},
|
||||
configureWebpack: config => {
|
||||
config.entry.app = ["babel-polyfill", "whatwg-fetch", "./src/main.js"];
|
||||
config.performance = {
|
||||
hints: false
|
||||
}
|
||||
config.plugins.push(
|
||||
new ThemeColorReplacer({
|
||||
fileName: 'css/theme-colors-[contenthash:8].css',
|
||||
@ -30,16 +65,40 @@ module.exports = {
|
||||
resolveCss
|
||||
})
|
||||
)
|
||||
// Ignore all locale files of moment.js
|
||||
config.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
|
||||
// 生产环境下将资源压缩成gzip格式
|
||||
if (isProd) {
|
||||
// add `CompressionWebpack` plugin to webpack plugins
|
||||
config.plugins.push(new CompressionWebpackPlugin({
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
}))
|
||||
}
|
||||
// if prod, add externals
|
||||
if (isProd) {
|
||||
config.externals = assetsCDN.externals
|
||||
}
|
||||
},
|
||||
chainWebpack: config => {
|
||||
// 生产环境下关闭css压缩的 colormin 项,因为此项优化与主题色替换功能冲突
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
if (isProd) {
|
||||
config.plugin('optimize-css')
|
||||
.tap(args => {
|
||||
args[0].cssnanoOptions.preset[1].colormin = false
|
||||
return args
|
||||
})
|
||||
}
|
||||
// 生产环境下使用CDN
|
||||
if (isProd) {
|
||||
config.plugin('html')
|
||||
.tap(args => {
|
||||
args[0].cdn = assetsCDN
|
||||
return args
|
||||
})
|
||||
}
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
@ -51,7 +110,7 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
},
|
||||
publicPath: process.env.NODE_ENV === 'production' ? '/vue-antd-admin/' : '/',
|
||||
publicPath: isProd ? '/vue-antd-admin/' : '/',
|
||||
outputDir: 'dist',
|
||||
assetsDir: 'static',
|
||||
productionSourceMap: false
|
||||
|
Loading…
x
Reference in New Issue
Block a user