ソースを参照

feat[litemall-admin]: 更新vue-element-admin框架版本4.2.1

Junling Bu 6 年 前
コミット
e028dea9ef
38 ファイル変更369 行追加852 行削除
  1. 0 17
      litemall-admin/.babelrc
  2. 1 1
      litemall-admin/.editorconfig
  3. 8 0
      litemall-admin/.env.deployment
  4. 14 0
      litemall-admin/.env.development
  5. 8 0
      litemall-admin/.env.production
  6. 2 1
      litemall-admin/.eslintignore
  7. 4 1
      litemall-admin/.eslintrc.js
  8. 4 2
      litemall-admin/.gitignore
  9. 0 10
      litemall-admin/.postcssrc.js
  10. 0 5
      litemall-admin/.travis.yml
  11. 5 0
      litemall-admin/babel.config.js
  12. 26 58
      litemall-admin/build/build.js
  13. 0 64
      litemall-admin/build/check-versions.js
  14. BIN
      litemall-admin/build/logo.png
  15. 0 108
      litemall-admin/build/utils.js
  16. 0 5
      litemall-admin/build/vue-loader.conf.js
  17. 0 107
      litemall-admin/build/webpack.base.conf.js
  18. 0 98
      litemall-admin/build/webpack.dev.conf.js
  19. 0 188
      litemall-admin/build/webpack.prod.conf.js
  20. 0 5
      litemall-admin/config/dep.env.js
  21. 0 5
      litemall-admin/config/dev.env.js
  22. 0 88
      litemall-admin/config/index.js
  23. 0 5
      litemall-admin/config/prod.env.js
  24. 24 0
      litemall-admin/jest.config.js
  25. 9 0
      litemall-admin/jsconfig.json
  26. 72 75
      litemall-admin/package.json
  27. 5 0
      litemall-admin/postcss.config.js
  28. 0 0
      litemall-admin/public/favicon.ico
  29. 2 1
      litemall-admin/index.html
  30. BIN
      litemall-admin/src/assets/custom-theme/fonts/element-icons.ttf
  31. BIN
      litemall-admin/src/assets/custom-theme/fonts/element-icons.woff
  32. 0 1
      litemall-admin/src/assets/custom-theme/index.css
  33. 29 3
      litemall-admin/src/filters/index.js
  34. 2 2
      litemall-admin/src/main.js
  35. 31 0
      litemall-admin/src/styles/element-variables.scss
  36. 1 1
      litemall-admin/src/utils/request.js
  37. 1 1
      litemall-admin/src/views/errorPage/401.vue
  38. 121 0
      litemall-admin/vue.config.js

+ 0 - 17
litemall-admin/.babelrc

@@ -1,17 +0,0 @@
-{
-  "presets": [
-    ["env", {
-      "modules": false,
-      "targets": {
-        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
-      }
-    }],
-    "stage-2"
-  ],
-  "plugins": ["transform-vue-jsx", "transform-runtime"],
-  "env": {
-    "development":{
-      "plugins": ["dynamic-import-node"]
-    }
-  }
-}

+ 1 - 1
litemall-admin/.editorconfig

@@ -1,4 +1,4 @@
-# http://editorconfig.org
+# https://editorconfig.org
 root = true
 
 [*]

+ 8 - 0
litemall-admin/.env.deployment

@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'deploymenet'
+
+# base api
+VUE_APP_BASE_API = 'http://122.51.199.160:8080/admin'
+

+ 14 - 0
litemall-admin/.env.development

@@ -0,0 +1,14 @@
+# just a flag
+ENV = 'development'
+
+# base api
+VUE_APP_BASE_API = 'http://localhost:8080/admin'
+
+# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
+# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
+# It only does one thing by converting all import() to require().
+# This configuration can significantly increase the speed of hot updates,
+# when you have a large number of pages.
+# Detail:  https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
+
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 8 - 0
litemall-admin/.env.production

@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = 'https://www.example.com/admin'
+

+ 2 - 1
litemall-admin/.eslintignore

@@ -1,3 +1,4 @@
 build/*.js
-config/*.js
 src/assets
+public
+dist

+ 4 - 1
litemall-admin/.eslintrc.js

@@ -21,7 +21,10 @@ module.exports = {
         "allowFirstLine": false
       }
     }],
+    "vue/singleline-html-element-content-newline": "off",
+    "vue/multiline-html-element-content-newline":"off",
     "vue/name-property-casing": ["error", "PascalCase"],
+    "vue/no-v-html": "off",
     'accessor-pairs': 2,
     'arrow-spacing': [2, {
       'before': true,
@@ -44,7 +47,7 @@ module.exports = {
     'curly': [2, 'multi-line'],
     'dot-location': [2, 'property'],
     'eol-last': 2,
-    'eqeqeq': [2, 'allow-null'],
+    'eqeqeq': ["error", "always", {"null": "ignore"}],
     'generator-star-spacing': [2, {
       'before': true,
       'after': true

+ 4 - 2
litemall-admin/.gitignore

@@ -6,8 +6,8 @@ yarn-debug.log*
 yarn-error.log*
 **/*.log
 
-test/unit/coverage
-test/e2e/reports
+tests/**/coverage/
+tests/e2e/reports
 selenium-debug.log
 
 # Editor directories and files
@@ -17,5 +17,7 @@ selenium-debug.log
 *.ntvs*
 *.njsproj
 *.sln
+*.local
 
 package-lock.json
+yarn.lock

+ 0 - 10
litemall-admin/.postcssrc.js

@@ -1,10 +0,0 @@
-// https://github.com/michael-ciniawsky/postcss-load-config
-
-module.exports = {
-  "plugins": {
-    "postcss-import": {},
-    "postcss-url": {},
-    // to edit target browsers: use "browserslist" field in package.json
-    "autoprefixer": {}
-  }
-}

+ 0 - 5
litemall-admin/.travis.yml

@@ -1,5 +0,0 @@
-language: node_js
-node_js: stable
-script: npm run test
-notifications:
-  email: false

+ 5 - 0
litemall-admin/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/app'
+  ]
+}

+ 26 - 58
litemall-admin/build/build.js

@@ -1,67 +1,35 @@
-'use strict'
-require('./check-versions')()
-
-const ora = require('ora')
-const rm = require('rimraf')
-const path = require('path')
+const { run } = require('runjs')
 const chalk = require('chalk')
-const webpack = require('webpack')
-const config = require('../config')
-const webpackConfig = require('./webpack.prod.conf')
-var connect = require('connect')
-var serveStatic = require('serve-static')
-
-const spinner = ora(
-  'building for ' + process.env.env_config + ' environment...'
-)
-spinner.start()
+const config = require('../vue.config.js')
+const rawArgv = process.argv.slice(2)
+const args = rawArgv.join(' ')
 
-rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
-  if (err) throw err
-  webpack(webpackConfig, (err, stats) => {
-    spinner.stop()
-    if (err) throw err
-    process.stdout.write(
-      stats.toString({
-        colors: true,
-        modules: false,
-        children: false,
-        chunks: false,
-        chunkModules: false
-      }) + '\n\n'
-    )
+if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
+  const report = rawArgv.includes('--report')
 
-    if (stats.hasErrors()) {
-      console.log(chalk.red(' Build failed with errors.\n'))
-      process.exit(1)
-    }
+  run(`vue-cli-service build ${args}`)
 
-    console.log(chalk.cyan(' Build complete.\n'))
-    console.log(
-      chalk.yellow(
-        ' Tip: built files are meant to be served over an HTTP server.\n' +
-          " Opening index.html over file:// won't work.\n"
-      )
-    )
+  const port = 9526
+  const publicPath = config.publicPath
 
-    if (process.env.npm_config_preview) {
-      const port = 9526
-      const host = 'http://localhost:' + port
-      const basePath = config.build.assetsPublicPath
-      const app = connect()
+  var connect = require('connect')
+  var serveStatic = require('serve-static')
+  const app = connect()
 
-      app.use(
-        basePath,
-        serveStatic('./dist', {
-          index: ['index.html', '/']
-        })
-      )
+  app.use(
+    publicPath,
+    serveStatic('./dist', {
+      index: ['index.html', '/']
+    })
+  )
 
-      app.listen(port, function() {
-        console.log(
-          chalk.green(`> Listening at  http://localhost:${port}${basePath}`)
-        )
-      })
+  app.listen(port, function () {
+    console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`))
+    if (report) {
+      console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`))
     }
+
   })
-})
+} else {
+  run(`vue-cli-service build ${args}`)
+}

+ 0 - 64
litemall-admin/build/check-versions.js

@@ -1,64 +0,0 @@
-'use strict'
-const chalk = require('chalk')
-const semver = require('semver')
-const packageConfig = require('../package.json')
-const shell = require('shelljs')
-
-function exec(cmd) {
-  return require('child_process')
-    .execSync(cmd)
-    .toString()
-    .trim()
-}
-
-const versionRequirements = [
-  {
-    name: 'node',
-    currentVersion: semver.clean(process.version),
-    versionRequirement: packageConfig.engines.node
-  }
-]
-
-if (shell.which('npm')) {
-  versionRequirements.push({
-    name: 'npm',
-    currentVersion: exec('npm --version'),
-    versionRequirement: packageConfig.engines.npm
-  })
-}
-
-module.exports = function() {
-  const warnings = []
-
-  for (let i = 0; i < versionRequirements.length; i++) {
-    const mod = versionRequirements[i]
-
-    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
-      warnings.push(
-        mod.name +
-          ': ' +
-          chalk.red(mod.currentVersion) +
-          ' should be ' +
-          chalk.green(mod.versionRequirement)
-      )
-    }
-  }
-
-  if (warnings.length) {
-    console.log('')
-    console.log(
-      chalk.yellow(
-        'To use this template, you must update following to modules:'
-      )
-    )
-    console.log()
-
-    for (let i = 0; i < warnings.length; i++) {
-      const warning = warnings[i]
-      console.log('  ' + warning)
-    }
-
-    console.log()
-    process.exit(1)
-  }
-}

BIN
litemall-admin/build/logo.png


+ 0 - 108
litemall-admin/build/utils.js

@@ -1,108 +0,0 @@
-'use strict'
-const path = require('path')
-const config = require('../config')
-const MiniCssExtractPlugin = require('mini-css-extract-plugin')
-const packageConfig = require('../package.json')
-
-exports.assetsPath = function(_path) {
-  const assetsSubDirectory =
-    process.env.NODE_ENV === 'production'
-      ? config.build.assetsSubDirectory
-      : config.dev.assetsSubDirectory
-
-  return path.posix.join(assetsSubDirectory, _path)
-}
-
-exports.cssLoaders = function(options) {
-  options = options || {}
-
-  const cssLoader = {
-    loader: 'css-loader',
-    options: {
-      sourceMap: options.sourceMap
-    }
-  }
-
-  const postcssLoader = {
-    loader: 'postcss-loader',
-    options: {
-      sourceMap: options.sourceMap
-    }
-  }
-
-  // generate loader string to be used with extract text plugin
-  function generateLoaders(loader, loaderOptions) {
-    const loaders = []
-
-    // Extract CSS when that option is specified
-    // (which is the case during production build)
-    if (options.extract) {
-      loaders.push(MiniCssExtractPlugin.loader)
-    } else {
-      loaders.push('vue-style-loader')
-    }
-
-    loaders.push(cssLoader)
-
-    if (options.usePostCSS) {
-      loaders.push(postcssLoader)
-    }
-
-    if (loader) {
-      loaders.push({
-        loader: loader + '-loader',
-        options: Object.assign({}, loaderOptions, {
-          sourceMap: options.sourceMap
-        })
-      })
-    }
-
-    return loaders
-  }
-  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
-  return {
-    css: generateLoaders(),
-    postcss: generateLoaders(),
-    less: generateLoaders('less'),
-    sass: generateLoaders('sass', {
-      indentedSyntax: true
-    }),
-    scss: generateLoaders('sass'),
-    stylus: generateLoaders('stylus'),
-    styl: generateLoaders('stylus')
-  }
-}
-
-// Generate loaders for standalone style files (outside of .vue)
-exports.styleLoaders = function(options) {
-  const output = []
-  const loaders = exports.cssLoaders(options)
-
-  for (const extension in loaders) {
-    const loader = loaders[extension]
-    output.push({
-      test: new RegExp('\\.' + extension + '$'),
-      use: loader
-    })
-  }
-
-  return output
-}
-
-exports.createNotifierCallback = () => {
-  const notifier = require('node-notifier')
-
-  return (severity, errors) => {
-    if (severity !== 'error') return
-
-    const error = errors[0]
-    const filename = error.file && error.file.split('!').pop()
-
-    notifier.notify({
-      title: packageConfig.name,
-      message: severity + ': ' + error.name,
-      subtitle: filename || '',
-      icon: path.join(__dirname, 'logo.png')
-    })
-  }
-}

+ 0 - 5
litemall-admin/build/vue-loader.conf.js

@@ -1,5 +0,0 @@
-'use strict'
-
-module.exports = {
-  //You can set the vue-loader configuration by yourself.
-}

+ 0 - 107
litemall-admin/build/webpack.base.conf.js

@@ -1,107 +0,0 @@
-'use strict'
-const path = require('path')
-const utils = require('./utils')
-const config = require('../config')
-const { VueLoaderPlugin } = require('vue-loader')
-const vueLoaderConfig = require('./vue-loader.conf')
-
-function resolve(dir) {
-  return path.join(__dirname, '..', dir)
-}
-
-const createLintingRule = () => ({
-  test: /\.(js|vue)$/,
-  loader: 'eslint-loader',
-  enforce: 'pre',
-  include: [resolve('src'), resolve('test')],
-  options: {
-    formatter: require('eslint-friendly-formatter'),
-    emitWarning: !config.dev.showEslintErrorsInOverlay
-  }
-})
-
-module.exports = {
-  context: path.resolve(__dirname, '../'),
-  entry: {
-    app: './src/main.js'
-  },
-  output: {
-    path: config.build.assetsRoot,
-    filename: '[name].js',
-    publicPath:
-      process.env.NODE_ENV === 'production'
-        ? config.build.assetsPublicPath
-        : config.dev.assetsPublicPath
-  },
-  resolve: {
-    extensions: ['.js', '.vue', '.json'],
-    alias: {
-      '@': resolve('src')
-    }
-  },
-  module: {
-    rules: [
-      ...(config.dev.useEslint ? [createLintingRule()] : []),
-      {
-        test: /\.vue$/,
-        loader: 'vue-loader',
-        options: vueLoaderConfig
-      },
-      {
-        test: /\.js$/,
-        loader: 'babel-loader?cacheDirectory',
-        include: [
-          resolve('src'),
-          resolve('test'),
-          resolve('node_modules/webpack-dev-server/client')
-        ]
-      },
-      {
-        test: /\.svg$/,
-        loader: 'svg-sprite-loader',
-        include: [resolve('src/icons')],
-        options: {
-          symbolId: 'icon-[name]'
-        }
-      },
-      {
-        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
-        loader: 'url-loader',
-        exclude: [resolve('src/icons')],
-        options: {
-          limit: 10000,
-          name: utils.assetsPath('img/[name].[hash:7].[ext]')
-        }
-      },
-      {
-        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
-        loader: 'url-loader',
-        options: {
-          limit: 10000,
-          name: utils.assetsPath('media/[name].[hash:7].[ext]')
-        }
-      },
-      {
-        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
-        loader: 'url-loader',
-        options: {
-          limit: 10000,
-          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
-        }
-      }
-    ]
-  },
-  plugins: [new VueLoaderPlugin()],
-  node: {
-    // prevent webpack from injecting useless setImmediate polyfill because Vue
-    // source contains it (although only uses it if it's native).
-    setImmediate: false,
-    // prevent webpack from injecting mocks to Node native modules
-    // that does not make sense for the client
-    dgram: 'empty',
-    fs: 'empty',
-    net: 'empty',
-    tls: 'empty',
-    child_process: 'empty'
-  }
-}

+ 0 - 98
litemall-admin/build/webpack.dev.conf.js

@@ -1,98 +0,0 @@
-'use strict'
-const path = require('path')
-const utils = require('./utils')
-const webpack = require('webpack')
-const config = require('../config')
-const merge = require('webpack-merge')
-const baseWebpackConfig = require('./webpack.base.conf')
-const HtmlWebpackPlugin = require('html-webpack-plugin')
-const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
-const portfinder = require('portfinder')
-
-function resolve(dir) {
-  return path.join(__dirname, '..', dir)
-}
-
-const HOST = process.env.HOST
-const PORT = process.env.PORT && Number(process.env.PORT)
-
-const devWebpackConfig = merge(baseWebpackConfig, {
-  mode: 'development',
-  module: {
-    rules: utils.styleLoaders({
-      sourceMap: config.dev.cssSourceMap,
-      usePostCSS: true
-    })
-  },
-  // cheap-module-eval-source-map is faster for development
-  devtool: config.dev.devtool,
-
-  // these devServer options should be customized in /config/index.js
-  devServer: {
-    clientLogLevel: 'warning',
-    historyApiFallback: true,
-    hot: true,
-    compress: true,
-    host: HOST || config.dev.host,
-    port: PORT || config.dev.port,
-    open: config.dev.autoOpenBrowser,
-    overlay: config.dev.errorOverlay
-      ? { warnings: false, errors: true }
-      : false,
-    publicPath: config.dev.assetsPublicPath,
-    proxy: config.dev.proxyTable,
-    quiet: true, // necessary for FriendlyErrorsPlugin
-    watchOptions: {
-      poll: config.dev.poll
-    }
-  },
-  plugins: [
-    new webpack.DefinePlugin({
-      'process.env': require('../config/dev.env')
-    }),
-    new webpack.HotModuleReplacementPlugin(),
-    // https://github.com/ampedandwired/html-webpack-plugin
-    new HtmlWebpackPlugin({
-      filename: 'index.html',
-      template: 'index.html',
-      inject: true,
-      favicon: resolve('favicon.ico'),
-      title: 'vue-element-admin',
-      templateParameters: {
-        BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory,
-      },
-    }),
-  ]
-})
-
-module.exports = new Promise((resolve, reject) => {
-  portfinder.basePort = process.env.PORT || config.dev.port
-  portfinder.getPort((err, port) => {
-    if (err) {
-      reject(err)
-    } else {
-      // publish the new Port, necessary for e2e tests
-      process.env.PORT = port
-      // add port to devServer config
-      devWebpackConfig.devServer.port = port
-
-      // Add FriendlyErrorsPlugin
-      devWebpackConfig.plugins.push(
-        new FriendlyErrorsPlugin({
-          compilationSuccessInfo: {
-            messages: [
-              `Your application is running here: http://${
-                devWebpackConfig.devServer.host
-              }:${port}`
-            ]
-          },
-          onErrors: config.dev.notifyOnErrors
-            ? utils.createNotifierCallback()
-            : undefined
-        })
-      )
-
-      resolve(devWebpackConfig)
-    }
-  })
-})

+ 0 - 188
litemall-admin/build/webpack.prod.conf.js

@@ -1,188 +0,0 @@
-'use strict'
-const path = require('path')
-const utils = require('./utils')
-const webpack = require('webpack')
-const config = require('../config')
-const merge = require('webpack-merge')
-const baseWebpackConfig = require('./webpack.base.conf')
-const CopyWebpackPlugin = require('copy-webpack-plugin')
-const HtmlWebpackPlugin = require('html-webpack-plugin')
-const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
-const MiniCssExtractPlugin = require('mini-css-extract-plugin')
-const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
-
-function resolve(dir) {
-  return path.join(__dirname, '..', dir)
-}
-
-const env = require('../config/' + process.env.env_config + '.env')
-
-// For NamedChunksPlugin
-const seen = new Set()
-const nameLength = 4
-
-const webpackConfig = merge(baseWebpackConfig, {
-  mode: 'production',
-  module: {
-    rules: utils.styleLoaders({
-      sourceMap: config.build.productionSourceMap,
-      extract: true,
-      usePostCSS: true
-    })
-  },
-  devtool: config.build.productionSourceMap ? config.build.devtool : false,
-  output: {
-    path: config.build.assetsRoot,
-    filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
-    chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
-  },
-  plugins: [
-    // http://vuejs.github.io/vue-loader/en/workflow/production.html
-    new webpack.DefinePlugin({
-      'process.env': env
-    }),
-    // extract css into its own file
-    new MiniCssExtractPlugin({
-      filename: utils.assetsPath('css/[name].[contenthash:8].css'),
-      chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
-    }),
-    // generate dist index.html with correct asset hash for caching.
-    // you can customize output by editing /index.html
-    // see https://github.com/ampedandwired/html-webpack-plugin
-    new HtmlWebpackPlugin({
-      filename: config.build.index,
-      template: 'index.html',
-      inject: true,
-      favicon: resolve('favicon.ico'),
-      title: 'vue-element-admin',
-      templateParameters: {
-        BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory,
-      },
-      minify: {
-        removeComments: true,
-        collapseWhitespace: true,
-        removeAttributeQuotes: true
-        // more options:
-        // https://github.com/kangax/html-minifier#options-quick-reference
-      }
-      // default sort mode uses toposort which cannot handle cyclic deps
-      // in certain cases, and in webpack 4, chunk order in HTML doesn't
-      // matter anyway
-    }),
-    new ScriptExtHtmlWebpackPlugin({
-      //`runtime` must same as runtimeChunk name. default is `runtime`
-      inline: /runtime\..*\.js$/
-    }),
-    // keep chunk.id stable when chunk has no name
-    new webpack.NamedChunksPlugin(chunk => {
-      if (chunk.name) {
-        return chunk.name
-      }
-      const modules = Array.from(chunk.modulesIterable)
-      if (modules.length > 1) {
-        const hash = require('hash-sum')
-        const joinedHash = hash(modules.map(m => m.id).join('_'))
-        let len = nameLength
-        while (seen.has(joinedHash.substr(0, len))) len++
-        seen.add(joinedHash.substr(0, len))
-        return `chunk-${joinedHash.substr(0, len)}`
-      } else {
-        return modules[0].id
-      }
-    }),
-    // keep module.id stable when vender modules does not change
-    new webpack.HashedModuleIdsPlugin(),
-    // copy custom static assets
-    new CopyWebpackPlugin([
-      {
-        from: path.resolve(__dirname, '../static'),
-        to: config.build.assetsSubDirectory,
-        ignore: ['.*']
-      }
-    ])
-  ],
-  optimization: {
-    splitChunks: {
-      chunks: 'all',
-      cacheGroups: {
-        libs: {
-          name: 'chunk-libs',
-          test: /[\\/]node_modules[\\/]/,
-          priority: 10,
-          chunks: 'initial' // 只打包初始时依赖的第三方
-        },
-        elementUI: {
-          name: 'chunk-elementUI', // 单独将 elementUI 拆包
-          priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
-          test: /[\\/]node_modules[\\/]element-ui[\\/]/
-        },
-        commons: {
-          name: 'chunk-commons',
-          test: resolve('src/components'), // 可自定义拓展你的规则
-          minChunks: 3, // 最小公用次数
-          priority: 5,
-          reuseExistingChunk: true
-        }
-      }
-    },
-    runtimeChunk: 'single',
-    minimizer: [
-      new UglifyJsPlugin({
-        uglifyOptions: {
-          mangle: {
-            safari10: true
-          }
-        },
-        sourceMap: config.build.productionSourceMap,
-        cache: true,
-        parallel: true
-      }),
-      // Compress extracted CSS. We are using this plugin so that possible
-      // duplicated CSS from different components can be deduped.
-      new OptimizeCSSAssetsPlugin()
-    ]
-  }
-})
-
-if (config.build.productionGzip) {
-  const CompressionWebpackPlugin = require('compression-webpack-plugin')
-
-  webpackConfig.plugins.push(
-    new CompressionWebpackPlugin({
-      asset: '[path].gz[query]',
-      algorithm: 'gzip',
-      test: new RegExp(
-        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
-      ),
-      threshold: 10240,
-      minRatio: 0.8
-    })
-  )
-}
-
-if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
-  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
-    .BundleAnalyzerPlugin
-
-  if (config.build.bundleAnalyzerReport) {
-    webpackConfig.plugins.push(
-      new BundleAnalyzerPlugin({
-        analyzerPort: 8080,
-        generateStatsFile: false
-      })
-    )
-  }
-
-  if (config.build.generateAnalyzerReport) {
-    webpackConfig.plugins.push(
-      new BundleAnalyzerPlugin({
-        analyzerMode: 'static',
-        reportFilename: 'bundle-report.html',
-        openAnalyzer: false
-      })
-    )
-  }
-}
-
-module.exports = webpackConfig

+ 0 - 5
litemall-admin/config/dep.env.js

@@ -1,5 +0,0 @@
-module.exports = {
-	NODE_ENV: '"production"',
-  ENV_CONFIG: '"dep"',
-  BASE_API: '"http://122.51.199.160:8080/admin"'
-}

+ 0 - 5
litemall-admin/config/dev.env.js

@@ -1,5 +0,0 @@
-module.exports = {
-	NODE_ENV: '"development"',
-  ENV_CONFIG: '"dev"',
-  BASE_API: '"http://localhost:8080/admin"'
-}

+ 0 - 88
litemall-admin/config/index.js

@@ -1,88 +0,0 @@
-'use strict'
-// Template version: 1.2.6
-// see http://vuejs-templates.github.io/webpack for documentation.
-
-const path = require('path')
-
-module.exports = {
-  dev: {
-    // Paths
-    assetsSubDirectory: 'static',
-    assetsPublicPath: '/',
-    proxyTable: {},
-
-    // Various Dev Server settings
-
-    // can be overwritten by process.env.HOST
-    // if you want dev by ip, please set host: '0.0.0.0'
-    host: 'localhost',
-    port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
-    autoOpenBrowser: true,
-    errorOverlay: true,
-    notifyOnErrors: false,
-    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
-
-    // Use Eslint Loader?
-    // If true, your code will be linted during bundling and
-    // linting errors and warnings will be shown in the console.
-    useEslint: true,
-    // If true, eslint errors and warnings will also be shown in the error overlay
-    // in the browser.
-    showEslintErrorsInOverlay: false,
-
-    /**
-     * Source Maps
-     */
-
-    // https://webpack.js.org/configuration/devtool/#development
-    devtool: 'cheap-source-map',
-
-    // CSS Sourcemaps off by default because relative paths are "buggy"
-    // with this option, according to the CSS-Loader README
-    // (https://github.com/webpack/css-loader#sourcemaps)
-    // In our experience, they generally work as expected,
-    // just be aware of this issue when enabling this option.
-    cssSourceMap: false
-  },
-
-  build: {
-    // Template for index.html
-    index: path.resolve(__dirname, '../dist/index.html'),
-
-    // Paths
-    assetsRoot: path.resolve(__dirname, '../dist'),
-    assetsSubDirectory: 'static',
-
-    /**
-     * You can set by youself according to actual condition
-     * You will need to set this if you plan to deploy your site under a sub path,
-     * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
-     * then assetsPublicPath should be set to "/bar/".
-     * In most cases please use '/' !!!
-     */
-    assetsPublicPath: './',
-
-    /**
-     * Source Maps
-     */
-    productionSourceMap: false,
-    // https://webpack.js.org/configuration/devtool/#production
-    devtool: 'source-map',
-
-    // Gzip off by default as many popular static hosts such as
-    // Surge or Netlify already gzip all static assets for you.
-    // Before setting to `true`, make sure to:
-    // npm install --save-dev compression-webpack-plugin
-    productionGzip: false,
-    productionGzipExtensions: ['js', 'css'],
-
-    // Run the build command with an extra argument to
-    // View the bundle analyzer report after build finishes:
-    // `npm run build:prod --report`
-    // Set to `true` or `false` to always turn it on or off
-    bundleAnalyzerReport: process.env.npm_config_report || false,
-
-    // `npm run build:prod --generate_report`
-    generateAnalyzerReport: process.env.npm_config_generate_report || false
-  }
-}

+ 0 - 5
litemall-admin/config/prod.env.js

@@ -1,5 +0,0 @@
-module.exports = {
-	NODE_ENV: '"production"',
-	ENV_CONFIG: '"prod"',
-    BASE_API: '"https://www.example.com/admin"'
-}

+ 24 - 0
litemall-admin/jest.config.js

@@ -0,0 +1,24 @@
+module.exports = {
+  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
+  transform: {
+    '^.+\\.vue$': 'vue-jest',
+    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
+      'jest-transform-stub',
+    '^.+\\.jsx?$': 'babel-jest'
+  },
+  moduleNameMapper: {
+    '^@/(.*)$': '<rootDir>/src/$1'
+  },
+  snapshotSerializers: ['jest-serializer-vue'],
+  testMatch: [
+    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
+  ],
+  collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
+  coverageDirectory: '<rootDir>/tests/unit/coverage',
+  // 'collectCoverage': true,
+  'coverageReporters': [
+    'lcov',
+    'text-summary'
+  ],
+  testURL: 'http://localhost/'
+}

+ 9 - 0
litemall-admin/jsconfig.json

@@ -0,0 +1,9 @@
+{ 
+  "compilerOptions": {
+    "baseUrl": "./",
+    "paths": {
+        "@/*": ["src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

+ 72 - 75
litemall-admin/package.json

@@ -1,18 +1,25 @@
 {
   "name": "litemall-admin",
-  "version": "0.1.0",
-  "description": "litemall-admin basing on vue-element-admin 3.9.3",
+  "version": "1.0.0",
+  "description": "litemall-admin basing on vue-element-admin 4.2.1",
   "author": "linlinjava <linlinjava@163.com>",
   "license": "MIT",
-  "private": true,
   "scripts": {
-    "dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
-    "build:dep": "cross-env NODE_ENV=production env_config=dep node build/build.js",
-    "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
+    "dev": "vue-cli-service serve",
+    "build": "vue-cli-service build --mode production",
+    "build:prod": "vue-cli-service build --mode production",
+    "build:dep": "vue-cli-service build --mode deployment",
+    "preview": "node build/index.js --preview",
     "lint": "eslint --ext .js,.vue src",
-    "test": "npm run lint",
-    "precommit": "lint-staged",
-    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
+    "test:unit": "jest --clearCache && vue-cli-service test:unit",
+    "test:ci": "npm run lint && npm run test:unit",
+    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
+    "new": "plop"
+  },
+  "husky": {
+    "hooks": {
+      "pre-commit": "lint-staged"
+    }
   },
   "lint-staged": {
     "src/**/*.{js,vue}": [
@@ -20,90 +27,80 @@
       "git add"
     ]
   },
+  "keywords": [
+    "vue",
+    "admin",
+    "dashboard",
+    "element-ui",
+    "boilerplate",
+    "admin-template",
+    "management-system"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/linlinjava/litemall.git"
+  },
+  "bugs": {
+    "url": "https://github.com/linlinjava/litemall/issues"
+  },
   "dependencies": {
     "@tinymce/tinymce-vue": "1.1.0",
-    "@riophae/vue-treeselect": "0.0.37",
     "v-charts": "1.19.0",
-    "axios": ">=0.18.1",
-    "clipboard": "1.7.1",
+    "axios": "0.18.1",
+    "clipboard": "2.0.4",
     "connect": "3.6.6",
-    "echarts": "4.1.0",
+    "echarts": "4.2.1",
     "element-ui": "2.12.0",
     "file-saver": "1.3.8",
-    "font-awesome": "4.7.0",
     "js-cookie": "2.2.0",
-    "jszip": "3.1.5",
+    "jszip": "3.2.1",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
-    "screenfull": "3.3.3",
-    "vue": "2.5.17",
+    "screenfull": "4.2.0",
+    "vue": "2.6.10",
     "vue-count-to": "1.0.13",
-    "vue-router": "3.0.1",
-    "vuex": "3.0.1",
-    "xlsx": "^0.11.16"
+    "vue-router": "3.0.2",
+    "vuex": "3.1.0",
+    "xlsx": "0.14.1"
   },
   "devDependencies": {
-    "autoprefixer": "8.5.0",
-    "babel-core": "6.26.3",
-    "babel-eslint": "8.2.6",
-    "babel-helper-vue-jsx-merge-props": "2.0.3",
-    "babel-loader": "7.1.5",
-    "babel-plugin-dynamic-import-node": "2.0.0",
-    "babel-plugin-syntax-jsx": "6.18.0",
-    "babel-plugin-transform-runtime": "6.23.0",
-    "babel-plugin-transform-vue-jsx": "3.7.0",
-    "babel-preset-env": "1.7.0",
-    "babel-preset-stage-2": "6.24.1",
-    "chalk": "2.4.1",
-    "copy-webpack-plugin": "4.5.2",
-    "cross-env": "5.2.0",
-    "css-loader": "1.0.0",
-    "eslint": "4.19.1",
-    "eslint-friendly-formatter": "4.0.1",
-    "eslint-loader": "2.0.0",
-    "eslint-plugin-vue": "4.7.1",
-    "file-loader": "1.1.11",
-    "friendly-errors-webpack-plugin": "1.7.0",
-    "hash-sum": "1.0.2",
-    "html-webpack-plugin": "4.0.0-alpha",
-    "husky": "0.14.3",
-    "lint-staged": "7.2.2",
-    "mini-css-extract-plugin": "0.4.1",
-    "node-notifier": "5.2.1",
-    "node-sass": "^4.7.2",
-    "optimize-css-assets-webpack-plugin": "5.0.0",
-    "ora": "3.0.0",
-    "path-to-regexp": "2.4.0",
-    "portfinder": "1.0.13",
-    "postcss-import": "11.1.0",
-    "postcss-loader": "2.1.6",
-    "postcss-url": "7.3.2",
-    "rimraf": "2.6.2",
-    "sass-loader": "7.0.3",
-    "script-ext-html-webpack-plugin": "2.0.1",
+    "@babel/core": "7.0.0",
+    "@babel/register": "7.0.0",
+    "@vue/cli-plugin-babel": "3.5.3",
+    "@vue/cli-plugin-eslint": "^3.9.1",
+    "@vue/cli-plugin-unit-jest": "3.5.3",
+    "@vue/cli-service": "3.5.3",
+    "@vue/test-utils": "1.0.0-beta.29",
+    "autoprefixer": "^9.5.1",
+    "babel-core": "7.0.0-bridge.0",
+    "babel-eslint": "10.0.1",
+    "babel-jest": "23.6.0",
+    "chalk": "2.4.2",
+    "chokidar": "2.1.5",
+    "connect": "3.6.6",
+    "eslint": "5.15.3",
+    "eslint-plugin-vue": "5.2.2",
+    "html-webpack-plugin": "3.2.0",
+    "husky": "1.3.1",
+    "lint-staged": "8.1.5",
+    "mockjs": "1.0.1-beta3",
+    "node-sass": "^4.9.0",
+    "plop": "2.3.0",
+    "runjs": "^4.3.2",
+    "sass-loader": "^7.1.0",
+    "script-ext-html-webpack-plugin": "2.1.3",
     "script-loader": "0.7.2",
-    "semver": "5.5.0",
-    "serve-static": "1.13.2",
-    "shelljs": "0.8.2",
-    "svg-sprite-loader": "3.8.0",
-    "svgo": "1.0.5",
-    "uglifyjs-webpack-plugin": "1.2.7",
-    "url-loader": "1.0.1",
-    "vue-loader": "15.3.0",
-    "vue-style-loader": "4.1.2",
-    "vue-template-compiler": "2.5.17",
-    "webpack": "4.16.5",
-    "webpack-cli": "3.1.0",
-    "webpack-dev-server": "3.1.14",
-    "webpack-merge": "4.1.4"
+    "serve-static": "^1.13.2",
+    "svg-sprite-loader": "4.1.3",
+    "svgo": "1.2.0",
+    "vue-template-compiler": "2.6.10"
   },
   "engines": {
-    "node": ">= 6.0.0",
+    "node": ">=8.9",
     "npm": ">= 3.0.0"
   },
   "browserslist": [
     "> 1%",
-    "last 2 versions",
-    "not ie <= 8"
+    "last 2 versions"
   ]
 }

+ 5 - 0
litemall-admin/postcss.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  plugins: {
+    autoprefixer: {}
+  }
+}

litemall-admin/favicon.ico → litemall-admin/public/favicon.ico


+ 2 - 1
litemall-admin/index.html

@@ -5,7 +5,8 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta name="renderer" content="webkit">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <title>litemall-admin</title>
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= webpackConfig.name %></title>
   </head>
   <body>
     <div id="app"></div>

BIN
litemall-admin/src/assets/custom-theme/fonts/element-icons.ttf


BIN
litemall-admin/src/assets/custom-theme/fonts/element-icons.woff


ファイルの差分が大きいため隠しています
+ 0 - 1
litemall-admin/src/assets/custom-theme/index.css


+ 29 - 3
litemall-admin/src/filters/index.js

@@ -1,6 +1,12 @@
-// set function parseTime,formatTime to filter
+// import parseTime, formatTime and set to filter
 export { parseTime, formatTime } from '@/utils'
 
+/**
+ * Show plural label if time is plural number
+ * @param {number} time
+ * @param {string} label
+ * @return {string}
+ */
 function pluralize(time, label) {
   if (time === 1) {
     return time + label
@@ -8,6 +14,9 @@ function pluralize(time, label) {
   return time + label + 's'
 }
 
+/**
+ * @param {number} time
+ */
 export function timeAgo(time) {
   const between = Date.now() / 1000 - Number(time)
   if (between < 3600) {
@@ -19,7 +28,12 @@ export function timeAgo(time) {
   }
 }
 
-/* 数字 格式化*/
+/**
+ * Number formatting
+ * like 10000 => 10k
+ * @param {number} num
+ * @param {number} digits
+ */
 export function numberFormatter(num, digits) {
   const si = [
     { value: 1E18, symbol: 'E' },
@@ -31,12 +45,24 @@ export function numberFormatter(num, digits) {
   ]
   for (let i = 0; i < si.length; i++) {
     if (num >= si[i].value) {
-      return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
+      return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
     }
   }
   return num.toString()
 }
 
+/**
+ * 10000 => "10,000"
+ * @param {number} num
+ */
 export function toThousandFilter(num) {
   return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
 }
+
+/**
+ * Upper case first char
+ * @param {String} string
+ */
+export function uppercaseFirst(string) {
+  return string.charAt(0).toUpperCase() + string.slice(1)
+}

+ 2 - 2
litemall-admin/src/main.js

@@ -5,13 +5,13 @@ import Cookies from 'js-cookie'
 import 'normalize.css/normalize.css' // A modern alternative to CSS resets
 
 import Element from 'element-ui'
-import 'element-ui/lib/theme-chalk/index.css'
+import './styles/element-variables.scss'
 
 import '@/styles/index.scss' // global css
 
 import App from './App'
-import router from './router'
 import store from './store'
+import router from './router'
 
 import './icons' // icon
 import './permission' // permission control

+ 31 - 0
litemall-admin/src/styles/element-variables.scss

@@ -0,0 +1,31 @@
+/**
+* I think element-ui's default theme color is too light for long-term use.
+* So I modified the default color and you can modify it to your liking.
+**/
+
+/* theme color */
+$--color-primary: #1890ff;
+$--color-success: #13ce66;
+$--color-warning: #FFBA00;
+$--color-danger: #ff4949;
+// $--color-info: #1E1E1E;
+
+$--button-font-weight: 400;
+
+// $--color-text-regular: #1f2d3d;
+
+$--border-color-light: #dfe4ed;
+$--border-color-lighter: #e6ebf5;
+
+$--table-border:1px solid#dfe6ec;
+
+/* icon font path, required */
+$--font-path: '~element-ui/lib/theme-chalk/fonts';
+
+@import "~element-ui/packages/theme-chalk/src/index";
+
+// the :export directive is the magic sauce for webpack
+// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
+:export {
+  theme: $--color-primary;
+}

+ 1 - 1
litemall-admin/src/utils/request.js

@@ -5,7 +5,7 @@ import { getToken } from '@/utils/auth'
 
 // create an axios instance
 const service = axios.create({
-  baseURL: process.env.BASE_API, // api 的 base_url
+  baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
   timeout: 5000 // request timeout
 })
 

+ 1 - 1
litemall-admin/src/views/errorPage/401.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="errPage-container">
-    <el-button icon="arrow-left" class="pan-back-btn" @click="back">返回</el-button>
+    <el-button icon="el-icon-arrow-left" class="pan-back-btn" @click="back">返回</el-button>
     <el-row>
       <el-col :span="12">
         <h1 class="text-jumbo text-ginormous">Oops!</h1>

+ 121 - 0
litemall-admin/vue.config.js

@@ -0,0 +1,121 @@
+'use strict'
+const path = require('path')
+
+function resolve(dir) {
+  return path.join(__dirname, dir)
+}
+
+const name = 'litemall' // page title
+
+// If your port is set to 80,
+// use administrator privileges to execute the command line.
+// For example, Mac: sudo npm run
+// You can change the port by the following method:
+// port = 9527 npm run dev OR npm run dev --port = 9527
+const port = process.env.port || process.env.npm_config_port || 9527 // dev port
+
+// All configuration item explanations can be find in https://cli.vuejs.org/config/
+module.exports = {
+  /**
+   * You will need to set publicPath if you plan to deploy your site under a sub path,
+   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
+   * then publicPath should be set to "/bar/".
+   * In most cases please use '/' !!!
+   * Detail: https://cli.vuejs.org/config/#publicpath
+   */
+  publicPath: './',
+  outputDir: 'dist',
+  assetsDir: 'static',
+  lintOnSave: process.env.NODE_ENV === 'development',
+  productionSourceMap: false,
+  devServer: {
+    port: port
+  },
+  configureWebpack: {
+    // provide the app's title in webpack's name field, so that
+    // it can be accessed in index.html to inject the correct title.
+    name: name,
+    resolve: {
+      alias: {
+        '@': resolve('src')
+      }
+    }
+  },
+  chainWebpack(config) {
+    config.plugins.delete('preload') // TODO: need test
+    config.plugins.delete('prefetch') // TODO: need test
+
+    // set svg-sprite-loader
+    config.module
+      .rule('svg')
+      .exclude.add(resolve('src/icons'))
+      .end()
+    config.module
+      .rule('icons')
+      .test(/\.svg$/)
+      .include.add(resolve('src/icons'))
+      .end()
+      .use('svg-sprite-loader')
+      .loader('svg-sprite-loader')
+      .options({
+        symbolId: 'icon-[name]'
+      })
+      .end()
+
+    // set preserveWhitespace
+    config.module
+      .rule('vue')
+      .use('vue-loader')
+      .loader('vue-loader')
+      .tap(options => {
+        options.compilerOptions.preserveWhitespace = true
+        return options
+      })
+      .end()
+
+    config
+      // https://webpack.js.org/configuration/devtool/#development
+      .when(process.env.NODE_ENV === 'development',
+        config => config.devtool('cheap-source-map')
+      )
+
+    config
+      .when(process.env.NODE_ENV !== 'development',
+        config => {
+          config
+            .plugin('ScriptExtHtmlWebpackPlugin')
+            .after('html')
+            .use('script-ext-html-webpack-plugin', [{
+            // `runtime` must same as runtimeChunk name. default is `runtime`
+              inline: /runtime\..*\.js$/
+            }])
+            .end()
+          config
+            .optimization.splitChunks({
+              chunks: 'all',
+              cacheGroups: {
+                libs: {
+                  name: 'chunk-libs',
+                  test: /[\\/]node_modules[\\/]/,
+                  priority: 10,
+                  chunks: 'initial' // only package third parties that are initially dependent
+                },
+                elementUI: {
+                  name: 'chunk-elementUI', // split elementUI 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[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+                },
+                commons: {
+                  name: 'chunk-commons',
+                  test: resolve('src/components'), // can customize your rules
+                  minChunks: 3, //  minimum common number
+                  priority: 5,
+                  reuseExistingChunk: true
+                }
+              }
+            })
+          config.optimization.runtimeChunk('single')
+        }
+      )
+  }
+}