页面目录结构
注意需要将默认的 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 。
打包后每个模块的内容打包到一个单独目录下。
总结
© 版权声明
THE END
暂无评论内容