vue多入口项目,模块开发

多入口多模块项目

一般的webpack项目都是单页面项目,入口在main.js,我们也是可以配置webpack为多入口项目的。如果一个项目很大,有很多小的分项目,这种情况就比较适合多页面程序了,通过不同的入口加载不同的模块,这样可以让前端分模块开发,解决了一个入口多人开发时各种各样问题的冲突。

优点

  • 进行全局的掌控
  • 开发一个子系统时,不需要启动另外一个系统
  • 根据需求加载一个或多个系统模块
  • 想不出来了。。。。

怎么配置vue多入口项目?

首先,我们先创建一个vue项目,这个请参考cli3官网的教程。
这时main.js是项目入口
首先我在src下面创建了四个模块:ax-website finance pms-manage system
在这里插入图片描述
四个模块的基本结构和src的结构相似都需要app.vue和main.ts(这里用的是typescript开发)

我们就需要一个命令行工具来帮我们实现了inquirer,这个命令行库具体可以看官方文档。
具体的思路就是,使用inquire来询问开发者启动哪些项目,然后保存这个配置,然后使用vue.config.js来读取配置项启动选择的项目。
我们需要一个配置文件来管理我们的多入口启动项,我们在根目录下新建pack-master.config.yaml:
在这里插入图片描述

default:
  app:
    index: 'src/main.ts'   //主入口
    pms-manage: 'src/pms-manage/main.ts'
    ax-website: 'src/ax-website/main.ts'
    system: 'src/system/main.ts'
    finance: 'src/finance/main.ts'
projects:
  index:
    app:
      - index
  pms-manage:
    app:
      - pms-manage
  ax-website:
    app:
      - ax-website
  system:
    app:
      - system
  finance:
    app:
      - finance

引入每个模块的入口文件,然后在根目录下创建pack-master.js文件:
在这里插入图片描述

'use strict'
const inquirer = require('inquirer')
const yaml = require('js-yaml')
const fs = require('fs')
const path = require('path')
const _ = require('lodash')

const doc = yaml.safeLoad(
  fs.readFileSync(path.join(__dirname, './pack-master.config.yaml'), 'utf8')
)
const historyFilePath = path.join(__dirname, 'pack-master.history.json')
const { projects } = doc
const baseProject = projects.index
const defaultConfigs = doc.default
const hiddenChoices = ['index']
const projectsList = Object.keys(projects)
  .filter(projectName => hiddenChoices.indexOf(projectName) === -1)
  .map(projectName => ({
    name: projectName
  }))

function findEntries(project, collections) {
  Object.keys(project).forEach(configName => {
    if (configName === 'dependencies') {
      return
    }
    collections[configName] = collections[configName] || {}
    const config = project[configName]
    config.forEach(entryName => {
      const entryPath = defaultConfigs[configName][entryName]
      collections[configName][entryName] = entryPath
    })
  })
}

function mergeWithBaseProject(collections) {
  const baseCollections = {}
  findEntries(baseProject, baseCollections)
  return _.merge(baseCollections, collections)
}

function findDependencies(_projectNames) {
  let projectNames = _projectNames
  projectNames.forEach(projectName => {
    const project = projects[projectName]
    const { dependencies } = project
    if (dependencies) {
      projectNames = _.uniq(projectNames.concat(dependencies))
    }
  })
  return projectNames
}

inquirer
  .prompt([
    {
      type: 'confirm',
      name: 'use_prev',
      message: '使用上次的配置?',
      default: true,
    },
    {
      type: 'checkbox',
      message: '选择项目',
      name: 'projects',
      choices: projectsList,
      when(answers) {
        return !fs.existsSync(historyFilePath) || !answers.use_prev
      },
      validate(answer) {
        if (answer.length < 1) {
          return '你必须至少选择一个项目.'
        }
        return true
      },
    },
  ])
  .then(answers => {
    if (!answers.use_prev || !fs.existsSync(historyFilePath)) {
      let collections = {}
      // Find dependencies
      answers.projects = findDependencies(answers.projects)
      answers.projects.forEach(projectName => {
        const project = projects[projectName]
        findEntries(project, collections)
      })
      collections = mergeWithBaseProject(collections)
      collections.projects = answers.projects
      const data = JSON.stringify(collections, null, '  ')
      fs.writeFileSync(historyFilePath, data)
    }
    const projectList = require('./pack-master.history.json').projects
    console.log(`使用项目: \x1b[32m${projectList.join(', ')}\x1b[0m`)
  })

这样在我们启动项目的时候就能选择不同的模块去加载,并创建历史记录,在下次启动时会读取历史记录来提示是否加载,如果选择Y则使用上次加载的模块,如果选择N,则重新选择模块加载。

最后,需要在vue.config.js配置pages:

const pages = {}
if (isProduction) {
  const yaml = require('js-yaml')
  const fs = require('fs')

  const doc = yaml.safeLoad(fs.readFileSync(path.join(__dirname, './pack-master.config.yaml'), 'utf8'))
  app = doc.default.app
} else {
  const masterPackConfigs = require('./pack-master.history.json')
  app = masterPackConfigs.app
}
for (let name in app) {
  pages[name] = {
    entry: app[name],
  }
}
module.exports = {
	pages,
}

这样就可以正常使用了,完美!贴图
在这里插入图片描述


版权声明:本文为weixin_44705688原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。