无界微前端,零基础入门到精通,收藏这篇就够了

目录

前置知识

一、无界微前端的优缺点

1.优点

2.缺点

二、微前端技术选型决策树

三、无界通讯

1、通过props方法

2、通过 bus 方法

3.通过 postmessage 方法

4.路由跳转

四、插件系统

1. html-loader 可以对子应 html 进行处理

2. jsIgnoresh和cssIgnores(子应用自己加载)

3. js-excludes 和 css-excludes 可以排除子应用特定的 js 和 css 加载

4. js-before-loaders、js-loader、js-after-loaders 可以方便的对子应用 js 进行自定义

5. css-before-loaders、css-loader、css-after-loaders 可以方便的对子应用 css 进行自定义

五、基础改造

1、主应用

2、子应用

(1)vue.config.js主要是为了解决本地调用的时候跨域问题

(2)main.js(以智能网关为例)

3、主应用接入无界组件

4、子应用其他改造

六、应用共享

七、使用wujie-polyfill插件


前置知识

monorepo

一、无界微前端的优缺点

1.优点

1.预加载和预执行
预执行指的是在应用空闲的时候将子应用提前渲染出来exec:true
预加载所需要的静态资源提前从网络中加载到内存中(preloadApp:({name: ‘唯一标识’,exec:true}))
提升子应用打开的首屏时间
2、弹框对比iframe可以全屏显示
3.如果路由保持活性,则可以通过浏览器前进和回退回到之前的路由

2.缺点

1、兼容性风险:不兼容旧版浏览器(如IE11)
2、Shadow DOM导致元素选择器失效,因此 body 也要加上定位
如果需要从外部影响Shadow DOM内的样式,使用::part 而不是用/deep/或>>>

<!-- 子应用 -->
<div part="alert-box" >
  新增定义
</div>
<!--主应用-->
wujie-app::part(alert-box) {
  background: red;
}

二、微前端技术选型决策树

├─是否需要绝对安全隔离?

├─ 是 → iframe
└─ 否 → 是否需要IE兼容?
├─ 是 → qiankun
└─ 否 → 是否需要高性能组件级集成
├─ 是 → 无界微前端
└─ 否 → qiankun(综合生态考量)

三、无界通讯

1、通过props方法
<!-- 主应用 -->
<WujieVue
   ...
    :props="$store.state.wujieProps"
></WujieVue>
// 子应用
window.$wujie.props.serverPath


// 法二:
//主应用main.js
const props = {
    jump: (name, query) => {
        router.push({ name, query });
    },
    parent_Window: window,
};
 setupApp({
    name: item.code /** 唯一性用户必须保证 */,
    url: item.path /** 需要渲染的url */,
    exec: true /** 预执行 */,
    props /** 注入给子应用的属性 */,
    ...lifecycles,
    degrade:false,//true则话,子应用会变成iframe
});
//子应用
window.$wujie.props.parent_Window
2、通过 bus 方法
// 子应用 App.vue
watch: {
    $route() {
        window.$wujie?.bus.$emit('sub-route-change', 'vue2', this.$route.path);
    }
},
// 主应用Main.js
bus.$on("sub-route-change", (name, path) => {
  console.log(name, path)
});
3.通过 postmessage 方法
/* 主应用传给子应用
  主应用代码
  代码的test是来源于当前WujieVue标签中定义的那个name属性
*/
// 发送方为主应用的代码
handlePostmessageToChild() {
    const subAppWindow = window.document.querySelector(
        'iframe[name="test"]'
    ).contentWindow;
    const data = {
        type: "test",
        message: "你好test-child1-base,我是主应用,现在发消息给你"+new Date().getTime()
    };
    subAppWindow.postMessage(JSON.stringify(data), "*");
}
// 发送方为子应用的代码
handlePostmessageToMain() {
    window.parent.postMessage(
        JSON.stringify({
            type: "main",
            message: `test-child1-base:已收到内容为"${this.parentMsg}"的信息`
        }),
        "*"
    );
}
// 接收方的代码
mounted() {
    window.addEventListener("message", this.handleMessage);
},
beforeDestroy() {
    window.removeEventListener("message", this.handleMessage);
},
methods: {
    handleMessage(e) {
        try {
            let res = JSON.parse(e.data);
            if (res.type === "test") { //这个test 是主应用发送给子应用的消息类型
                this.parentMsg = res.message; // 这个就是主应用发过来的信息
            }
        } catch (err) {
            return;
        }
    }
}
4.路由跳转

场景1:主应用点击主应用的侧边栏,子应用会自动切换路由

handleClick(parent, item, isInit) {
    this.vue2Url = this.$route.query.url + item.path;
    if (!isInit) {// 保持路由活性的项目才需要通知子应用
        this.handleClickPostmessage(item.path);
    }
},
handleClickPostmessage(path) {
    let str = 'iframe[name="'+this.$route.query.appDataCode+'"]';
    const subAppWindow = window.document.querySelector(str)?.contentWindow;
    const data = {
        type: this.$route.query.appDataCode + 'routerChange',
        message: path
    };
    subAppWindow.postMessage(JSON.stringify(data), '*');
}

场景2:子应用A点击子应用B

<template>
    <div class="about">
        <button @click="handleClick">去子应用B</button>
    </div>
</template>
<script>
export default {
    methods: {
        handleClick() {
            window?.$wujie.props.jump(跳转的路由, 跳转的路由携带的参数); // 这个主要是根据主应用的定义的方法来实现
        }
    }
};
</script>

场景3:子应用内容跳转路由通知父应用激活相对应路由的侧边栏

// 子应用 App.vue
watch: {
    $route() {
        window.$wujie?.bus.$emit(
            "sub-route-change", // 事件名称
            "vue2", // 主应用的路由
            this.$route.path
        );
    }
},
// 主应用
WujieVue.bus.$on("sub-route-change", (name, path) => {
    this.menu.forEach((item) => {
        if(item.path === path) {
            this.defaultActive = item.id // 这个是侧边栏激活的id
        } else if(item.children && item.children.length) {
            this.digui(item.children,path)// 递归找id
        }
    });
});

四、插件系统

1. html-loader 可以对子应 html 进行处理
plugins:[ {
    // 对子应用的html进行的内容进行修改
    htmlLoader: (code) => {
        return code.replace('test-child-base', 'vue22');
    },
  }],
2. jsIgnoresh和cssIgnores(子应用自己加载)

jsIgnores:如果用户想子应用自己加载某些js文件(通过script标签),而非框架劫持加载

css-ignores:如果用户想子应用自己加载某些`css`文件(通过`link`标签),而非框架劫持加载

plugins:[ 
    { jsIgnores: [/luckysheet\/luckysheet\.umd\.js/, /luckysheet\/plugins\/js\/plugin\.js/] },
    { cssIgnores: [
        /luckysheet\/plugins\/css\/pluginsCss\.css/,/luckysheet\/plugins\/plugins\.css/,
        /luckysheet\/css\/luckysheet\.css/, /luckysheet\/assets\/iconfont\/iconfont\.css/
    ]},
],
3. js-excludes 和 css-excludes 可以排除子应用特定的 js 和 css 加载
4. js-before-loaders、js-loader、js-after-loaders 可以方便的对子应用 js 进行自定义

js-before-loaders使用场景:
如果用户想在html中所有的js之前做:
在子应用运行一个src="http://xxxxx"的脚本
在子应用中运行一个内联的 js 脚本
执行一个回调函数

5. css-before-loaders、css-loader、css-after-loaders 可以方便的对子应用 css 进行自定义
  plugins:[
    {
        // 对css脚本动态的进行替换
        // code 为样式代码、url为样式的地址(内联样式为'')、base为子应用当前的地址
        cssLoader: (code, url, base) => {
            return code+".check-cssBeforeLoaders { background: red !important; }";
        },
    },
]

五、基础改造

1、主应用

安装命令

npm intstall wujie-vue2
//  main.js... 以下是于无界相关的主应用改造

import WujieVue from 'wujie-vue2';
const { setupApp } = WujieVue;
Vue.use(WujieVue);
const props = {
    jump: (name, query) => { // 这里是给子应用跳转到其他子应用的方法
        router.push({ name, query });
    }
};
const lifecycles = {
    beforeLoad: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeLoad 生命周期`),
    beforeMount: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeMount 生命周期`),
    afterMount: (appWindow) => console.log(`${appWindow.__WUJIE.id} afterMount 生命周期`),
    beforeUnmount: (appWindow) => console.log(`${appWindow.__WUJIE.id} beforeUnmount 生命周期`),
    afterUnmount: (appWindow) => console.log(`${appWindow.__WUJIE.id} afterUnmount 生命周期`),
    activated: (appWindow) => console.log(`${appWindow.__WUJIE.id} activated 生命周期`),
    deactivated: (appWindow) => console.log(`${appWindow.__WUJIE.id} deactivated 生命周期`),
    loadError: (url, e) => console.log(`${url} 加载失败`, e)
};

// 头部的应用数据
let appWujieData = [
    {
        name: 'test-child1-base',
        code: 'test',
        routerPath: '/vue2',
        path: 'http://localhost:8083/#'
    },
    {
        name: 'vue22',
        code: 'test1',
        routerPath: '/vue2',
        path: 'http://localhost:8087/#'
    },
    {
        name: '智能网关',
        code: 'platform-gateway',
        routerPath: '/indexOld',
        path: 'http://localhost:8082/#'
    },
    {
        name: '待办中心',
        code: 'workitem',
        routerPath: '/indexOld',
        path: 'http://localhost:8084/#'
    }
];

appWujieData.forEach((item) => {
    setupApp({
        name: item.code /** 唯一性用户必须保证 */,
        url: item.path /** 需要渲染的url */,
        exec: true /** 预执行 */,
        props /** 注入给子应用的属性 */,
        ...lifecycles,
        sandbox: {
            css: 'strict', // 启用严格样式隔离
            disableDocumentRewrite: false, // 允许DOM重写
            excludeAssetFilter: (url) => {
                return !url.includes('dynamic-module'); // 过滤特殊资源
            }
        },
        plugins: [
            {
                // 强制卸载钩子
                beforeUnmount: (app) => {
                    app.window.__WUJIE_UNMOUNT_ALL?.();
                    const shadow = app.shadowRoot;
                    while (shadow?.firstChild) {
                        shadow.firstChild.remove();
                    }
                }
            }
        ]
    });
});
2、子应用

(1)vue.config.js主要是为了解决本地调用的时候跨域问题

// vue.config.js  
module.exports  = {
    devServer: {
      port: 端口号, // 子应用端口 
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS"
      }
    }
  }

(2)main.js(以智能网关为例)

// 子应用入口文件改造
if (window.__POWERED_BY_WUJIE__) { // 子应用是否在无界的环境中
    let instance;
    if(window.$wujie.props) {
      store.commit('changePath', window.$wujie.props.serverPath ) // path.json放到主应用中请求了
    }
    window.__WUJIE_MOUNT = () => {
        instance = new Vue({
            el: '#app',
            router,
            store,
            components: { App },
            template: '<App/>'
        });
    };
    window.__WUJIE_UNMOUNT = () => {
        instance.$destroy();
    };
} else {
  axios.get('static/path.json').then(res => {
      const path = res.data
      const serverType = path.serverType;
      const GATEWAY_MAP = path.GATEWAY_MAP;
      const basePath = GATEWAY_MAP[serverType];
      const serverPath = basePath;
      store.commit('changePath', serverPath)
      new Vue({
          el: "#app",
          router,
          store,
          components: { App },
          template: "<App/>"
      });
  })


}
3、主应用接入无界组件
<!-- 这里的属性跟setupApp一致 -->
<WujieVue
    v-if="vue2Url"
    :key="`${$route.query.appDataCode}_${Date.now()}`"
    width="100%"
    height="100%"
    :alive="false"
    :exec="true"
    :name="$route.query.appDataCode"
    :props="$store.state.wujieProps"
    :url="vue2Url"
></WujieVue>
4、子应用其他改造

1. body的样式需要设置为position: relative,不然element的那些下拉弹出框位置不对

2.e.target获取的是wujie-vue了,应该使用

(e.target.shadowRoot && e.composed) ? (e.composedPath()[0] || e.target) : e.target


3.子应用的获取window

六、应用共享

// 主应用的main.js
import lodash from "lodash";

// 将需要共享的包挂载到主应用全局
window.lodash = lodash;

plugins:[{ jsBeforeLoaders: [{ content: 'window.lodash = window.parent.lodash' }]}]


//子应用

let userInfo =  window.lodash.clone(this.userInfo)
userInfo.age++

七、使用wujie-polyfill插件

npm install wujie-polyfill -S
//main.js
import { startApp } from 'wujie'
import { 
    LocationReloadPlugin, 
    EventTargetPlugin, 
    DocFullScrollPlugin 
} from "wujie-polyfill";

setupApp({
    name: '唯一id',
    url: '子应用地址',
    exec: true,
    el: '容器',
    sync: true
    plugins: [
        LocationReloadPlugin(), 
        EventTargetPlugin(), 
        DocFullScrollPlugin()
    ]
})
<template>
<div>
    <WujieVue
        width="100%"
        height="100%"
        name="xxx"
        :url="xxx"
        :plugins=“plugins”
        >
    </WujieVue>
</div>
</template>
<script lang="ts">
import WujieVue from 'wujie-vue2'
import { 
    LocationReloadPlugin, 
    EventTargetPlugin, 
    DocFullScrollPlugin 
} from "wujie-polyfill";
export default {
    name: 'micro-app',
    components: {
        WujieVue: WujieVue
    },
    data () {
        return {
            plugins: [
                LocationReloadPlugin(), 
                EventTargetPlugin(), 
                DocFullScrollPlugin()
            ]
        }
    },
}
</script>

2025开年,AI技术打得火热,正在改变前端人的职业命运:

阿里云核心业务全部接入Agent体系;

字节跳动30%前端岗位要求大模型开发能力;

腾讯、京东、百度开放招聘技术岗,80%与AI相关……

大模型正在重构技术开发范式,传统CRUD开发模式正在被AI原生应用取代!

最残忍的是,业务面临转型,领导要求用RAG优化知识库检索,你不会;带AI团队,微调大模型要准备多少数据,你不懂;想转型大模型应用开发工程师等相关岗,没项目实操经验……这不是技术焦虑,而是职业生存危机!

曾经React、Vue等热门的开发框架,已不再是就业的金钥匙。如果认为会调用API就是懂大模型、能进行二次开发,那就大错特错了。制造、医疗、金融等各行业都在加速AI应用落地,未来企业更看重能用AI大模型技术重构业务流的技术人。

如今技术圈降薪裁员频频爆发,传统岗位大批缩水,相反AI相关技术岗疯狂扩招,薪资逆势上涨150%,大厂老板们甚至开出70-100W年薪,挖掘AI大模型人才!

在这里插入图片描述

不出1年 “有AI项目开发经验”或将成为前端人投递简历的门槛。

风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!

大模型目前在人工智能领域可以说正处于一种“炙手可热”的状态,吸引了很多人的关注和兴趣,也有很多新人小白想要学习入门大模型,那么,如何入门大模型呢?

下面给大家分享一份2025最新版的大模型学习路线,帮助新人小白更系统、更快速的学习大模型!

2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享

### 无界微前端接入应用的实现方案 #### 1. 基本概念与架构设计 无界微前端是一种基于 WebComponent 容器和 iframe 沙箱的技术解决方案,旨在解决传统微前端框架中存在的诸多问题,例如适配成本高、样式隔离差以及子应用通信复杂等问题[^3]。通过将子应用注入到主应用同域的 iframe 中运行,可以充分利用 iframe 提供的天然沙箱环境,从而有效降低开发者的维护难度。 #### 2. 主应用初始化配置 为了成功接入无界微前端,首先需要完成主应用的基础配置工作。以下是具体步骤: - **安装依赖库** 需要引入无界微前端的相关 SDK 或工具包。可以通过 npm 或 yarn 进行安装: ```bash npm install @boundary/microfrontend-sdk --save ``` - **注册子应用信息** 在主应用中定义并注册各个子应用的信息,包括名称、入口 URL 和生命周期钩子函数等。以下是一个简单的代码示例: ```javascript import { registerApplication, start } from '@boundary/microfrontend-sdk'; const apps = [ { name: 'app1', entryPoint: '/path/to/app1', // 子应用路径 activeWhen: ['/app1'], // 当访问 /app1 路径时加载该子应用 }, { name: 'app2', entryPoint: '/path/to/app2', activeWhen: ['/app2'], } ]; apps.forEach(app => { registerApplication({ ...app, loadApp: ({ domElement }) => { const scriptTag = document.createElement('script'); scriptTag.src = app.entryPoint; domElement.appendChild(scriptTag); } }); }); start(); // 启动无界微前端容器 ``` #### 3. 子应用改造与部署 为了让子应用能无界微前端环境中正常运行,通常需要对其进行一定的调整: - **支持动态加载** 子应用应具备按需加载的能力,以便在被激活时快速响应用户的请求。如果使用的是现代构建工具(如 Vite),可以在项目配置文件中启用相关选项来优化资源打包过程[^4]。 - **兼容 iframe 环境** 由于子应用会被嵌套在一个独立的 iframe 内部执行,因此需要注意处理可能引发冲突的部分逻辑,比如全局变量污染或者事件监听机制的不同行为。此外还需确保路由系统的正确性——即不干扰主应用的整体导航流程[^4]。 #### 4. 解决常见挑战 尽管无界微前端提供了许多优势特性,但在实际落地过程中仍可能会遇到一些技术难点: - **跨域资源共享 (CORS)** 如果某些静态资源位于不同的服务器上,则必须妥善设置 CORS 头部字段以允许合法的数据交换操作[^1]。 - **状态同步管理** 对于多个子应用之间存在交互需求的情况,建议借助专门的状态管理库(如 Redux 或 Vuex)配合自定义的消息传递协议来进行高效协作[^2]。 --- ### 总结 综上所述,通过合理规划主应用结构布局,并按照既定规范对各子模块实施必要的升级改造措施之后,即可顺利完成整个项目的迁移过渡目标。最终达成的效果不仅能满足现阶段业务发展的多样化场景要求,而且也为未来进一步扩展预留出了充足的空间余地。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值