微服务架构最佳实践(vue-cli3多项目搭建)

4,835 阅读3分钟

作者俊余,前端界的一名小学生。

背景

2016年由ThoughtWorks提出微前端的概念,将后端微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。

H5前端所承载的业务主要是拉新,保持用户粘性,保持项目生态的完整性以及数据展示,管理系统。 所以对应到产品就是活动页面(拉新,保持用户粘性),各家小程序(保持项目生态的完整性),pc后台管理系统(数据展示,管理系统) 如何把微服务架构思路加入到我们现有框架中。

框架目的

  • 独立开发、独立测试、独立发布、独立部署,提高了开发效率。 (业务解耦)
  • 统一的样式、统一的公共组件,项目的粒度易控制
  • 资源按需加载,提取公共库

理解美团的微服务架构

我理解美团的微服务架构构建portal项目来做项目总入口,提供全局 路由,require依赖,数据流。

portal 单独把Main.js打包成一个项目作为项目总入口,子项目只生成chunk包,按需加载。 加载就是合并的过程,提供完整的子项目注册,挂载,分离。

架构图

我们参考美团的微服务架构,根据产品的不同特性。将架构分为下面两种。

1. 单页面应用架构

单页应用架构我们主要应用在活动项目中,我们把每个活动抽象成组件,最终线上运行的是一个单页应用 活动框架继承了portal项目的所有优点,项目微服务化,业务解耦等等。

  • 通过路由精准控制每个活动上下线,下线活动代码随时可以删除(不可复用)
  • 活动通用页面,通用组件可复用

我们先来看下目录结构

活动架构

整个活动项目将src/main.js作为主入口,加载所有的依赖,引入页面路由,通过统一的Router来做资源索引。 使用异步加载chunks,达到比portal更优的效果

component: () => import(/* webpackChunkName: "newUserCoupon-h5" */ '@/pages/newUserCoupon/views/couponH5')

原理

一个nginx规则对应一个index.html。1对1,线上根据路由进入不同的活动,同时不必加载所有业务代码,但可以提取公共依赖。

2. 多项目打包

多项目打包我们主要应用在hybird项目中,框架最终输出的每一个独立打包的文件夹,每个项目互不干扰,源代码都在一个仓库里。

  • 开发,打包,生产的代码都通过文件夹区分开,项目之间互不影响,独立的路由系统。

vue.config.js

const path = require('path');
let projectMode = process.argv.slice(0).reverse()[1]
let appName =  process.argv.slice(0).reverse()[0].replace('--', '');
function resolve (dir) {
    return path.join(__dirname, dir)
}
console.log(process.argv.slice(0).reverse())
if (projectMode == 'serve') {
    // let projectServeName = process.argv[3].replace('--', '');
    module.exports = {
        lintOnSave: false,
        chainWebpack: (config)=>{
            config.resolve.alias
                .set('@pages', resolve('src/pages'))
        },
        pages: {
            index: {
                entry: 'src/pages/' + appName + '/main.js',
            }
        },
        devServer: {
            open: 'Google Chrome',
            overlay: {
                warnings: false,
                errors: false
            }
        }
    }
} else {
    module.exports = {
        outputDir: 'dist/'+appName,
        chainWebpack: (config)=>{
            config.resolve.alias
                .set('@pages', resolve('src/pages'))
        },
        configureWebpack: {
            resolve: {
                alias: {
                    'vue$': 'vue/dist/vue.js'
                }
            }
        },
        publicPath: './',
        productionSourceMap: false,
        pages: {
            index: {
                // page 的入口
                entry: 'src/pages/'+ appName +'/main.js',
                // 模板来源
                template: 'public/index.html',
                // 在 dist/index.html 的输出
                filename: 'index.html',
                // 当使用 title 选项时,
                // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
                title: '',
                // 在这个页面中包含的块,默认情况下会包含
                // 提取出来的通用 chunk 和 vendor chunk。
                chunks: ['chunk-vendors', 'chunk-common', 'index']
            }
        }
    }
}

接下来只要运行

 yarn run build --{appname}

就可以打包出我们希望的应用啦

打包页面

线上nginx.conf 我们优化一下不需要每一个项目都需要修改nginx

 if ($uri ~ /hybird/(.*)/.*) {
    set $hybird /hybird/$1;
    }
    location ~ /hybird/(.*)/.* {
    	 root /data/www-data/hupu.com;
      try_files $uri ./$uri/index.html $hybird/index.html;
    }

多页面应用打包网上有很多文章介绍。 我参考的是Vue CLI 3多页应用实践和源码设计. 这篇文章不仅仅给出的完善的配置,目录结构并且包含了源码分析

后续

后续我们想改进package.json 依赖,进一步抽离package.json 参考文献: