feat: perfect migrate to @vue/cli-service, upgrade vue babel version (#1267)

* feat: perfect migrate to @vue/cli-service, upgrade vue babel version

1. update to @vue/cli-service@3.0.5, @babel/core@7.0.0
2. use vue-cli service replace config file in build/ and config/
3. upgrade vue and babel configuration
4. solve the svg-sprite config problem #980

refs: #932 #1087  #980 #1056

* fix: fix breadcrumb dependency

* fix: fix index template and static assets load with vue-cli 3

* fix: fix import driver.js in guide page

* refactor(mock): mak mock api compatible with both web-view and webpack server

1. 把 Mockjs 功能移到 server 端中间件,同时也兼容前端直接劫持 XHR
2. dev 环境下默认作为 express 中间件通过 webpack server 提供 mock api
3. prod 构建时,默认在前端用 Mockjs 劫持 XHR

benefits:
  - dev 开发调试时能直接看到 XHR 请求,方便调试网络,能和后端对接联调
  - 避开在开发时因为 Mockjs 引起的网络 bug
  - prod 构建时劫持 XHR,保证本项目的 Github Pages preview 能正常显示 (逻辑和 error-log 一样)
  - 前后台使用的 mock 是同一份代码,不会增加维护负担

ref: [#562](https://github.com/PanJiaChen/vue-element-admin/issues/562#issuecomment-378116233)

* update requires the lowest version of node

* add favicon

* fix(TreeTable): fix `Array.prototype.concat` on custom-tree-table page
This commit is contained in:
zthxxx
2018-10-29 13:55:36 +08:00
committed by 花裤衩
parent 6c967f177a
commit 40a7626acb
71 changed files with 211 additions and 893 deletions

74
mock/article.js Normal file
View File

@@ -0,0 +1,74 @@
import Mock from 'mockjs'
const List = []
const count = 100
const baseContent = '<p>我是测试数据我是测试数据</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'
for (let i = 0; i < count; i++) {
List.push(Mock.mock({
id: '@increment',
timestamp: +Mock.Random.date('T'),
author: '@first',
reviewer: '@first',
title: '@title(5, 10)',
content_short: '我是测试数据',
content: baseContent,
forecast: '@float(0, 100, 2, 2)',
importance: '@integer(1, 3)',
'type|1': ['CN', 'US', 'JP', 'EU'],
'status|1': ['published', 'draft', 'deleted'],
display_time: '@datetime',
comment_disabled: true,
pageviews: '@integer(300, 5000)',
image_uri,
platforms: ['a-platform']
}))
}
export default {
'/article/list': config => {
const { importance, type, title, page = 1, limit = 20, sort } = config.query
let mockList = List.filter(item => {
if (importance && item.importance !== +importance) return false
if (type && item.type !== type) return false
if (title && item.title.indexOf(title) < 0) return false
return true
})
if (sort === '-id') {
mockList = mockList.reverse()
}
const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
return {
total: mockList.length,
items: pageList
}
},
'/article/detail': config => {
const { id } = config.query
for (const article of List) {
if (article.id === +id) {
return article
}
}
},
'/article/pv': {
pvData: [
{ key: 'PC', pv: 1024 },
{ key: 'mobile', pv: 1024 },
{ key: 'ios', pv: 1024 },
{ key: 'android', pv: 1024 }
]
},
'/article/create': {
data: 'success'
},
'/article/update': {
data: 'success'
}
}

50
mock/index.js Normal file
View File

@@ -0,0 +1,50 @@
import Mock from 'mockjs'
import mocks from './mocks'
import { param2Obj } from '../src/utils'
const MOCK_API_BASE = '/mock'
export function mockXHR() {
// 修复在使用 MockJS 情况下,设置 withCredentials = true且未被拦截的跨域请求丢失 Cookies 的问题
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const [route, respond] of Object.entries(mocks)) {
Mock.mock(new RegExp(`${route}`), XHR2ExpressReqWrap(respond))
}
}
const responseFake = (route, respond) => (
{
route: new RegExp(`${MOCK_API_BASE}${route}`),
response(req, res) {
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
)
export default Object.keys(mocks).map(route => responseFake(route, mocks[route]))

33
mock/login.js Normal file
View File

@@ -0,0 +1,33 @@
const userMap = {
admin: {
roles: ['admin'],
token: 'admin',
introduction: '我是超级管理员',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
editor: {
roles: ['editor'],
token: 'editor',
introduction: '我是编辑',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
export default {
'/login/login': config => {
const { username } = config.body
return userMap[username]
},
'/login/logout': 'success',
'/user/info': config => {
const { token } = config.query
if (userMap[token]) {
return userMap[token]
} else {
return false
}
}
}

12
mock/mocks.js Normal file
View File

@@ -0,0 +1,12 @@
import login from './login'
import article from './article'
import search from './remoteSearch'
import transaction from './transaction'
export default {
...login,
...article,
...search,
...transaction
}

22
mock/remoteSearch.js Normal file
View File

@@ -0,0 +1,22 @@
import Mock from 'mockjs'
const NameList = []
const count = 100
for (let i = 0; i < count; i++) {
NameList.push(Mock.mock({
name: '@first'
}))
}
NameList.push({ name: 'mockPan' })
export default {
'/search/user': config => {
const { name } = config.query
const mockNameList = NameList.filter(item => {
const lowerCaseName = item.name.toLowerCase()
return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0)
})
return { items: mockNameList }
}
}

16
mock/transaction.js Normal file
View File

@@ -0,0 +1,16 @@
import Mock from 'mockjs'
const count = 20
export default {
'/transaction/list': {
total: count,
[`items|${count}`]: [{
order_no: '@guid()',
timestamp: +Mock.Random.date('T'),
username: '@name()',
price: '@float(1000, 15000, 0, 2)',
'status|1': ['success', 'pending']
}]
}
}