Skip to content
一、加载和解析js

因为一般现在前端的页面大多都不是静态页面,而是动态页面,一个页面的渲染完成,不止是只有 html 部分,还有逻辑处理的 js 和 使页面变得精美的 css。

  • main/micro/loader/index.js 中添加 getResources

    javascript
     /**
      * 获取 js
      * @param root
      * @param entry
      * @return {Promise<(string|*[])[]>}
      */
      export const getResources = async (root, entry) => {
          const scriptUrl = []
          const script = []
          const dom = root.outerHTML
          function deepParse (element) {
              const children = element.children
              const parent = element.parent
            
              // 第一步处理位于 script 中的内容
              if (element.nodeName.toLowerCase() === 'script') {
                  const src = element.getAttribute('src')
                  if (!src) {
                      script.push(element.outerHTML)
                  } else {
                      if (src.startsWith('http')) {
                          scriptUrl.push(src)
                      } else {
                          scriptUrl.push(`http:${entry}/${src}`)
                      }
                  }
                  if (parent) {
                      parent.replaceChild(document.createElement('此 js 文件已经被微前端替换'), element)
                  }
              }
              // link 也会有js 内容
              if (element.nodeName.toLowerCase() === 'link') {
                  const href = element.getAttribute('href')
                  if (href.endsWith('.js')) {
                      if (href.startsWith('http')) {
                          scriptUrl.push(href)
                      } else {
                          scriptUrl.push(`http:${entry}/${href}`)
                      }
                  }
              }
            
              for (let i = 0; i < children.length; i++) {
                  deepParse(children[i])
              }
          }
          deepParse(root)
          return [dom, scriptUrl, script]
      }
  • main/micro/loader/index.jsparseHtml 调用

    javascript
    export const parseHtml = async (entry) => {
      // axios ajax fetch
      const html = await fetchResource(entry)
      const div = document.createElement('div')
      div.innerHTML = html
      let allScript = []
      // 标签、link、script
      const [dom, scriptUrl, script] = await getResources(div, entry)
      const fetchedScript = await Promise.all(scriptUrl.map(async item => fetchResource(item)))
      allScript = script.concat(fetchedScript)
      return [dom, allScript]
    }
  • js 执行

    • 创建 main/micro/sandbox/performScript.js

      javascript
       /**
        * 执行js脚本 方式一
        * @param script
        */
        export const performScriptForFunction = (script) => {
            new Function(script).call(window, window)
        }
        
       /**
        * 执行js脚本 方式二
        * @param script
        */
        export const performScriptForEval = (script) => {
            eval(script)
        }
    • main/micro/loader/index.js 中的 loadHtml 方法执行调用

      javascript
      import { performScriptForFunction } from '../sandbox/performScript'
      
       /**
        * 加载html方法
        */
        export const loadHtml = async (app) => {
            // 1. 子应用需要显示在哪里
            const container = app.container
            // 2. 子应用的入口
            const entry = app.entry
            const [dom, scripts] = await parseHtml(entry)
            const ct = document.querySelector(container)
            if (!ct) {
                throw new Error('容器不存在,请查看')
            }
            ct.innerHTML = dom
            scripts.forEach(item => {
                performScriptForFunction(item)
            })
            return app
        }

Released under the MIT License.