Repository: lincenying/vue2-multiple-entry
Branch: master
Commit: 62432a5a2322
Files: 53
Total size: 32.9 KB
Directory structure:
gitextract_x_z8bi1j/
├── .browserslistrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── babel.config.js
├── entris.js
├── jsconfig.json
├── package.json
├── postcss.config.js
├── public/
│ ├── index.html
│ ├── robots.txt
│ └── static/
│ └── manifest.json
├── src/
│ ├── api/
│ │ ├── config.js
│ │ └── index.js
│ ├── assets/
│ │ └── scss/
│ │ ├── _reset.scss
│ │ └── style.scss
│ ├── components/
│ │ ├── module-1.vue
│ │ ├── module-2.vue
│ │ ├── module-3.vue
│ │ ├── module-view.vue
│ │ └── nav-component.vue
│ ├── modules/
│ │ ├── index/
│ │ │ ├── app.vue
│ │ │ └── index.js
│ │ ├── module2/
│ │ │ ├── app.vue
│ │ │ └── index.js
│ │ ├── module3/
│ │ │ ├── app.vue
│ │ │ └── index.js
│ │ ├── router/
│ │ │ ├── app.vue
│ │ │ ├── components/
│ │ │ │ ├── lists.vue
│ │ │ │ └── view.vue
│ │ │ ├── index.js
│ │ │ ├── pages/
│ │ │ │ ├── index.vue
│ │ │ │ └── view.vue
│ │ │ └── router/
│ │ │ └── index.js
│ │ ├── view/
│ │ │ ├── app.vue
│ │ │ └── index.js
│ │ └── vuex/
│ │ ├── app.vue
│ │ ├── components/
│ │ │ ├── lists.vue
│ │ │ └── view.vue
│ │ ├── index.js
│ │ ├── pages/
│ │ │ ├── index.vue
│ │ │ └── view.vue
│ │ ├── router/
│ │ │ └── index.js
│ │ └── store/
│ │ ├── index.js
│ │ └── modules/
│ │ ├── topic.js
│ │ └── topics.js
│ ├── polyfill/
│ │ └── index.js
│ └── utils/
│ └── index.js
└── vue.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .browserslistrc
================================================
> 1%
last 2 versions
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
================================================
FILE: .eslintignore
================================================
build/*.js
config/*.js
public/static/**/*.js
dist/**/*.js
dist/**/*.css
================================================
FILE: .eslintrc.json
================================================
{
"extends": ["lcy-vue"],
"rules": {
"no-irregular-whitespace": 0
}
}
================================================
FILE: .gitignore
================================================
.DS_Store
.idea/
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*-port.txt
package-lock.json
admin.lock
yarn-error.log
server/config/secret.js
server/config/mpapp.js
server/config/shihua.js
================================================
FILE: .prettierignore
================================================
package.json
================================================
FILE: .prettierrc
================================================
{
"printWidth": 150,
"semi": false,
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "none",
"arrowParens": "avoid",
"htmlWhitespaceSensitivity": "css"
}
================================================
FILE: README.md
================================================
# vue2 多页配置实例
基于`vue2 + vue-router + vuex`而组成的多页配置实例
多页实例中包含 纯单页, 基于 vue-router 的单页, 基于 vue-router + vuex 的单页, 多种模式自由组合
在 module 文件夹中只留一个模块, 就变成 纯`SPA`
所有模块均带修改head里的title, 所有模块也都包含`ajax`例子, 任何不带`ajax`的例子都是耍流氓
vuex模块带有懒加载
DEMO: http://old.mmxiaowu.com/vue2-multiple-entry/index
fork demo
```bash
$ git clone
// 安装依赖
$ yarn
// 生产模式
$ yarn build
// 开发模式
$ yarn serve
// eslint 检测
$ yarn lint
```
访问: http://localhost:8086/index
# 目录结构
- /dist/ = webpack编译后生成文件目录
- /src/api/ = axios配置目录
- /src/assets/ = 静态文件目录
- /src/components/ = 组件目录
- /src/modules/ = 多页面模块, 每个模块一个文件夹
- /src/modules/router = 多页面模块之带路由模块的例子
- /src/modules/vuex = 多页面模块之带路由和vuex的模块的例子
- /utils/ = 一些有用的插件
================================================
FILE: babel.config.js
================================================
module.exports = {
presets: ['@vue/app']
}
================================================
FILE: entris.js
================================================
const fs = require('fs')
const path = require('path')
const entryPath = path.resolve(__dirname, './src/modules')
const entris = fs.readdirSync(entryPath).reduce(function (o, dirname) {
o[dirname] = path.join(entryPath, dirname)
return o
}, {})
module.exports = entris
================================================
FILE: jsconfig.json
================================================
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"target": "ES6",
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
================================================
FILE: package.json
================================================
{
"name": "vue2-multiple-entry",
"version": "2.0.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.8.3",
"nprogress": "^0.2.0",
"store2": "^2.12.0",
"toastr": "^2.1.4",
"vue": "^2.6.12",
"vue-meta": "^2.4.0",
"vue-router": "^3.5.1",
"vueg": "^1.4.5",
"vuex": "^3.6.2",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.11",
"@vue/cli-plugin-eslint": "^4.5.11",
"@vue/cli-service": "^4.5.11",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"caniuse-lite": "^1.0.30001183",
"eslint": "^7.19.0",
"eslint-config-lcy-vue": "^3.1.1",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.5.0",
"lint-staged": "^10.5.3",
"node-sass": "^5.0.0",
"prettier": "^2.2.1",
"sass-loader": "^10.1.1",
"vue-template-compiler": "^2.6.12"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint"
]
}
}
================================================
FILE: postcss.config.js
================================================
module.exports = {
plugins: {
autoprefixer: {}
}
}
================================================
FILE: public/index.html
================================================
vue2-multiple-entry
================================================
FILE: public/robots.txt
================================================
User-agent: *
Disallow:
================================================
FILE: public/static/manifest.json
================================================
{
"name": "vue2-multiple-entry",
"short_name": "vue2-multiple-entry",
"icons": [
{
"src": "/static/img/icons/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "/static/img/icons/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "/static/img/icons/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "/static/img/icons/msapplication-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "/static/img/icons/android-chrome-168x168.png",
"sizes": "168x168",
"type": "image/png"
}, {
"src": "/static/img/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
}, {
"src": "/static/img/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"background_color": "#000000",
"display": "standalone",
"theme_color": "#2874f0"
}
================================================
FILE: src/api/config.js
================================================
module.exports = {
api: 'https://cnodejs.org/api/v1/',
timeout: 30000
}
================================================
FILE: src/api/index.js
================================================
import config from '@/api/config'
import { setMessage } from '@/utils'
import axios from 'axios'
import NProgress from 'nprogress'
import qs from 'qs'
axios.interceptors.request.use(
config => {
NProgress.start()
return config
},
error => Promise.reject(error)
)
axios.interceptors.response.use(
response => response,
error => Promise.resolve(error.response)
)
function checkStatus(response) {
NProgress.done()
if (response.status === 200 || response.status === 304) {
return response.data
}
return {
success: false,
message: response.statusText,
data: response.statusText
}
}
function checkCode(res) {
if (!res.success) {
setMessage(res.message || res.data)
}
return res
}
export default {
post(url, data) {
return axios({
method: 'post',
url: config.api + url,
data: qs.stringify(data),
timeout: config.timeout,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
.then(checkStatus)
.then(checkCode)
},
get(url, params) {
return axios({
method: 'get',
url: config.api + url,
params,
timeout: config.timeout,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(checkStatus)
.then(checkCode)
}
}
================================================
FILE: src/assets/scss/_reset.scss
================================================
html {
overflow-x: hidden;
overflow-y: scroll;
background: #ebf0f0;
overflow-anchor: none;
}
/* 清除内外边距 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote,
/* structural elements 结构元素 */
dl, dt, dd, ul, ol, li,
/* list elements 列表元素 */
pre,
/* text formatting elements 文本格式元素 */
fieldset, button, input, textarea, th, td {
margin: 0;
padding: 0;
}
/* 设置默认字体 */
body, button, input, select, textarea {
color: #333;
outline: none;
font-family: -apple-system-font, "Helvetica Neue", Tahoma, "PingFang SC", "lantinghei sc", "Microsoft Yahei", sans-serif;
font-size: 16px;
line-height: 1.6;
font-feature-settings: 'kern' 1;
-webkit-font-smoothing: antialiased;
}
h1 {
font-size: 20px;
/* 18px / 12px = 1.5 */
}
h2 {
font-size: 18px;
}
h3 {
font-size: 16px;
}
h4, h5, h6 {
font-size: 100%;
}
address, cite, dfn, em, var {
font-style: normal;
}
/* 统一等宽字体 */
small {
font-size: 12px;
}
/* 小于 12px 的中文很难阅读,让 small 正常化 */
/* 重置列表元素 */
ul, ol {
list-style: none;
}
/* 重置文本格式元素 */
a {
text-decoration: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
a:hover {
text-decoration: none;
}
abbr[title], acronym[title] {
/* 注:1.ie6 不支持 abbr; 2.这里用了属性选择符,ie6 下无效果 */
border-bottom: 1px dotted;
cursor: help;
}
q:before, q:after {
content: '';
}
/* 重置表单元素 */
legend {
color: #000;
}
/* for ie6 */
fieldset, img {
border: none;
}
/* 注:optgroup 无法扶正 */
button, input, select, textarea {
font-size: 100%;
/* 使得表单元素在 ie 下能继承字体大小 */
}
/* 重置表格元素 */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* 重置 hr */
hr {
border: none;
height: 1px;
}
article, aside, canvas, figure, figure img, figcaption, hgroup, footer, header, nav, section, audio, video {
position: relative;
display: block;
}
nav ul, nav ol {
list-style: none;
}
.hidden {
display: none;
}
.clearfix {
*zoom: 1;
}
.clearfix:before, .clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
================================================
FILE: src/assets/scss/style.scss
================================================
@import '_reset.scss';
#vueg-background {
padding-top: 80px;
box-sizing: border-box;
background: none !important;
}
.g-doc {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.nav-wrap {
flex: 0 0 60px;
margin-bottom: 20px;
background: #54d9e0;
.nav-block {
display: flex;
align-items: center;
width: 1200px;
height: 60px;
margin: 0 auto;
li {
flex: 0 0 auto;
list-style: none;
width: 120px;
text-align: center;
a {
font-size: 16px;
color: #fff;
}
&.current {
a {
color: red;
}
}
&.logo {
width: 109px;
margin-right: 30px;
img {
width: 109px;
height: 31px;
}
}
}
}
}
.body {
flex: 1 1 auto;
width: 1200px;
margin: 0 auto 20px;
padding: 20px;
background: #fff;
border-radius: 5px;
box-shadow: 0 0 10px #eee;
.header {
position: relative;
padding-bottom: 15px;
text-align: center;
font-size: 16px;
font-weight: 800;
border-bottom: 1px solid #eee;
a {
display: inline-block;
position: absolute;
right: 0;
top: 0;
font-weight: 400;
font-size: 14px;
line-height: 22px;
}
}
.topics {
margin-top: 20px;
li + li {
margin-top: 10px;
}
}
.content {
margin-top: 20px;
.markdown-text {
word-break: break-all;
}
img {
max-width: 100%;
}
}
.pages {
margin-top: 20px;
padding-top: 20px;
text-align: center;
border-top: 1px solid #eee;
a {
display: inline-block;
& + a {
margin-left: 20px;
}
}
}
}
================================================
FILE: src/components/module-1.vue
================================================
================================================
FILE: src/components/module-2.vue
================================================
================================================
FILE: src/components/module-3.vue
================================================
================================================
FILE: src/components/module-view.vue
================================================
================================================
FILE: src/components/nav-component.vue
================================================
================================================
FILE: src/modules/index/app.vue
================================================
================================================
FILE: src/modules/index/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
import App from './app.vue'
Vue.use(Meta)
const app = new Vue({
...App
})
app.$mount('#app')
================================================
FILE: src/modules/module2/app.vue
================================================
================================================
FILE: src/modules/module2/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
import App from './app.vue'
Vue.use(Meta)
const app = new Vue({
...App
})
app.$mount('#app')
================================================
FILE: src/modules/module3/app.vue
================================================
================================================
FILE: src/modules/module3/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
import App from './app.vue'
Vue.use(Meta)
const app = new Vue({
...App
})
app.$mount('#app')
================================================
FILE: src/modules/router/app.vue
================================================
================================================
FILE: src/modules/router/components/lists.vue
================================================
================================================
FILE: src/modules/router/components/view.vue
================================================
================================================
FILE: src/modules/router/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
// import vueg from 'vueg'
import router from './router'
import App from './app.vue'
Vue.use(Meta)
// Vue.use(vueg, router, {
// shadow: false,
// forwardAnim: 'fadeInRight'
// })
const app = new Vue({
router,
...App
})
app.$mount('#app')
================================================
FILE: src/modules/router/pages/index.vue
================================================
================================================
FILE: src/modules/router/pages/view.vue
================================================
================================================
FILE: src/modules/router/router/index.js
================================================
/* eslint-disable no-inline-comments */
import Vue from 'vue'
import VueRouter from 'vue-router'
// 正常打包
// import index from '../pages/index.vue'
// import view from '../pages/view.vue'
// 懒加载
// const index = resolve => require(['../pages/index.vue'], resolve)
// const view = resolve => require(['../pages/view.vue'], resolve)
// 懒加载 - 按组
// const index = r => require.ensure([], () => r(require('../pages/index.vue')), 'group-index')
// const view = r => require.ensure([], () => r(require('../pages/view.vue')), 'group-view')
// 懒加载 - 按组 import
const index = () => import(/* webpackChunkName: "router-index" */ '../pages/index.vue')
const view = () => import(/* webpackChunkName: "router-view" */ '../pages/view.vue')
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'hash',
//base: __dirname,
routes: [
{ name: 'index', path: '/', component: index },
{ name: 'view', path: '/view/:id', component: view }
]
})
export default router
================================================
FILE: src/modules/view/app.vue
================================================
================================================
FILE: src/modules/view/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
import App from './app.vue'
Vue.use(Meta)
const app = new Vue({
...App
})
app.$mount('#app')
================================================
FILE: src/modules/vuex/app.vue
================================================
================================================
FILE: src/modules/vuex/components/lists.vue
================================================
================================================
FILE: src/modules/vuex/components/view.vue
================================================
================================================
FILE: src/modules/vuex/index.js
================================================
import '@/polyfill'
import Vue from 'vue'
import Meta from 'vue-meta'
// import vueg from 'vueg'
import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'
import App from './app.vue'
Vue.use(Meta)
// Vue.use(vueg, router, {
// // duration: '10',
// shadow: false,
// forwardAnim: 'fadeInRight'
// })
sync(store, router)
router.beforeEach((route, redirect, next) => {
window.scrollTo(0, 0)
next()
})
const app = new Vue({
router,
store,
...App
})
app.$mount('#app')
================================================
FILE: src/modules/vuex/pages/index.vue
================================================
================================================
FILE: src/modules/vuex/pages/view.vue
================================================
================================================
FILE: src/modules/vuex/router/index.js
================================================
/* eslint-disable no-inline-comments */
import Vue from 'vue'
import VueRouter from 'vue-router'
// 正常打包
// import index from '../pages/index.vue'
// import view from '../pages/view.vue'
// 懒加载
// const index = resolve => require(['../pages/index.vue'], resolve)
// const view = resolve => require(['../pages/view.vue'], resolve)
// 懒加载 - 按组
// const index = r => require.ensure([], () => r(require('../pages/index.vue')), 'group-index')
// const view = r => require.ensure([], () => r(require('../pages/view.vue')), 'group-view')
// 懒加载 - 按组 import
const index = () => import(/* webpackChunkName: "vuex-index" */ '../pages/index.vue')
const view = () => import(/* webpackChunkName: "vuex-view" */ '../pages/view.vue')
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'hash',
//base: __dirname,
routes: [
{ name: 'index', path: '/', component: index },
{ name: 'view', path: '/view/:id', component: view }
]
})
export default router
================================================
FILE: src/modules/vuex/store/index.js
================================================
import Vue from 'vue'
import Vuex from 'vuex'
import topics from './modules/topics'
import topic from './modules/topic'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
topics,
topic
}
})
================================================
FILE: src/modules/vuex/store/modules/topic.js
================================================
import api from '@/api'
const state = {
item: {
data: {},
path: ''
}
}
const actions = {
async ['getTopic'](
{
commit,
state,
rootState: {
route: { fullPath }
}
},
config
) {
const path = fullPath
if (state.item.data.id && path === state.item.path) {
return
}
const { data, success } = await api.get(`topic/${config.id}`)
if (data && success) {
commit('receiveTopic', {
data,
path
})
}
}
}
const mutations = {
['receiveTopic'](state, { data, path }) {
state.item = {
data,
path
}
}
}
const getters = {
['getTopic'](state) {
return state.item
}
}
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
================================================
FILE: src/modules/vuex/store/modules/topics.js
================================================
import api from '@/api'
const state = {
lists: {
data: [],
page: 1,
path: ''
}
}
const actions = {
async ['getTopics'](
{
commit,
state,
rootState: {
route: { fullPath }
}
},
config
) {
const path = fullPath
if (state.lists.data.length > 0 && path === state.lists.path && config.page === 1) {
return
}
const { data, success } = await api.get('topics', config)
if (data && success) {
commit('receiveTopics', {
...config,
data,
path
})
}
}
}
const mutations = {
['receiveTopics'](state, { data, page, path }) {
let list
if (page === 1) {
list = [].concat(data)
} else {
list = state.lists.data.concat(data)
}
state.lists = {
data: list,
page,
path
}
}
}
const getters = {
['getTopics'](state) {
return state.lists
}
}
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
================================================
FILE: src/polyfill/index.js
================================================
import 'core-js/features/promise'
import 'core-js/features/array/find'
import 'core-js/features/array/find-index'
import 'core-js/features/array/includes'
================================================
FILE: src/utils/index.js
================================================
import toastr from 'toastr'
toastr.options.positionClass = 'toast-top-center'
function pluralize(time, label) {
return time + label
}
export const setMessage = config => {
let content, type
if (typeof config === 'string') {
content = config
type = 'error'
} else {
content = config.content
type = config.type
}
toastr[type](content)
}
export const strlen = str => {
let charCode = -1
const len = str.length
let realLength = 0
for (let i = 0; i < len; i++) {
charCode = str.charCodeAt(i)
if (charCode >= 0 && charCode <= 128) realLength += 1
else realLength += 2
}
return realLength
}
export function timeAgo(time) {
const preg = /^[\d]+$/
const timestamp = preg.test(time)
if (!timestamp) {
const tmp = Date.parse(time)
time = tmp / 1000
}
const between = Date.now() / 1000 - Number(time)
if (between < 60) {
return '刚刚'
} else if (between < 3600) {
return pluralize(parseInt(between / 60, 10), ' 分钟前')
} else if (between < 86400) {
return pluralize(parseInt(between / 3600, 10), ' 小时前')
}
return pluralize(parseInt(between / 86400, 10), ' 天前')
}
export const timeYmd = timestamp => {
var time = new Date(timestamp * 1000)
var year = time.getFullYear()
var month = time.getMonth() + 1
var date = time.getDate()
return year + '-' + (month < 10 ? '0' + month : month) + '-' + (date < 10 ? '0' + date : date)
}
================================================
FILE: vue.config.js
================================================
/* eslint-disable no-inline-comments */
const entris = require('./entris')
const pages = {}
Object.keys(entris).forEach(item => {
pages[item] = {
// page 的入口
entry: 'src/modules/' + item + '/index.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: item + '.html'
}
})
module.exports = {
publicPath: '/',
// publicPath: '/vue2-multiple-entry/',
pages,
configureWebpack: {
devtool: 'source-map',
performance: {
hints: 'warning',
maxAssetSize: 30000000, // 单位为字节
maxEntrypointSize: 50000000, // 单位为字节
assetFilter(assetFilename) {
// 提供资源文件名的断言函数
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js')
}
}
},
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
config.module.rule('eslint').uses.clear()
config.module.rule('eslint').clear()
},
css: {
loaderOptions: {}
},
pluginOptions: {},
devServer: {
port: 8086,
host: '0.0.0.0',
hot: true,
disableHostCheck: true,
proxy: {
'/api': {
target: 'http://localhost:4000',
changeOrigin: true,
pathRewrite: {
'^/api': '/api'
}
}
},
historyApiFallback: {
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: '/index.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/module2/, to: '/module2.html' },
{ from: /^\/module3/, to: '/module3.html' },
{ from: /^\/router/, to: '/router.html' },
{ from: /^\/vuex/, to: '/vuex.html' },
{ from: /^\/view/, to: '/view.html' }
]
}
}
}