docs: function renderHtml(html, state, settings = {}) {
  
      // 清除settings里的空或未定义项
      for (let i in settings) {
          if (typeof settings[i] === 'undefined' || settings[i] === null)
              delete settings[i]
      }
  
      let options = Object.assign({
          // routes: {},
          // configStore: {},
          // template: '',
          distPathName: 'dist',
          distPublicPathName: 'dist',
          injection: {}
      }, settings)
  
      // return template
  
      let { template, distPathName, distPublicPathName } = options
      let injection = Object.assign({}, options.injection)
      _distPathName = distPathName
  
      // 针对非开发环境，获取打包目录下的所有文件列表
      if (!distFiles[distPathName] && !__DEV__) {
          const fs = require('fs')
          const path = require('path')
          distFiles[distPathName] = fs.readdirSync(path.resolve(distPathName, 'public/client'))
      }
  
      function filterStyle(htmlString) {
          let styleCollectionString = htmlString.replace(/\r\n/gi, '').replace(/\n/gi, '').match(/<div id="styleCollection(.*?)>(.*?)<\/div>/gi)[0]
  
          // 去掉 <div id="styleCollection">...</div>
          let onlyStyle = styleCollectionString.substr(styleCollectionString.indexOf('>') + 1, styleCollectionString.length)
          onlyStyle = onlyStyle.substr(0, onlyStyle.length - 6)
  
          return {
              html: htmlString.replace(/\n/gi, '').replace(styleCollectionString, ''),
              styles: onlyStyle
          }
      }
  
      // 样式处理
      if (typeof injection.html === 'undefined' || typeof injection.component_styles === 'undefined') {
          let htmlObj = filterStyle(html)
          if (typeof injection.html === 'undefined') injection.html = htmlObj.html
          if (typeof injection.component_styles === 'undefined') injection.component_styles = htmlObj.styles
      }
  
      // header 的 meta 生成
      if (typeof injection.meta === 'undefined')
          injection.meta = htmlExtends.meta.map((meta) => {
              let metaStr = '<meta'
              for (var key in meta) {
                  metaStr += ` ${key}="${meta[key]}"`
              }
              metaStr += '>'
              return metaStr
          }).join('')
  
      if (typeof injection.title === 'undefined')
          injection.title = htmlExtends.title || 'App Title'
  
  
      if (template === undefined) {
          template = `
              <!DOCTYPE html>
              <html lang="en">
  
              <head>
                  <meta charset="UTF-8">
                  <script>//inject_meta</script>
                  <title><script>//inject_title</script></title>
                  <script>//inject_component_styles</script>
              </head>
  
              <body>
                  <div id="root">
                      <div><script>//inject_html</script></div>
                  </div>
  
                  <script>//inject_redux_state</script>
                  <script>//inject_js</script>
  
              </body>
  
              </html>
          `
      }
  
      // 序列化的redux状态
      if (typeof injection.redux_state === 'undefined')
          injection.redux_state = `<script>window.__REDUX_STATE__ = ${JSON.stringify(state)};</script>`
  
      // 跟进环境，注入的js链接
      if (typeof injection.js === 'undefined')
          injection.js = (args) => `<script src="${args.path}/${getInjectionJsFilename('client', distPathName)}"></script>`
  
      if (typeof injection.pwa === 'undefined')
          injection.pwa = require('sp-pwa/injection').default
      if (typeof injection.pwa_filename === 'undefined')
          injection.pwa_filename = require('sp-pwa/injection-filename').default
  
      // 返回给浏览器的html
      const injection_html = injection.html
      delete injection.html
  
      let responseHtml = template
  
      for (let key in injection) {
          let value = injection[key]
          if (typeof value === 'function')
              value = value({
                  path: __DEV__ ? `http://localhost:${CLIENT_DEV_PORT}/${distPublicPathName}` : `/client`,
                  distPathName: distPathName,
                  distFiles: distFiles[distPathName]
              })
          responseHtml = responseHtml.replace(`<script>//inject_${key}</script>`, value)
      }
  
      responseHtml = responseHtml.replace(`<script>//inject_html</script>`, injection_html)
  
      return responseHtml
  }