Vanilla WebComponents 方法:"importing js from html" 和 "fetching html from js" 文件之间有什么真正的区别吗
Vanilla WebComponents approaches: is there any real difference between "importing js from html" and "fetching html from js" file
上下文:直到现在我都不介意如何将模板 html 文件导入我的 vanilla webcomponent,因为我总是写小 html 代码。所以我在我的 webcomponent .js 文件之上编码了 html 并做了类似的事情:
const template = document.createElement("template");
template.innerHTML = `<div id="firstdiv"><input id="inputAny"/></div>`;
class anyVanillaWebComponent extends HTMLElement {
...
connectedCallback() {
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
const inputAny = this.shadowRoot.getElementById("inputAny");
...
这在教程、博客和论坛中很常见。现在我想将 html 与 javascript 分开,假设这将使我的项目树更加清晰。
四处搜索,我发现了一些基于浏览器不再支持 "import" 的假设的讨论 [(请参阅底部关于导入替代方案的更新讨论)]。1
基本上这让我想到了两种可能性:
1 - 将 .js 文件从 html 导入到 html
举例:
<template id="my-webcomponent-template">
<link rel="stylesheet" href="./some.css">
<div>some content ...</div>
</template>
<script src="MyWebcomponent.js"></script>
2 - 从 .js 文件
异步获取 my-webcomponent.html
(async () => {
const res = await fetch('/MyWebcomponent.html');
const textTemplate = await res.text();
const HTMLTemplate = new DOMParser().parseFromString(textTemplate, 'text/html')
.querySelector('template');
class MyWebcomponent extends HTMLElement {...
基于 2017 年的此类讨论,我似乎应该避免选择选项 1,但我不清楚选项 2 为什么以及是否有一些真正的优势。所以我的直接问题是:是否有任何真正的区别在 "importing" 和 "fetching" html 文件之间编码 Vanilla Webcomponents 预计将由支持本机 Webcomponents 的浏览器直接呈现(例如,Chrome)?
如果您不打算在各种页面中使用您的自定义元素,那么这两种解决方案都不错。
第一个可能会更快,因为您将保存一个 HTTP 请求,因为 HTML 模板在主 HTML 页面中立即可用。
但如果您打算重用自定义元素(或为了更好的代码分离),第二种解决方案更好,因为消费者与 Web 组件分离。
你总能看到一个bundler/packager。 Webpack 和其他人工作得很好。
我专门为 Web 组件编写了这个:
https://www.npmjs.com/package/component-build-tools
它允许零个或多个模板作为真正的 HTML 文件,并且如果您想本地化您的组件,则允许导入基于区域设置的字符串。
它还允许您使用 ES6 导入编写组件,然后在需要时交叉编译为 ES5,并允许输出为 ES6 模块文件、CJS 文件或简单的 IIFE 文件。
上下文:直到现在我都不介意如何将模板 html 文件导入我的 vanilla webcomponent,因为我总是写小 html 代码。所以我在我的 webcomponent .js 文件之上编码了 html 并做了类似的事情:
const template = document.createElement("template");
template.innerHTML = `<div id="firstdiv"><input id="inputAny"/></div>`;
class anyVanillaWebComponent extends HTMLElement {
...
connectedCallback() {
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
const inputAny = this.shadowRoot.getElementById("inputAny");
...
这在教程、博客和论坛中很常见。现在我想将 html 与 javascript 分开,假设这将使我的项目树更加清晰。
四处搜索,我发现了一些基于浏览器不再支持 "import" 的假设的讨论 [(请参阅底部关于导入替代方案的更新讨论)]。1
基本上这让我想到了两种可能性:
1 - 将 .js 文件从 html 导入到 html 举例:
<template id="my-webcomponent-template">
<link rel="stylesheet" href="./some.css">
<div>some content ...</div>
</template>
<script src="MyWebcomponent.js"></script>
2 - 从 .js 文件
异步获取 my-webcomponent.html(async () => {
const res = await fetch('/MyWebcomponent.html');
const textTemplate = await res.text();
const HTMLTemplate = new DOMParser().parseFromString(textTemplate, 'text/html')
.querySelector('template');
class MyWebcomponent extends HTMLElement {...
基于 2017 年的此类讨论,我似乎应该避免选择选项 1,但我不清楚选项 2 为什么以及是否有一些真正的优势。所以我的直接问题是:是否有任何真正的区别在 "importing" 和 "fetching" html 文件之间编码 Vanilla Webcomponents 预计将由支持本机 Webcomponents 的浏览器直接呈现(例如,Chrome)?
如果您不打算在各种页面中使用您的自定义元素,那么这两种解决方案都不错。
第一个可能会更快,因为您将保存一个 HTTP 请求,因为 HTML 模板在主 HTML 页面中立即可用。
但如果您打算重用自定义元素(或为了更好的代码分离),第二种解决方案更好,因为消费者与 Web 组件分离。
你总能看到一个bundler/packager。 Webpack 和其他人工作得很好。
我专门为 Web 组件编写了这个: https://www.npmjs.com/package/component-build-tools
它允许零个或多个模板作为真正的 HTML 文件,并且如果您想本地化您的组件,则允许导入基于区域设置的字符串。
它还允许您使用 ES6 导入编写组件,然后在需要时交叉编译为 ES5,并允许输出为 ES6 模块文件、CJS 文件或简单的 IIFE 文件。