使用Vue-CLI生成的目录结构和webpack配置都是为了配合单文件应用的,如果需求是一个多页面应用那怎么办呢?本文通过更改webpack配置,我们可以把默认的单文件配置更改为多文件配置
目录结构
先看一个商城src/page下的目录结构:
├─cart
│ cart.css
│ cart.html
│ cart.js
│ cart_base.css
│ cart_trade.css
│
├─category
│ category.css
│ category.html
│ category.js
│
├─goods
│ goods.css
│ goods.html
│ goods.js
│ goods_common.css
│ goods_custom.css
│ goods_mars.css
│ goods_sku.css
│ goods_theme.css
│
├─index
│ index.css
│ index.html
│ index.js
│
├─member
│ │ member.html
│ │ member.js
│ │
│ └─components
│ address.css
│ address.vue
│ address_base.css
│ all.vue
│ form.vue
│ member.css
│ member.vue
│ member_base.css
│
└─search
search.css
search.html
search.js
复制代码
我对文件的组织方式是: 各个页面的html,css,js放在同一目录下,方便管理。每个html都有一个对应的入口文件,如:cart.js
,category.js
,goods.js
等。
多页面入口配置
既然要配置成多页面,那就先配置webpack的entry,可以看到vue-cli生成的webpack.base.conf.js配置就只有一个入口:
// webpack.base.conf.js
entry: {
app: './src/main.js'
}
复制代码
我们的目的是找到每个页面目录下的所有入口文件名及其路径。 这里我为了方便读取文件路径,直接使用glob
// /build/utils.js/
let glob = require('glob')
let PAGE_PATH = path.resolve(__dirname, '../src/pages')
exports.entries = function() {
//entryFiles是文件路径数组
let entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
let map = {}
entryFiles.forEach((filePath) => {
// 取出文件名
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
map[filename] = filePath
})
return map
}
复制代码
简单几行代码,我们便配置好了一个多页面的入口。由于出口是跟入口一一对应的,所以我们不需要再对出口做任何配置。
接下来只需要注释掉webpack.base.conf.js
里面的入口配置代码换成我们刚才配置的即可:
// webpack.base.conf.js
module.exports = {
// entry: {
// // app: './src/main.js'
// },
entry: utils.entries()
...
}
复制代码
多页面输出配置
多页面输出配置只需要关注HtmlWebpackPlugin即可。 因为HtmlWebpackPlugin默认只有一个template,通过查阅文档,发现一个HtmlWebpackPlugin只能配置一个String类型的template,不能配置成数组形式。换句话说,我们有多少个页面,就需要多少个HtmlWebpackPlugin。
先看下,webpack.dev.conf.js里面HtmlWebpackPlugin的配置:
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
复制代码
和 webpack.prod.conf.js里面HtmlWebpackPlugin的配置
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
})
复制代码
注意到开发环境和生产环境不一样,需要分别配置。
话不多说,上代码:
exports.htmlPlugin = function() {
let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
let arr = []
entryHtml.forEach((filePath) => {
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
let conf = {
template: filePath,
filename: filename + '.html',
chunks: [filename],
inject: true
}
if (process.env.NODE_ENV === 'production') {
conf = merge(conf, {
chunks: ['manifest', 'vendor', 'app', filename],
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
}
arr.push(new HtmlWebpackPlugin(conf))
})
return arr
}
复制代码