├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── LICENSE ├── README-zh_CN.md ├── README.md ├── example └── src │ ├── components │ └── HelloWorld.vue │ └── views │ ├── index │ ├── App.vue │ ├── app.js │ └── file.json │ └── multi-page │ ├── file.json │ ├── home │ ├── App.vue │ ├── app.js │ └── file.json │ └── subpage │ ├── App.vue │ ├── app.js │ └── file.json ├── generator.js ├── index.js ├── logger ├── dirTree.js └── index.js ├── logo.png ├── package.json ├── prompts.js ├── template └── src │ └── views │ └── preview │ ├── App.vue │ ├── app.js │ ├── file.json │ ├── mdc.drawer.css │ └── tree-item.vue ├── vue.config.js └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 4 | 'standard', 5 | // https://github.com/vuejs/eslint-plugin-vue#priority-c-recommended-minimizing-arbitrary-choices-and-cognitive-overhead 6 | 'plugin:vue/recommended', 7 | ], 8 | rules: { 9 | 'vue/require-default-prop': 'off' 10 | } 11 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | 5 | jobs: 6 | include: 7 | - stage: npm release 8 | node_js: "8" 9 | script: echo "Deploying to npm ..." 10 | deploy: 11 | provider: npm 12 | email: "aircity@drrr.us" 13 | api_key: $NPM_API_KEY 14 | gem: vue-cli-plugin-pages 15 | on: deploy-npm-release 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2016-present aircity@drrr.us 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README-zh_CN.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | 简体中文 2 | 3 | # vue-cli-plugin-pages 4 | 5 | 基于vue-cli 3.x的多页面应用插件 6 | 7 | ## 🔗 内容列表 8 | 9 | * [特性](#-特性) 10 | * [应用](#-应用) 11 | 12 | ## ✨ 特性 13 | 14 | * 生成多页面配置 [pages](https://cli.vuejs.org/config/#pages) (将匹配`src/views/**/app.js`的文件作为入口中的一个,生成pages的entry和filename) 15 | ``` 16 | { 17 | "index": { 18 | "entry": "src/views/index/app.js", 19 | "filename": "index.html", 20 | "template": "public/index.html" 21 | }, 22 | "preview": { 23 | "entry": "src/views/preview/app.js", 24 | "filename": "preview.html", 25 | "template": "public/index.html" 26 | }, 27 | "multi-page~home": { 28 | "entry": "src/views/multi-page/home/app.js", 29 | "filename": "multi-page/home.html", 30 | "template": "public/index.html" 31 | }, 32 | "multi-page~subpage": { 33 | "entry": "src/views/multi-page/subpage/app.js", 34 | "filename": "multi-page/subpage.html", 35 | "template": "public/index.html" 36 | } 37 | } 38 | ``` 39 | 40 | * 将页面位置生成到`logs/location.json` 41 | ``` 42 | { 43 | "route": [ 44 | { "name": "Index Page", "chunk": "index", "location": "index.html" }, 45 | { "name": "Index Page", "chunk": "preview", "location": "preview.html" }, 46 | { 47 | "name": "Home Page", 48 | "chunk": "multi-page~home", 49 | "location": "multi-page/home.html" 50 | }, 51 | { 52 | "name": "Subpage", 53 | "chunk": "multi-page~subpage", 54 | "location": "multi-page/subpage.html" 55 | } 56 | ] 57 | } 58 | ``` 59 | 60 | * 将页面目录文件树生成到`logs/tree.json` 61 | 62 | ``` 63 | { 64 | "path": "#", 65 | "name": "views", 66 | "children": [ 67 | { 68 | "path": "index.html", 69 | "name": "Index Page", 70 | "children": [], 71 | "size": 135, 72 | "type": "file", 73 | "extension": ".js", 74 | "merged": true 75 | }, 76 | { 77 | "path": "#", 78 | "name": "Multi Page", 79 | "children": [ 80 | { 81 | "path": "multi-page/home.html", 82 | "name": "Home Page", 83 | "children": [], 84 | "size": 135, 85 | "type": "file", 86 | "extension": ".js", 87 | "merged": true 88 | }, 89 | { 90 | "path": "multi-page/subpage.html", 91 | "name": "Subpage", 92 | "children": [], 93 | "size": 135, 94 | "type": "file", 95 | "extension": ".js", 96 | "merged": true 97 | } 98 | ], 99 | "size": 270, 100 | "type": "directory" 101 | }, 102 | { 103 | "path": "preview.html", 104 | "name": "Index Page", 105 | "children": [], 106 | "size": 135, 107 | "type": "file", 108 | "extension": ".js", 109 | "merged": true 110 | } 111 | ], 112 | "size": 540, 113 | "type": "directory" 114 | } 115 | 116 | ``` 117 | 118 | ## 🔨 应用 119 | 120 | :warning: Make sure you have vue-cli 3.x.x: 121 | 122 | ``` 123 | vue --version 124 | ``` 125 | 126 | If you don't have a project created with vue-cli 3.x yet: 127 | 128 | ``` 129 | vue create my-new-app 130 | ``` 131 | 132 | Navigate to the newly created project folder and add the cli plugin: 133 | 134 | ``` 135 | cd my-new-app 136 | vue add pages 137 | ``` 138 | 139 | Start your app: 140 | 141 | ``` 142 | npm run serve 143 | ``` 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./README-zh_CN.md) 2 | 3 | # vue-cli-plugin-pages 4 | 5 | This is a vue-cli 3.x plugin to build multi-page application. 6 | 7 | ## 🔗 Table of contents 8 | 9 | * [Features](#-features) 10 | * [Usage](#-usage) 11 | 12 | 13 | ## ✨ Features 14 | 15 | * Generate multi-page [pages](https://cli.vuejs.org/config/#pages) config.(Get the entries and filenames through `src/views/**/app.js`) 16 | ``` 17 | { 18 | "index": { 19 | "entry": "src/views/index/app.js", 20 | "filename": "index.html", 21 | "template": "public/index.html" 22 | }, 23 | "preview": { 24 | "entry": "src/views/preview/app.js", 25 | "filename": "preview.html", 26 | "template": "public/index.html" 27 | }, 28 | "multi-page~home": { 29 | "entry": "src/views/multi-page/home/app.js", 30 | "filename": "multi-page/home.html", 31 | "template": "public/index.html" 32 | }, 33 | "multi-page~subpage": { 34 | "entry": "src/views/multi-page/subpage/app.js", 35 | "filename": "multi-page/subpage.html", 36 | "template": "public/index.html" 37 | } 38 | } 39 | ``` 40 | 41 | * Generate multi-page location to `logs/location.json`. 42 | ``` 43 | { 44 | "route": [ 45 | { "name": "Index Page", "chunk": "index", "location": "index.html" }, 46 | { "name": "Index Page", "chunk": "preview", "location": "preview.html" }, 47 | { 48 | "name": "Home Page", 49 | "chunk": "multi-page~home", 50 | "location": "multi-page/home.html" 51 | }, 52 | { 53 | "name": "Subpage", 54 | "chunk": "multi-page~subpage", 55 | "location": "multi-page/subpage.html" 56 | } 57 | ] 58 | } 59 | ``` 60 | 61 | * Generate multi-page directory tree to `logs/tree.json`. 62 | 63 | ``` 64 | { 65 | "path": "#", 66 | "name": "views", 67 | "children": [ 68 | { 69 | "path": "index.html", 70 | "name": "Index Page", 71 | "children": [], 72 | "size": 135, 73 | "type": "file", 74 | "extension": ".js", 75 | "merged": true 76 | }, 77 | { 78 | "path": "#", 79 | "name": "Multi Page", 80 | "children": [ 81 | { 82 | "path": "multi-page/home.html", 83 | "name": "Home Page", 84 | "children": [], 85 | "size": 135, 86 | "type": "file", 87 | "extension": ".js", 88 | "merged": true 89 | }, 90 | { 91 | "path": "multi-page/subpage.html", 92 | "name": "Subpage", 93 | "children": [], 94 | "size": 135, 95 | "type": "file", 96 | "extension": ".js", 97 | "merged": true 98 | } 99 | ], 100 | "size": 270, 101 | "type": "directory" 102 | }, 103 | { 104 | "path": "preview.html", 105 | "name": "Index Page", 106 | "children": [], 107 | "size": 135, 108 | "type": "file", 109 | "extension": ".js", 110 | "merged": true 111 | } 112 | ], 113 | "size": 540, 114 | "type": "directory" 115 | } 116 | 117 | ``` 118 | 119 | ## 🔨 Usage 120 | 121 | :warning: Make sure you have vue-cli 3.x.x: 122 | 123 | ``` 124 | vue --version 125 | ``` 126 | 127 | If you don't have a project created with vue-cli 3.x yet: 128 | 129 | ``` 130 | vue create my-new-app 131 | ``` 132 | 133 | Navigate to the newly created project folder and add the cli plugin: 134 | 135 | ``` 136 | cd my-new-app 137 | vue add pages 138 | ``` 139 | 140 | Start your app: 141 | 142 | ``` 143 | npm run serve 144 | ``` 145 | -------------------------------------------------------------------------------- /example/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 31 | 32 | 33 | 49 | -------------------------------------------------------------------------------- /example/src/views/index/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /example/src/views/index/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /example/src/views/index/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Index Page" 3 | } 4 | -------------------------------------------------------------------------------- /example/src/views/multi-page/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Multi Page" 3 | } 4 | -------------------------------------------------------------------------------- /example/src/views/multi-page/home/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /example/src/views/multi-page/home/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /example/src/views/multi-page/home/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Home Page" 3 | } 4 | -------------------------------------------------------------------------------- /example/src/views/multi-page/subpage/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /example/src/views/multi-page/subpage/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /example/src/views/multi-page/subpage/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Subpage" 3 | } 4 | -------------------------------------------------------------------------------- /generator.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | module.exports = (api, opts) => { 5 | api.render('./template') 6 | if (opts.generate === 'whole') { 7 | api.render('./example') 8 | } 9 | const configPath = 10 | process.env.VUE_CLI_SERVICE_CONFIG_PATH || api.resolve('vue.config.js') 11 | 12 | if (!fs.existsSync(configPath)) { 13 | try { 14 | let template = fs.readFileSync(path.join(__dirname, './vue.config.js')) 15 | fs.writeFile(configPath, template, function (err) { 16 | if (err) { 17 | return console.log(err) 18 | } 19 | }) 20 | } catch (e) { 21 | throw e 22 | } 23 | } else { 24 | // api.injectImports(configPath, `const logger = require('vue-cli-plugin-pages/logger')`) 25 | console.log(`You can easy to get pages opition:`) 26 | console.log(`const logger = require('vue-cli-plugin-pages/logger')`) 27 | console.log(`const pages = logger.start()`) 28 | } 29 | 30 | api.onCreateComplete(() => { 31 | // Linting the generated files 32 | if (api.hasPlugin('eslint')) { 33 | // Lint generated/modified files 34 | try { 35 | const lint = require('@vue/cli-plugin-eslint/lint') 36 | lint({ 37 | silent: true 38 | }, api) 39 | } catch (e) { 40 | // No ESLint vue-cli plugin 41 | } 42 | } 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const logger = require('./logger') 2 | const pages = logger.start() 3 | 4 | module.exports = api => { 5 | if (!api.service.projectOptions.pages) { 6 | api.service.projectOptions.pages = pages 7 | } 8 | api.chainWebpack(webpackConfig => { 9 | webpackConfig.resolve.modules.add(api.resolve('src')) 10 | webpackConfig.resolve.alias.set('@logs', api.resolve('logs')) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /logger/dirTree.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const FS = require('fs') 4 | const PATH = require('path') 5 | const constants = { 6 | DIRECTORY: 'directory', 7 | FILE: 'file' 8 | } 9 | 10 | function safeReadDirSync (path) { 11 | let dirData = {} 12 | try { 13 | dirData = FS.readdirSync(path) 14 | } catch (ex) { 15 | if (ex.code === 'EACCES') { 16 | return null 17 | } else throw ex 18 | } 19 | return dirData 20 | } 21 | 22 | /** 23 | * Normalizes windows style paths by replacing double backslahes with single forward slahes (unix style). 24 | * @param {string} path 25 | * @return {string} 26 | */ 27 | function normalizePath (path) { 28 | return path.replace(/\\/g, '/') 29 | } 30 | 31 | /** 32 | * Tests if the supplied parameter is of type RegExp 33 | * @param {any} regExp 34 | * @return {Boolean} 35 | */ 36 | function isRegExp (regExp) { 37 | return typeof regExp === 'object' && regExp.constructor === RegExp 38 | } 39 | 40 | function directoryTree (path, options, onEachFile) { 41 | const name = PATH.basename(path) 42 | path = options && options.normalizePath ? normalizePath(path) : path 43 | const item = { 44 | path, 45 | name 46 | } 47 | let stats 48 | 49 | try { 50 | stats = FS.statSync(path) 51 | } catch (e) { 52 | return null 53 | } 54 | 55 | // Skip if it matches the exclude regex 56 | if (options && options.exclude) { 57 | const excludes = isRegExp(options.exclude) ? [options.exclude] 58 | : options.exclude 59 | if (excludes.some(exclusion => exclusion.test(path))) { 60 | return null 61 | } 62 | } 63 | 64 | if (stats.isFile()) { 65 | const ext = PATH.extname(path).toLowerCase() 66 | // Skip if it does not match the extension regex 67 | if (options && options.extensions && !options.extensions.test(ext)) { 68 | return null 69 | } 70 | // Skip if it does not match the basename regex 71 | const basename = PATH.basename(path) 72 | if (options && options.basename && !options.basename.test(basename)) { 73 | return null 74 | } 75 | item.size = stats.size // File size in bytes 76 | item.extension = ext 77 | item.type = constants.FILE 78 | // Handling pages root 79 | if (onEachFile && !item.merged) { 80 | onEachFile(item, PATH) 81 | } 82 | } else if (stats.isDirectory()) { 83 | const dirData = safeReadDirSync(path) 84 | if (dirData === null) return null 85 | 86 | item.children = dirData 87 | .map(child => directoryTree(PATH.join(path, child), options, onEachFile)) 88 | .filter(e => !!e) 89 | item.size = item.children.reduce((prev, cur) => prev + cur.size, 0) 90 | item.type = constants.DIRECTORY 91 | // Handling pages 92 | if (item.children.length === 0) return null 93 | if ( 94 | item.children.length === 1 && 95 | item.children[0].type === 'file' && 96 | !item.children[0].merged 97 | ) { 98 | Object.assign(item, item.children[0]) 99 | delete item.children 100 | item.merged = true 101 | } 102 | if (onEachFile && !item.merged) { 103 | onEachFile(item, PATH) 104 | } 105 | } else { 106 | return null // Or set item.size = 0 for devices, FIFO and sockets ? 107 | } 108 | return item 109 | } 110 | 111 | module.exports = directoryTree 112 | -------------------------------------------------------------------------------- /logger/index.js: -------------------------------------------------------------------------------- 1 | const globby = require('globby') 2 | const prettier = require('prettier') 3 | const makeDir = require('make-dir') 4 | const PATH = require('path') 5 | const del = require('del') 6 | const FS = require('fs') 7 | const dirTree = require('./dirTree.js') 8 | 9 | const mergeFileConfig = (item, dirpath) => { 10 | const configFile = PATH.join(dirpath, 'file.json') 11 | if (FS.existsSync(configFile)) { 12 | try { 13 | const infoJson = JSON.parse(FS.readFileSync(configFile).toString()) 14 | if (infoJson) { 15 | Object.assign(item, infoJson) 16 | } 17 | } catch (err) { 18 | console.log(err) 19 | } 20 | } 21 | } 22 | 23 | const getTemplatePath = (dirpath) => { 24 | const customTemplatePath = PATH.join(dirpath, 'index.ejs') 25 | const templatePath = PATH.join(dirpath, 'index.html') 26 | if (FS.existsSync(customTemplatePath)) { 27 | return customTemplatePath 28 | } else if (FS.existsSync(templatePath)) { 29 | return templatePath 30 | } else { 31 | return 'public/index.html' 32 | } 33 | } 34 | 35 | const relative = (from, to) => { 36 | return PATH.relative(from, to).replace(/\\/g, '/') 37 | } 38 | 39 | module.exports = { 40 | start () { 41 | const viewRoot = 'src/views' 42 | const paths = globby.sync([`${viewRoot}/**/app.js`]) 43 | const chunks = paths.map(path => { 44 | return PATH.dirname(PATH.relative(viewRoot, path)) 45 | .split(PATH.sep) 46 | .join('~') 47 | }) 48 | makeDir.sync('logs') 49 | del.sync('logs/*.json') 50 | // generate html-webpack-plugin options 51 | const htmlFile = 'logs/pages.json' 52 | let htmlConfig = {} 53 | paths.forEach((path, index) => { 54 | const chunk = chunks[index] 55 | const dirpath = PATH.dirname(path) 56 | const htmlTpl = getTemplatePath(dirpath) 57 | htmlConfig[chunk] = { 58 | entry: path, 59 | filename: relative(viewRoot, dirpath) + '.html', 60 | // template: 'public/index.html' 61 | template: htmlTpl, 62 | inject: htmlTpl.endsWith('.html') 63 | } 64 | }) 65 | 66 | htmlConfig = JSON.stringify(htmlConfig) !== '{}' ? htmlConfig : null 67 | if (htmlConfig) { 68 | const htmlConfigStr = prettier.format(JSON.stringify(htmlConfig), { 69 | parser: 'json' 70 | }) 71 | FS.writeFile(htmlFile, htmlConfigStr, function (err) { 72 | if (err) { 73 | return console.log(err) 74 | } 75 | }) 76 | } 77 | this.log(viewRoot, paths, chunks) 78 | return htmlConfig 79 | }, 80 | 81 | log (viewRoot, paths, chunks) { 82 | // generate view route 83 | const routeFile = 'logs/location.json' 84 | const routesPath = paths.map((path, index) => { 85 | const dirpath = PATH.dirname(path) 86 | const item = { 87 | name: chunks[index], 88 | chunk: chunks[index], 89 | location: relative(viewRoot, dirpath) + '.html' 90 | } 91 | mergeFileConfig(item, dirpath) 92 | return item 93 | }) 94 | if (routeFile) { 95 | const routesPathStr = prettier.format(JSON.stringify({ 96 | route: routesPath 97 | }), { 98 | parser: 'json' 99 | }) 100 | FS.writeFile(routeFile, routesPathStr, function (err) { 101 | if (err) { 102 | return console.log(err) 103 | } 104 | }) 105 | } 106 | // generate view Tree 107 | const logsTree = dirTree( 108 | viewRoot, { 109 | basename: /^app.js$/, 110 | normalizePath: true 111 | }, 112 | (item, PATH) => { 113 | const path = item.path 114 | const dirpath = PATH.dirname(path) 115 | if (item.type === 'file') { 116 | item.path = relative(viewRoot, dirpath) + '.html' 117 | mergeFileConfig(item, dirpath) 118 | } else if (item.type === 'directory') { 119 | mergeFileConfig(item, path) 120 | item.path = '#' 121 | } 122 | } 123 | ) 124 | const treeFile = 'logs/tree.json' 125 | if (logsTree) { 126 | const logsTreeStr = prettier.format(JSON.stringify(logsTree), { 127 | parser: 'json' 128 | }) 129 | FS.writeFile(treeFile, logsTreeStr, function (err) { 130 | if (err) { 131 | return console.log(err) 132 | } 133 | }) 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aircity/vue-cli-plugin-pages/0ec85cbef657d3efd6139c786058957179bce980/logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli-plugin-pages", 3 | "version": "1.1.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "author": "aircity ", 7 | "scripts": { 8 | "test": "node index.js" 9 | }, 10 | "dependencies": { 11 | "globby": "^10.0.1", 12 | "make-dir": "^3.0.0", 13 | "prettier": "^1.18.2" 14 | }, 15 | "devDependencies": { 16 | "eslint": "^6.4.0", 17 | "eslint-config-standard": "^14.1.0", 18 | "eslint-plugin-import": "^2.18.2", 19 | "eslint-plugin-node": "^10.0.0", 20 | "eslint-plugin-promise": "^4.2.1", 21 | "eslint-plugin-standard": "^4.0.1", 22 | "eslint-plugin-vue": "^5.2.3" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/Aircity/vue-cli-plugin-pages.git" 27 | }, 28 | "homepage": "https://github.com/Aircity/vue-cli-plugin-pages#readme", 29 | "description": "vue-cli 3 plugin to build multi-page application", 30 | "keywords": [ 31 | "vue", 32 | "vue-cli", 33 | "multi-page", 34 | "multipage", 35 | "multiple" 36 | ] 37 | } -------------------------------------------------------------------------------- /prompts.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 2 | name: 'generate', 3 | type: 'list', 4 | message: 'What do you want to generate?', 5 | choices: [ 6 | { 7 | name: 'Initial framework and generate examples', 8 | value: 'whole' 9 | }, 10 | { 11 | name: 'Initial framework only', 12 | value: 'init' 13 | } 14 | ], 15 | default: 'init' 16 | }] 17 | -------------------------------------------------------------------------------- /template/src/views/preview/App.vue: -------------------------------------------------------------------------------- 1 |