在单个文件中合并 Web 组件脚本引用
Combining Web Component Script References Within a Single File
我已经成功地在我的应用程序中实现了 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 文件中,这样我就没有那么多这些 <script>
在 index.html 页面本身的引用,我尽量保持简洁。
完成此任务的最简单方法是什么?我不需要额外的预处理。只是一种将这些 Web 组件组合成单个 <script>
引用或类似内容的简单方法。
如果您的脚本仅在满足 html 中的某些元素时才被激活(即 SelectDetailsPane.js 仅在该页面中确实存在详细信息窗格时才起作用,否则它什么都不做)您可以创建一个大脚本,也许将其缩小,然后将其包含在每个页面中。大文件中的每个组件都必须检查实际页面是否需要它。
这将缩短您的 html 文件并提高您网站的速度,因为浏览器只需要一个请求就可以获取所有组件的 js(下载一个大文件比下载许多小文件要快)
这是一个非常好用的解决方案。
在你的 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
中以前的脚本:
<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>
只需将它们作为 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 {
最后一步:Link HTML 中的 components.js 和 <head>
中的 type="module"
:
<script src="./components.js" type="module"></script>
我已经成功地在我的应用程序中实现了 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 文件中,这样我就没有那么多这些 <script>
在 index.html 页面本身的引用,我尽量保持简洁。
完成此任务的最简单方法是什么?我不需要额外的预处理。只是一种将这些 Web 组件组合成单个 <script>
引用或类似内容的简单方法。
如果您的脚本仅在满足 html 中的某些元素时才被激活(即 SelectDetailsPane.js 仅在该页面中确实存在详细信息窗格时才起作用,否则它什么都不做)您可以创建一个大脚本,也许将其缩小,然后将其包含在每个页面中。大文件中的每个组件都必须检查实际页面是否需要它。 这将缩短您的 html 文件并提高您网站的速度,因为浏览器只需要一个请求就可以获取所有组件的 js(下载一个大文件比下载许多小文件要快)
这是一个非常好用的解决方案。
在你的 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
中以前的脚本:
<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>
只需将它们作为 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 {
最后一步:Link HTML 中的 components.js 和 <head>
中的 type="module"
:
<script src="./components.js" type="module"></script>