vue工程包含多个项目且支持多个环境部署

前景介绍

1>> 项目中涉及多个子系统的n多功能样式部分,存在较大的冗余部分,可考虑将这些不同的子系统归属于同一个vue工程项目下,支持组件共享,样式共享,静态数据共享等内容
2>> 由于开发环境,测试环境,准生产环境,生产环境等多个环境有不同的访问内容(服务ip,对应一些不同的设置项),故而需要进行区分:设计如下

vue工程包含多个项目且支持多个环境部署_第1张图片

设计思路

1> 通过项目的package.json中的命令模块[scripts]中对默认的命令进行重构,将启动[npm run dev],打包[npm run build]的命令按照自定义的方式触发动作
2>对所执行命令进行分段解析,完成启动打包的动作【截取的部分包含【启动 || 打包】【项目名称】【环境】】
3>工程使用 [email protected] 进行初始化工程进行搭建(项目目录结构以及启动打包配置项会有一定的区别, [email protected] 以上没有vue.config.js文件,配置方面存在一定的差异)

项目目录结构设计

项目目录依托mddir插件进行生成
npm install mddir (安装)
mddir (使用,直接在终端命令行中输入即可运行,会在工程中(package.json同级)生成directoryList.md文件)
vue工程包含多个项目且支持多个环境部署_第2张图片

项目运行设计、维护方案

  1. 项目名称,路由文件名称,vuex中modules模块名称必须一致,后续命令执行匹配对应的项目,如果检测不到,则命令会阻塞执行,同时也方便后续开发维护

  1. 最外层的公共组件,存放的为公共项目共享组件,严谨存放又业务逻辑相关的内容

代码功能模块解析

后续描述围绕命令npm run [b/d] [projectA/projectB] [dev,test,pre,pro]进行叙述;
  1. package.json中进行项目命令的初始入口拆分
增加"d" "b" 两部分内容,指向的【默认项目目录为根目录下的config】commandConfig.js为自定义的命令解析入口
ORDER_TARGET=DEV/BUILD 为后续在剖析命令的过程中加以区分所执行动作【后面会解释】
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js",
    "d": "node config/commandConfig.js ORDER_TARGET=DEV",
    "b": "node config/commandConfig.js ORDER_TARGET=BUILD"
},
  1. 对执行命令进行解析文件建立
解析思路大概为:
a.>通过获取node环境变量process.argv 进一步剥离所执行命令中携带的的相关信息
b.>通过命令中剥离出的信息,将默认目录指向对应的子项目,完成启动 || 打包动作
  1. 解析node环境变量process.argv

//console.log(process.argv) argv: argv: ['C:\\Program Files\\nodejs\\node.exe','\\config\\dev.js','ORDER_TARGET=DEV','project','pro']
//[0] = 电脑系统中存储的node所对应的程序路径 C:\\Program Files\\nodejs\\node.exe
//[1] = vue工程中所执行的当前指令对应的配置项文件路径 \\config\\dev.js
//[2] = 对应package.json当中scripts中的指令后所跟随的标识 [此处对应上述中讲的项目标识] ORDER_TARGET=DEV
//[3] = 所对应的项目名称为 projectA
//[4] = 为后新增的标识 pro 环境标识
//[n] = 如果继续叠加,以此类推son当中定义的执行标识[自定义]

let [,,ORDER_TARGET,PROJECT_NAME,LOP_NAME] = process.argv;
  1. 剥离、区分命令执行标识

区分当前执行命令:npm run dev/build
默认的配置项为package.json中scripts模块中指定的ORDER_TARGET属性
const finalTarget = ORDER_TARGET && ORDER_TARGET?.split('=')[1] || '';
const ORDER_SCRIPT = finalTarget == 'DEV' ? 'npm run start' : 'npm run build';//获取执行命令
  1. 判断当前命令中所指定项目是否在项目中具备

为方便后续项目的拓展以及维护,/src/projects/xxx的项目名称以及命令中所携带的项目名称必须对应
通过fs模块进行文件检测,加以判断(需先安装fs模块后在文件中进行require引入)
fs.exists()
第一个参数为当前所执行命令对应的项目默认指定路径(全文子项目路径位于/src/projects/xxx)
第二个参数为回调函数,回调函数参数为一个布尔值,当检测项目名称存在时,则为true,反之亦然
fs.exists(`./src/projects/${PROJECT_NAME}`,(v)=>{})
  1. 写入工程标识及运行标识

通过fs.writeFileSync()方法进行写入
第一个参数为需要写入文件的详细路径,这里放在./config/engineeringConfig.js
第二个参数为需要写入的内容(为一个文件对外暴露的完整写法)
写入的内容分为两部分,一部分为上述获取的项目名称projectA,另一部分为当前运行项目的环境标识,(dev/test)
后续可对该文件当中写入的两部分内容进行引入,使用
fs.writeFileSync('./config/engineeringConfig.js', `exports.PROJECT_NAME = '${PROJECT_NAME}';exports.LOP_NAME='${LOP_NAME}';`)
  1. 动态执行命令

通过child_process模块进行动态命令的触发(如果不是很懂这块的内容,可自行百度)
execSync()方法目前只需要关注第一个参数即可,内容为上述最开始根据命令中的ORDER_TARGET所获取的内容指定的执行命令
const ORDER_SCRIPT = finalTarget == 'DEV' ? 'npm run start' : 'npm run build';
这里需要注意:npm run start、build 必须在package.json当中具备的基础命令
let exec = require('child_process').execSync;
exec(ORDER_SCRIPT, {stdio: 'inherit'});
  1. 其他配置文件参数修缮
对除了当前核心命令的动作剖析以外,需要对其他默认的打包动作,所对应的产出目录,及配置文件进行修改
同时对各个子项目的默认目录指向配置文件,路由文件,store进行配置初始化
  • build目录配置完善

  1. 打包文件产出目录配置

配置打包命令运行的过程中访问的基础目录指向,产出静态目录标识配置等系列内容
打包/build/目录下所对应的配置项内容,均在package.json当中的build命令中进行首次初始化:scripts对象中进行挂载
(build:node build/build.js)
工程中所依赖的项目标识(PROJECT_NAME)内容位于/config/engineeingConfig.js(项目命令运行剖析存储的关键信息)需要在每个文件中进行引入使用
const {PROJECT_NAME} = require('../config/engineeringConfig.js');
//配置默认打包目录输入目录 /config/index.js
build: {
    // 配置打包以后的静态文件目录index.html的指向
    index: path.resolve(__dirname, `../dist/${PROJECT_NAME}/index.html`),
    // 配置打包静态文件输出目录
    assetsRoot: path.resolve(__dirname, `../dist/${PROJECT_NAME}`),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    devtool: '#source-map',
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    bundleAnalyzerReport: process.env.npm_config_report
}

//修改build/build.js中默认基础配置指定的webpack.prod.conf.js
//plugins中的htmlWebpackPlugin中的路径修改
new HtmlWebpackPlugin({
  filename: config.build.index,
  template: `src/projects/${PROJECT_NAME}/index.html`,
  inject: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
  },
  chunksSortMode: 'dependency'
}),

//修改build/的webpack.base.config.js(该文件于webpakc.prod.conf.js中进行引入)
//修改独立子项目的单独访问入口main.js的定向路径
entry: {
    app: `./src/projects/${PROJECT_NAME}/main.js`
},
  1. 修改默认启动项的配置

默认启动项的初始化入口位于package.json中的dev命令(scripts中)
dev:webpacK-dev-server --inline --progress --config build/webpack.dev.conf.js
//build/webpack.dev.conf.js
//修改插件指定路径 位于plugins中
new HtmlWebpackPlugin({
  filename: 'index.html',
  template: `src/projects/${PROJECT_NAME}/index.html`,
  inject: true
}),
  1. 默认访问标识alias配置

配置内容不同于常规的vue-cli项目,以往的内容位于package.json当中进行配置,高版本的vue-cli位于/build/webpack.base.config.js中的resolve中进行挂载初始化默认访问内容
@为后续访问src根目录建立
@@为后续访问子项目的根目录进行建立(如后续有需求,可自定义修改)
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      '@@':resolve(`src/projects/${PROJECT_NAME}`)
    }
},
  • 代理配置,直连ip访问配置

1.>针对项目中的访问ip端口进行统一的管理,对外暴露,生成前端统一的配置文件入口
2.>/config下新建url.config.js(该文件放置于此处,考虑如下:多项目的存在,访问的服务ip应该大致相似,甚至一致,所以单独提取放置于此,如果有单独需要进行修改的部分,可在对应的子项目中进行单独迭代配置)
3.>LOP_NAME为命令执行解析过程中,写入的环境标识(dev,test,pre,pro)部分,如果项目当中有其他的环境需求,可自定义进行相对应的拓展
4.>该文件会在request.js中axios.create的过程中(BASEURL)进行注入,命令中的环境标识,目前主要作用于此
// /config/url.config.js
const {LOP_NAME} = require('./engineeringConfig');
module.exports = {
    dev:{
        NODE_ENV:'dev'
    },
    test:{
        NODE_ENV:'185'
    },
    pre:{
        NODE_ENV:'173'
    },
    pro:{
        NODE_ENV:'pro'
    }
}[LOP_NAME];
  • vuex配置,router配置

1.>在/src/projects中的每个目录下分别新增store/index.js, router/index.js目录,分别放置相对应内容
2.>在main.js中分别引入,进行挂载(需要注意的是,这里的main.js为/projects/xxx中每个项目中所对应的main.js)
3.>每个子项目中main.js的配置入口位于/build/webpack.base.config.js中的entry模块当中
//import {PROJECT_NAME} from '../config/engineeringConfig.js';
//这里的 PROJECT_NAME 数据来源于命令执行开始,解析命令过程中进行存储的项目标识
entry: {
    app: `./src/projects/${PROJECT_NAME}/main.js`
},

如何新增一个子项目【待完善】

  1. 指定项目

工程中位于/src/projects/ 中留有默认的基础项目框架 baseProject 可对此目录进行完整复制,可作为新的子项目基础进行拓展(该基础项目当中包含了router,store等基础相关配置)
  1. /src/views/增加相对严格i的呢目录

项目启动,打包运行命令

命令的运行必须指定项目名称,否则命令运行提示异常,阻塞命令的执行

npm run d projectA 启动A项目 (启动可以不指定默认环境标识,则访问dev)
npm run d projectB 启动B项目 (启动可以不指定默认环境标识,则访问dev)

npm run b projectA test 打包测试分支
npm run d projectA pre 打包准生产分支
npm run b projectA 打包生产分支 (默认不指定环境,则打包的的环境标识为pro)
npm run d projectA pro 打包生产分支

后期拓展

工程内公共组件动态处理(具备自动挂载能力)
依赖element二次封装表格,实现自动生成,动态加载,动态灌入数据等
工程公共函数库完善
全文前后端交互api动态封装挂载(接口,请求实现相对隔离)

完整项目git地址

后续有项目问题,可联系 [email protected]进行沟通,随时可提供义务代码诊断
https://gitee.com/renmr/multi_project.git

你可能感兴趣的:(vue,node,webpack,vue.js,vue,node.js,webpack)