Vue-CLI 多页分目录打包__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
页面目录结构
注意需要将默认的 html 模板文件 public/index.html
移动到根目录下。
安装依赖
npm i --save-dev cross-env tasksfile
build/pages.js
获取 Vue CLI 需要的多页对象
const path = require('path')
const glob = require('glob')
const fs = require('fs')
const isProduction = process.env.NODE_ENV === 'production'
// 自定义不同模块的页面 title
const titleMap = {
index: '首页'
}
function getPages (globPath) {
const pages = {}
glob.sync(globPath).forEach((item) => {
const stats = fs.statSync(item)
if (stats.isDirectory()) {
const basename = path.basename(item, path.extname(item))
// 如果模块目录下有 index.html 则使用该文件为 html 模板文件
const template = fs.existsSync(`${item}/index.html`)
? `${item}/index.html`
: path.join(__dirname, '../index.html')
pages[basename] = {
entry: `${item}/main.js`,
title: titleMap[basename] || '默认页面',
template,
// 这行代码很重要
// 兼容开发和生产时 html 页面层级一致
filename: isProduction ? 'index.html' : `${basename}/index.html`
}
}
})
return pages
}
const pages = getPages(path.join(__dirname, '../src/pages/*'))
module.exports = pages
build/index.js
执行构建命令,循环执行 vue-cli-service build
。
const chalk = require('chalk')
const rimraf = require('rimraf')
const { sh } = require('tasksfile')
const PAGES = require('./pages')
// vue-cli-service --mode 值
const mode = process.env.MODE || 'prod'
// 模块名,可能为多个
const moduleNames = process.argv[2]
// 全部页面列表
const pageList = Object.keys(PAGES)
// 有效模块列表 未指定则为全部页面列表
const validPageList = moduleNames ? moduleNames.split(',').filter((item) => pageList.includes(item)) : pageList
if (!validPageList.length) {
console.log(chalk.red('**模块名不正确**'))
return
}
console.log(chalk.blue(`有效模块:${validPageList.join(',')}`))
// 删除 dist 目录
rimraf.sync('dist')
console.time('总编译时间')
const count = validPageList.length
let current = 0
// 逐个执行模块编译
for (let i = 0; i < validPageList.length; i += 1) {
const moduleName = validPageList[i]
process.env.MODULE_NAME = moduleName
console.log(chalk.blue(`${moduleName} 模块开始编译`))
// 通过 vue-cli-service build 编译
sh(`vue-cli-service build --mode ${mode}`, { async: true }).then(() => {
console.log(chalk.blue(`${moduleName} 模块编译完成`))
console.log()
current += 1
if (current === count) {
console.log(chalk.blue('-----全部模块编译完成-----'))
console.timeEnd('总编译时间')
}
})
}
build/dev-modules.js
自定义本地开发时需要编译的模块,模块名为 src/pages
下的文件夹名。
// 本地开发需要编译的模块
module.exports = [
]
vue.config.js
const chalk = require('chalk')
const devModuleList = require('./build/dev-modules')
const isProduction = process.env.NODE_ENV === 'production'
// 总的页面
const PAGES = require('./build/pages')
for (const basename in PAGES) {
if (Object.prototype.hasOwnProperty.call(PAGES, basename)) {
PAGES[basename].chunks = [
'chunk-vue',
'chunk-vendors',
'chunk-common',
`${basename}`
]
}
}
let pages = {}
const moduleName = process.env.MODULE_NAME
if (isProduction) {
// 构建模块的名称
if (!PAGES[moduleName]) {
console.log(chalk.red('**模块名不正确**'))
return
}
pages[moduleName] = PAGES[moduleName]
} else {
// 本地开发编译的模块
// 编译全部
if (process.env.DEV_MODULE === 'all') {
pages = PAGES
} else {
// 编译部分模块
const moduleList = [
// 固定编译的模块
'index',
'login',
// 自定义编译的模块
...devModuleList
]
moduleList.forEach(item => {
pages[item] = PAGES[item]
})
}
}
module.exports = {
// 这行代码很重要
publicPath: isProduction ? './' : '/',
pages,
// 这行代码很重要
outputDir: isProduction ? `dist/${moduleName}` : 'dist',
productionSourceMap: false,
css: {
loaderOptions: {
sass: {
prependData: '@import "~@/styles/variables.scss";'
}
}
},
chainWebpack: (config) => {
config.optimization.splitChunks({
cacheGroups: {
vue: {
name: 'chunk-vue',
test: /[\\/]node_modules[\\/]_?(vue|vue-router|vuex|element-ui)(@.*)?[\\/]/,
priority: -1,
chunks: 'initial'
},
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
})
}
}
package.json
{
"scripts": {
"serve": "vue-cli-service serve",
"serve:all": "cross-env DEV_MODULE=all vue-cli-service serve",
"build:test": "cross-env MODE=test node build/index.js",
"build:prod": "cross-env MODE=prod node build/index.js",
"lint": "vue-cli-service lint",
}
}
本地开发
本地开发时,npm run serve
会编译自定义的模块目录,npm run serve:all
会编译全部模块目录。
本地开发时编译后的目录结构如下:
所以启动后,需要将地址改为 http://localhost:8080/index/index.html
。
打包结果
构建时, npm run build:prod
打包全部页面,npm run build:prod index
仅打包 index 页面。
打包后的目录结构如下:
这样在不同模块之间跳转时,可以使用一致的相对路径跳转方式, ../index/index.html
。
打包后每个模块的内容打包到一个单独目录下。
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 郑小辉 原文链接:https://juejin.im/post/6950481985772978212