合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
1.创建一个主项目,相当于是基座,在主项目里面通过hashchange或者popstate监听路由的变化,切换路由时,进行子项目activeRule的匹配,然后获取到对应的子项目的entry入口 ```js const app = apps.find(item => { return window.location.pathname.startsWith(item.activeRule) }) // 3.加载子应用 const html = await fetch(app.entry).then(res => res.text()) ``` 2.通过entry入口,获取子应用的html,通过innerHTML放到基座的container容器中,这里的获取方式是通过fetch请求方法 ```js const html = await fetch(app.entry).then(res => res.text()) const container = document.querySelector(app.container) container.innerHTML = html ``` 3.获取script标签,核心代码 1.获取template中所有的script标签,如果script标签存在src属性,说明请求的是一个js,那么把这个地址存到promise.all里面,如果没有src属性,说明是一段立即执行的script代码,那么拿到script标签innerHTML里的内容 2. 由于将src的请求执行时是通过fetch方式,所以如果是jsonp跨域请求,会获取不到 ```js // 获取所有的 script 节点 const scripts = template.querySelectorAll('script') // 获取所有的 script 标签 function getExternalScripts() { console.log(Array.from(scripts), 1111) const scriptsArr = Array.from(scripts).map(script => { const src = script.getAttribute('src') if (!src) { return Promise.resolve(script.innerHTML) } else { let srcUrl = src.startsWith('http') ? src : `${url}/${src}` return fetchResource(srcUrl) } }) return Promise.all(scriptsArr) } ``` 4.提供全局变量,子应用可以根据这个来选择是独立渲染,还是挂载到基座上 ```js // 配置全局环境变量 window.__POWERED_BY_QIANKUN__ = true ``` 5.子应用里打包导出的格式要设置成umd格式,目的是为了兼容不同的模块规范,打包的结果是一个立即执行函数,会执行子应用的代码,将结果返回到window上(umd规范会判断兼容哪一种) ```js // node commonJs模块规范 if (typeof exports === 'object' && typeof module === 'object') { module.exports = factory() } // amd 模块规范 else if (typeof define === 'funciton' && define.amd) define([], factory) // commonjs es6的 import 规范 else if (typeof exports === 'object') // 如果都不是就是在window上 else ``` 6.手动构造了一个commonJS环境 ```js // 手动构造一个commonJs模块环境 const module = { exports: {} } const exports = module.exports scripts.forEach(code => { // eval上的代码可以访问外部变量 eval(code) }) console.log(module.exports) // 拿到了子应用内部的导出 ```