从清单 json 中动态更新 href/src 属性

dynamically update href/src attributes from manifest json

我正在通过读取 manifest.json 文件动态更新 html src/href 属性。

但我很确定我这样做的方式没有遵循最佳实践。我找不到关于这个主题的任何内容。

为了更新我的 html 中的链接,阅读我的 manifest.json 的理想方式是什么?

我的工作:

  <link id="maincss" rel="stylesheet">
</head>
<body>
  <script id="mainscript"></script>
  <script>
    function readTextFile(file, callback) {
        var rawFile = new XMLHttpRequest();
        rawFile.overrideMimeType("application/json");
        rawFile.open("GET", file, true);
        rawFile.onreadystatechange = function() {
            if (rawFile.readyState === 4 && rawFile.status == "200") {
                callback(rawFile.responseText);
            }
        }
        rawFile.send(null);
    }

    readTextFile("/dist/manifest.json", function(text){
        var data = JSON.parse(text);
        document.getElementById('mainscript').setAttribute('src', '/dist/'+data.main[1]);
        document.getElementById('maincss').setAttribute('href', '/dist/'+data.main[0]);
    });
  </script>

您可以看到,一旦我读取文件,我就为 javascript 设置了 src 属性,为 css.

设置了 href 属性

我的manifest.json:

{"main":["mycss.798d79ab87daa2i3df123.css","main.f8aaae15e396b637e82e.js"]}

您似乎在尝试将 JavaScript 和 CSS 外部化,这样您就可以在您的应用之外更改它们,而无需进行重新部署(或类似的操作)。

我认为这个用例有更简洁的解决方案,但考虑到您的设置,我只是稍微清理一下并使其更灵活一些。

我要解决的第一件事是:

<link id="maincss" rel="stylesheet"> document.getElementById('maincss').setAttribute('href', '/dist/'+data.main[0]);

这可能不是问题,但这实际上只是将您锁定到一个 css 文件。如果您需要添加另一个文件怎么办?或者可能是不同的文件类型(如字体样式)。

话虽如此,我会完全放弃占位符元素。显然,您引用占位符的方式(mainscript,maincss)也会被抛弃。

对于初学者,我会重构您的 json 文件以使其更具可扩展性,然后,我基本上会创建一个 "mini module loader"

我会这样做:

// Fake HTTP Get that returns your manifest file
const fakeGetRequest = () => {
  return [{
      "type": "link",
      "src": "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css",
    },
    {
      "type": "script",
      "src": "https://code.jquery.com/jquery-3.3.1.slim.min.js"
    }
  ];
}

// Helper function to centralize the creation of the reference tag
const createRef = (src, type) => {
  switch (type) {
    case 'script':
      const script = document.createElement('script');
      script.src = src;
      return script;
    case 'link':
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.href = src;
      return link;
  }
  return null;
}

// Your manifest.json
const manifest = fakeGetRequest();

// Iterate over your manifest and append things where you want them
manifest.forEach(item => {
  const ref = createRef(item.src, item.type);
  switch (item.type) {
    case 'link':
      document.head.appendChild(ref);
      break;
    case 'script':
      document.body.appendChild(ref);
      break;
  }
});

这将使您能够添加任意数量的 script/css 引用,并且您的代码将知道如何始终附加它们,无论您想要附加多少。由于您的清单文件现在是可配置的,并且您的页面中有代码知道如何将其翻译成有意义的东西,支持不同的文件类型,例如图像或您想要放入的任何其他文件,因此将该类型添加到您的代码中是一个问题所以它知道如何处理它。

我在清单中只有两个属性(srctype),但实际上,您可能需要类似 order 的东西(也许有一个需要先引用的依赖项), 另一个 属性 如果你想把它附加到 headbody, 等等...

说来话长,我觉得你的东西很好,真的没有太多需要改进的地方。您唯一可以显着改进的是可伸缩性(如果需要)。