Page directory structure



Note that the default HTML template file is requiredpublic/index.htmlMove to the root directory.

Install dependencies

npm i --save-dev cross-env tasksfile

build/pages.js

Gets the multi-page objects required by the Vue CLI

const path = require('path')
const glob = require('glob')
const fs = require('fs')

const isProduction = process.env.NODE_ENV === 'production'

// Customize the page title for different modules
const titleMap = {
  index: 'home'
}

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))

      // If there is index. HTML in the module directory, use this file as an HTML template file
      const template = fs.existsSync(`${item}/index.html`)?`${item}/index.html`
        : path.join(__dirname, '.. /index.html')

      pages[basename] = {
        entry: `${item}/main.js`.title: titleMap[basename] || 'Default page',
        template,
        // This line of code is important
        // Compatible development and production HTML page hierarchy consistency
        filename: isProduction ? 'index.html' : `${basename}/index.html`}}})return pages
}

const pages = getPages(path.join(__dirname, '.. /src/pages/*'))

module.exports = pages
Copy the code

build/index.js

Execute the build command and run vue-cli-service build in a loop.

const chalk = require('chalk')
const rimraf = require('rimraf')
const { sh } = require('tasksfile')

const PAGES = require('./pages')

/ / the vue - cli - service - mode values
const mode = process.env.MODE || 'prod'

// Module name, possibly multiple
const moduleNames = process.argv[2]

// List of all pages
const pageList = Object.keys(PAGES)

// If the list of valid modules is not specified, the list of all pages is
const validPageList = moduleNames ? moduleNames.split(', ').filter((item) = > pageList.includes(item)) : pageList
if(! validPageList.length) {console.log(chalk.red('** Module name is incorrect **'))
  return
}

console.log(chalk.blue('Valid module:${validPageList.join(', ')}`))

// Delete the dist directory
rimraf.sync('dist')

console.time('Total compile time')
const count = validPageList.length
let current = 0
// execute module by module compilation
for (let i = 0; i < validPageList.length; i += 1) {
  const moduleName = validPageList[i]
  process.env.MODULE_NAME = moduleName

  console.log(chalk.blue(`${moduleName}The module starts compiling))

  // Run vue-cli-service build to compile
  sh(`vue-cli-service build --mode ${mode}`, { async: true }).then(() = > {
    console.log(chalk.blue(`${moduleName}Module compiled))
    console.log()
    current += 1
    if (current === count) {
      console.log(chalk.blue('----- All modules compiled -----'))
      console.timeEnd('Total compile time')}}}Copy the code

build/dev-modules.js

You can customize the module to be compiled during local development. The module name is the folder name under SRC/Pages.

// Local development needs to compile the module
module.exports = [

]
Copy the code

vue.config.js

const chalk = require('chalk')

const devModuleList = require('./build/dev-modules')

const isProduction = process.env.NODE_ENV === 'production'

// Total page
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) {
  // The name of the building module
  if(! PAGES[moduleName]) {console.log(chalk.red('** Module name is incorrect **'))
    return
  }
  pages[moduleName] = PAGES[moduleName]
} else {
  // Locally developed compiled modules
  // Compile all
  if (process.env.DEV_MODULE === 'all') {
    pages = PAGES
  } else {
    // Compile some modules
    const moduleList = [
      // Fix the compiled module
      'index'.'login'.// Custom compiled modules. devModuleList ] moduleList.forEach(item= > {
      pages[item] = PAGES[item]
    })
  }
}

module.exports = {
  // This line of code is important
  publicPath: isProduction ? '/' : '/',
  pages,
  // This line of code is important
  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}})}}Copy the code

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",}}Copy the code

Local development

When developing locally,npm run serveWill compile a custom module directory,npm run serve:allAll module directories are compiled.

The compiled directory structure for local development is as follows:



Therefore, you need to change the address after startuphttp://localhost:8080/index/index.html

Pack the result

Build time,npm run build:prodPackage all pages,npm run build:prod indexOnly the Index page is packaged.

The directory structure is as follows:



In this way, a consistent relative path can be used when jumping between modules.../index/index.html

After packaging, the contents of each module are packed into a separate directory.

Making the address