待处理

113 阅读2分钟

github.com/Tencent/wuj…

github.com/fengshi123/…

【有道云笔记】微前端 note.youdao.com/s/1Nzooipm

github.com/webfansplz/…

juejin.cn/post/730383…

juejin.cn/post/730383…

juejin.cn/post/684490…

github.com/madcodelife…

const express = require("express"); const path = require("path");

const router = express.Router(); console.log("aaa: ", path.join(__dirname, "./")); router.use(express.static(path.join(__dirname, "./"))); router.get("/*", (req, res) => { console.log("index", req.url); res.sendFile(path.join(__dirname, req.url.split("/").slice(2).join("/"))); });

const app = express(); app.use(router); app.listen(3001, () => { console.log("server is running on port 3001"); });

Document
基座的代码,不被子应用的样式所污染
<!-- 加载子应用的div -->
<div id="container"></div>
<!-- 
    以前我们的js都是放到沙箱(自己实现的)中跑的  -> iframe
    我们的css隔离 (scopedCSS) -> webComponent(shadowRoot)
    渲染采用webComponent (拉取html模板 生成自定义组件插入到指定的dom种)
 -->

 <script>
    const strTmpWithCSS = `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="inner">hello jw</div>
        <style>
            div{background:red;color:#fff}
         </style>
    </body>
    </html>
    `
    const strScript = `
        window.a = 100; // 此属性不会影响父应用
        console.log(window.a); // 100
        const ele = document.querySelector('#inner')
        console.log(ele);
    `

    function createIframe(){
        const iframe = document.createElement('iframe');
        iframe.src = 'about:blank'
        document.body.appendChild(iframe);
        return iframe
    }

    function createSandbox(){
        const sandbox = {
            iframe:createIframe(), // 创建了一个iframe沙箱
            shadowRoot:null
        }
        return sandbox
    }
    function injectTemplate(sandbox,template){
        const wrapper =  document.createElement('div');
        wrapper.innerHTML = template;
        sandbox.shadowRoot.appendChild(wrapper)
    }
    
    function runScirptInSandbox(sandbox,script){
        const iframeWindow = sandbox.iframe.contentWindow;
        const scriptElement = iframeWindow.document.createElement('script');

        // 获取head 将script插入进去
        const headElement = iframeWindow.document.querySelector('head');


        // 我们希望在脚本执行之前,有些方法用的是父应用的
        // document.querySelector 应该用的不是iframe中的 -》 shadowRoot 去弄
        // 添加弹框的时候 document.createElement().appendChild() -> 代理到全局的window上去

        // iframe中的路由管理  history.pushState -> 将一些常用方法进行同步到主应用
        // ......
        Object.defineProperty(iframeWindow.Document.prototype, 'querySelector',{
            get(){
               // 加载的脚本内部调用了querySelector
               // document.querySeletor('abc')  -> sandbox.shadowRoot['querySelector']
               return new Proxy(sandbox.shadowRoot['querySelector'],{
                    apply(target,thisArgs,args){
                        return thisArgs.querySelector.apply(sandbox.shadowRoot,args)
                    }
               })
            }
        })
        scriptElement.textContent = script;
        headElement.appendChild(scriptElement)
    }
    function createCustomElement(){
        class WujieApp extends HTMLElement{
            connectedCallback(){
                // 1)创建沙箱
                const sandbox = createSandbox();
                // 2)创建shadowdDOM
                sandbox.shadowRoot = this.attachShadow({mode:'open'})
                // 3)将html、css放入到shadowdDOM
                injectTemplate(sandbox,strTmpWithCSS)
                // 4)将js放入沙箱执行
                runScirptInSandbox(sandbox,strScript)
            }
        }
        window.customElements.define('wujie-app',WujieApp);
        container.appendChild(document.createElement('wujie-app'))
    }
    // 定义一个组件来使用
    createCustomElement()
  


 </script>

笔记

  • shadowDom 里面不能是 script标签,闭合标签会和上面的父script 标签闭合;

  • puppeteer 安装失败

  •  

    报错信息:

    ...
    ERROR: Failed to set up Chromium r563942! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.
    Error: Download failed: server returned code 404. URL: https://mirrors.tools.huawei.com/chromium-browser-snapshots/Win_x64/563942/chrome-win32.zip
    ...
    
  •  

    报错原因:你的电脑中其他配置指定了 chrome-win32.zip 这个包的版本号为 563942,而这个版本比较老了,华为镜像仓上没有这个版本的资源。

    注:上面的错误信息也有可能不是 563942 版本,但原因是一样的,就是没找到指定版本的资源。

  •  

    解决方案:由于该npm 包是 微组件测试功能所依赖的,所以可以分两种情况来对其进行处理,一种情况是你不使用 微组件测试功能,另一种情况是你使用 微组件测试功能。

    •  

      不使用测试功能。可以通过跳过该依赖的安装来解决,在工程的 .yarnrc 和 .npmrc 中修改下面配置:

      // .yarnrc
      -  puppeteer_skip_chromium_download false
      +  puppeteer_skip_chromium_download true
      
      // .npmrc
      -  puppeteer_skip_chromium_download=false
      +  puppeteer_skip_chromium_download=true
      
    •  

      使用测试功能。将指定版本号的配置设置为空,让其下载最新版本的 chrome-win32.zip 包。在工程根目录的 .yarnrc 和 .npmrc 中分别新增下面配置:

      // .yarnrc
      PUPPETEER_CHROMIUM_REVISION ""
      
      // .npmrc
      PUPPETEER_CHROMIUM_REVISION=