基于vue-cli3的自动化多页面模板,可以各页面独立资源分文件夹编译和原生所有资源统一编译.

大家可以直接使用我改好的初始模板.

自己搭建

  1. 创建自动化脚本
    在项目根目录创建script文件夹,里面创建两个文件splitBuild.jsgetPages.js.

getPages.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// getPages.js 自动获取目录结构
const glob = require('glob')
let pages = {}
module.exports.pages = function () {
glob.sync('./src/pages/*/*.js').forEach(filepath => {
let fileList = filepath.split('/')
let fileName = fileList[fileList.length - 2]
pages[fileName] = {
entry: `src/pages/${fileName}/${fileName}.js`,
// 模板来源
template: `src/pages/${fileName}/${fileName}.html`,
// 在 dist/index.html 的输出
filename: process.env.VUE_APP_TITLE !== 'ps' ? `${fileName}.html` : `${fileName}/${fileName}.html`,
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', fileName]
}
})
return pages
}

splitBuild.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// splitBuild.js 分开编译资源处理脚本
var fs = require('fs')
const glob = require('glob')
const config = require('../vue.config.js')

const publicPath = config.publicPath || ''
const outputDir = config.outputDir || 'dist'
/**
* js文件copy
* @param src
* @param dst
*/
var callbackFileJs = function (src, dst) {
fs.readFile(src, 'utf8', function (error, data) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
return false
}
fs.writeFile(dst, data.toString(), 'utf8', function (error) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
return false
}
if (dst.includes('.map')) {
// let srcName = src.split('/')[4]
// fs.unlink(`./${outputDir}/js/${srcName}.map`,function () { // 删除map
// })
// fs.unlink(`./${outputDir}/js/${srcName}`,function () { // 删除js
// })
} else { // JS写入成功
callbackFileJs(dst, `${dst}.map`)
}
})
})
}
// 复制目录
glob.sync(`./${outputDir}/js/*.js`).forEach((filepath, name) => {
let fileNameList = filepath.split('.')
let fileName = fileNameList[1].split('/')[3]// 多页面页面目录
let copyName = filepath.split('/')[3]
let changeDirectory = `./${outputDir}/${fileName}/js`// 多页面JS文件地存放址
if (!fileName.includes('chunk-')) {
// eslint-disable-next-line
fs.exists(changeDirectory, function (exists) {
if (exists) {
// console.log(`${fileName}下JS文件已经存在`)
callbackFileJs(filepath, `${changeDirectory}/${copyName}`)
} else {
fs.mkdir(changeDirectory, function () {
callbackFileJs(filepath, `${changeDirectory}/${copyName}`)
// console.log(`${fileName}下JS文件创建成功`)
})
}
})
}
})

/**
* css文件拷贝
* @param src
* @param dst
*/
var callbackFileCss = function (src, dst) {
fs.readFile(src, 'utf8', function (error, data) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
return false
}
fs.writeFile(dst, data.toString(), 'utf8', function (error) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
PromiseRejectionEvent(error)
return false
}
// console.log('CSS写入成功')
fs.unlink(src, function () { // css删除成功
})
})
})
}
// 复制目录
glob.sync(`./${outputDir}/css/*.css`).forEach((filepath, name) => {
let fileNameList = filepath.split('.')
let fileName = fileNameList[1].split('/')[3]// 多页面页面目录
let copyName = filepath.split('/')[3]
let changeDirectory = `./${outputDir}/${fileName}/css`// 多页面JS文件地存放址
if (!fileName.includes('chunk-')) {
/* eslint-disable-next-line */
fs.exists(changeDirectory, function (exists) {
if (exists) {
// console.log(`${fileName}下CSS文件已经存在`)
callbackFileCss(filepath, `${changeDirectory}/${copyName}`)
} else {
fs.mkdir(changeDirectory, function () {
callbackFileCss(filepath, `${changeDirectory}/${copyName}`)
// console.log(`${fileName}下CSS文件创建成功`)
})
}
})
}
})

/**
* html文件替换
* @param src
* @param dst
*/
var callbackFile = function (src, dst, name, filepath) {
const index = publicPath.lastIndexOf('/')
let pt = publicPath
if (index !== -1) {
const count = publicPath.length
if (index + 1 === count) {
pt = publicPath.slice(0, index - 1)
}
}

fs.readFile(src, 'utf8', function (error, data) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
return false
}
let regCss = new RegExp(pt + '/css/' + name + '', 'g')
let regJs = new RegExp(pt + '/js/' + name + '', 'g')
let htmlContent = data.toString().replace(regCss, `./css/${name}`).replace(regJs, `./js/${name}`)
fs.writeFile(dst, htmlContent, 'utf8', function (error) {
if (error) {
// eslint-disable-next-line no-console
console.log(error)
return false
}
// console.log('html重新写入成功')
if (src.indexOf('/index.html') === -1) {
fs.unlink(src, function () {
// console.log('html删除成功')
})
}
fs.unlink(filepath, function () { // css删除成功
})
fs.unlink(filepath + '.map', function () { // css删除成功
})
})
})
}
// 复制目录
glob.sync(`./${outputDir}/js/*.js`).forEach((filepath, name) => {
let fileNameList = filepath.split('.')
let fileName = fileNameList[1].split('/')[3]// 多页面页面目录
let thisDirectory = `./${outputDir}/${fileName}/${fileName}.html`// 多页面JS文件地存放址
let changeDirectory = `./${outputDir}/${fileName}/index.html`// 多页面JS文件地存放址
if (!fileName.includes('chunk-')) {
callbackFile(thisDirectory, changeDirectory, fileName, filepath)
}
})

config配置

1
2
3
4
5
6
7
8
9
// vue.config.js
let pageMethod = require('./script/getPages.js')
const pages = pageMethod.pages()
// build-s编译不能将publicPath设置为'./'或'',会导致相对路径资源路径混乱
module.exports = {
pages,
publicPath: '/',
outputDir: 'dist'
}

package.json

1
2
3
4
5
6
7
8
9
10
{
...
"scripts": {
"serve": "vue-cli-service serve --open ",
"build-s": "vue-cli-service build --mode ps && node script/splitBuild.js",
"build": "vue-cli-service build",
...
},
...
}

使用说明

  1. 在src中创建pages文件夹
    1

  2. pages中创建的每一个文件夹就是一个单页面目录
    1

  3. 我们在对应单页面目录里创建对应html,vue及js文件即可.
    1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // html 就是页面的初始html(传统项目一般在public里面)
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>hello-world</title>
    </head>
    <body>
    <noscript>
    <strong>We're sorry but hello-world doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    </body>
    </html>
1
2
3
4
5
6
7
8
9
// js文件  项目初始化js
import Vue from 'vue'
import App from './index.vue'

Vue.config.productionTip = false

new Vue({
render: h => h(App)
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div id="app">
<img alt="Vue logo" src="../../assets/logo.png">
<p>页面2URL:http://localhost:8080/index2/</p>
</div>
</template>

<script>
// vue主页面
export default {
name: 'app'
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>