研发图纸文件管理系统-前端项目
iczer
2020-09-26 7b23be808f99a279f2489257ab086a163d75b485
Merge pull request #123 from guoranred/master

add nprogress and cdn assets
1个文件已添加
7个文件已修改
199 ■■■■■ 已修改文件
babel.config.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/header/HeaderSearch.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/guards.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/default/index.less 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/default/nprogress.less 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
babel.config.js
@@ -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
}
package.json
@@ -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,
public/index.html
@@ -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>
src/layouts/header/HeaderSearch.vue
@@ -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="站内搜索"
src/router/guards.js
@@ -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 @@
  if (!hasAuthority(to, permissions, roles)) {
    message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`)
    next({path: '/403'})
    NProgress.done()
  } else {
    next()
  }
@@ -61,7 +79,18 @@
  next()
}
/**
 * 进度条结束
 * @param to
 * @param form
 * @param options
 */
const progressDone = () => {
  // finish progress bar
  NProgress.done()
}
export default {
  beforeEach: [loginGuard, authorityGuard, redirectGuard],
  afterEach: []
  beforeEach: [progressStart, loginGuard, authorityGuard, redirectGuard],
  afterEach: [progressDone]
}
src/theme/default/index.less
@@ -1,2 +1,3 @@
@import "color";
@import "style";
@import "nprogress";
src/theme/default/nprogress.less
New 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); }
}
vue.config.js
@@ -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 @@
  },
  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,15 +65,39 @@
        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: {
@@ -51,7 +110,7 @@
      }
    }
  },
  publicPath: process.env.NODE_ENV === 'production' ? '/vue-antd-admin/' : '/',
  publicPath: isProd ? '/vue-antd-admin/' : '/',
  outputDir: 'dist',
  assetsDir: 'static',
  productionSourceMap: false