【问题标题】:Combining Web Component Script References Within a Single File在单个文件中组合 Web 组件脚本引用
【发布时间】:2020-09-09 20:27:54
【问题描述】:

我已经成功地在我的应用程序中实现了 Web 组件,这大大减少了 index.html 文件的长度。在这一点上唯一困扰我的部分是冗长的 Web 组件脚本引用列表,如下所示:

  <script src="web-components/ScheduleManager.js"></script>
  <script src="web-components/ActionButtons.js"></script>
  <script src="web-components/DetailsPane.js"></script>
  <script src="web-components/PageHeaderLinks.js"></script>
  <script src="web-components/SideBarHeader.js"></script>
  <script src="web-components/JobsTableHeader.js"></script>
  <script src="web-components/ModuleMenus.js"></script>
  <script src="web-components/SelectDetailsPane.js"></script>
  //... more web components

我正在寻找一种简单的方法,将这些 Web 组件分组到一个单独的文件中,然后将该文件导入我的 index.html 文件中,这样我就没有那么多 &lt;script&gt; index.html 页面本身的引用,我试图保持简洁。

完成此任务的最简单方法是什么?我不需要额外的预处理。只是将这些 Web 组件分组为单个 &lt;script&gt; 引用或类似内容的简单方法。

【问题讨论】:

  • 为什么不制作一个包含所有这些脚本文件的 innerHTML 的 Web 组件呢?可能有点矫枉过正,但这是一个非常简单的解决方案。
  • 好吧,因为模块化是 Web 组件的巨大优势之一。因此,将它们存储为一种文件类型,就像我们拥有它们之前的位置一样。我只想减少 index.html 页面上脚本引用的数量。我希望通过在其他地方以一种单一的方式处理它,然后拉入一个处理它的单一文件来做到这一点。
  • 那么你想添加的脚本只有在你使用它的情况下吗?还是将它们全部添加到一个脚本中?
  • 后者:只是将它们全部添加到一个脚本中。
  • 如果你的index.html 依赖于所有这些组件(换句话说,它们都需要在你的页面真正做有意义的事情之前定义)那么最好包含(所有必需的)组件index.html 的 中的 的组件

标签: javascript html web-component


【解决方案1】:

只需将它们作为 ES 模块导入。在您的index.html 旁边创建一个文件components.js

import { ScheduleManager } from 'web-components/ScheduleManager.js';
import { ActionButtons } from 'web-components/ActionButtons.js';
import { DetailsPane } from 'web-components/DetailsPane.js';
import { PageHeaderLinks } from 'web-components/PageHeaderLinks.js';
import { SideBarHeader } from 'web-components/SideBarHeader.js';
import { JobsTableHeader } from 'web-components/JobsTableHeader.js';
import { ModuleMenus } from 'web-components/ModuleMenus.js';
import { SelectDetailsPane } from 'web-components/SelectDetailsPane.js';

在您的 webcomponents 文件中,export 类,例如:

export class ScheduleManager extends HTMLElement {

最后一步:将 HTML 中的 components.js 与 &lt;head&gt; 中的 type="module" defer 链接:

<script src="./components.js" type="module" defer></script>

【讨论】:

  • 这只需一项调整即可 - 确保还从 components.js 文件中导出文件。谢谢!
【解决方案2】:

如果您的脚本仅在遇到 html 中的某些元素时才被激活(即 SelectDetailsPane.js 仅在此页面中确实存在详细信息窗格时才有效,否则它什么也不做)您可以创建一个大脚本,也许可以缩小它,然后将其包含在每个页面中。大文件中的每个组件都必须检查实际页面是否需要它。 这将缩短你的html文档并提高你网站的速度,因为浏览器只需要一个请求就可以获取所有组件的js(下载一个大文件比下载很多小文件更快)

【讨论】:

    【解决方案3】:

    这是一个非常好用的解决方案。

    在你的 index.html 中:

    <script src="loader.js"></script>
    

    在 loader.js 中:

    const scriptSources = ["web-components/ScheduleManager.js", "web-components/ActionButtons.js", "web-components/DetailsPane.js", "web-components/PageHeaderLinks.js", "web-components/SideBarHeader.js", "web-components/JobsTableHeader.js", "web-components/ModuleMenus.js", "web-components/SelectDetailsPane.js"];
    
    for(var i = 0; i < scriptSources.length; i++) {
      let newNode = document.createElement("script");
      newNode.src = scriptSources[i];
      document.head.appendChild(newNode);
    }
    // although it may seem like we can just use += on innerHTML, that is actually disallowed in html5.
    

    这是一个例子:

    const scriptSources = new Array(3).fill("data:text/plain;charset=utf-8;base64,Y29uc29sZS5sb2coImV4ZWN1dGVkIik=");
    // The data URI above encode 'console.log("executed")'. It is just filling an array so it executes three times. You could just use a normal array of srces like shown above.
    
    for(var i = 0; i < scriptSources.length; i++) {
      let newNode = document.createElement("script");
      newNode.src = scriptSources[i];
      document.head.appendChild(newNode);
    }

    请注意,使用上述方法意味着所有这些脚本都将在执行完头部中的其他任何内容后执行。如果您的 head 中有一些依赖于先前脚本的内容:

    <head>
        <script src="loader.js"></script>
        <Component>Component Here</Component>
    </head>
    

    Component 可能有问题。要解决这个问题,您可以将loader.js 更改为以下内容:

    const script = document.currentScript;
    const scriptSources = ["web-components/ScheduleManager.js", "web-components/ActionButtons.js", "web-components/DetailsPane.js", "web-components/PageHeaderLinks.js", "web-components/SideBarHeader.js", "web-components/JobsTableHeader.js", "web-components/ModuleMenus.js", "web-components/SelectDetailsPane.js"];
    
    for(var i = 0; i < scriptSources.length; i++) {
      let newNode = document.createElement("script");
      newNode.src = scriptSources[i];
      script.parentNode.insertBefore(newNode, script.nextSibling);
    }
    

    这是上面的一个例子:

    <script>
    const script = document.currentScript;
    const scriptSources = ["data:text/plain;charset=utf-8;base64,Y2xhc3MgQ29tcG9uZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgew0KY29uc3RydWN0b3IoKSB7DQogICBzdXBlcigpOw0KdGhpcy5pbm5lckhUTUwgPSAiSXQgV29ya2VkISI7DQogIH0NCn0NCmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnY29tcC1vbmVudCcsIENvbXBvbmVudCk7"];
    // the above makes a web component that sets the innerHTML to "It Worked!"
    for(var i = 0; i < scriptSources.length; i++) {
      let newNode = document.createElement("script");
      newNode.src = scriptSources[i];
      script.parentNode.insertBefore(newNode, script.nextSibling);
    }
    </script>
    <comp-onent>It didn't work.</comp-onent>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多