【问题标题】:Vanilla WebComponents approaches: is there any real difference between "importing js from html" and "fetching html from js" fileVanilla WebComponents 方法:“从 html 导入 js”和“从 js 获取 html”文件之间有什么真正的区别
【发布时间】:2019-08-06 15:56:50
【问题描述】:

上下文:直到现在我都不介意如何将模板 html 文件导入我的香草 web 组件,因为我总是编写小的 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 分开,假设这将使我的项目树更清晰。

四处搜索我发现了一些讨论,假设浏览器将不再支持“导入”[(请参阅底部关于导入替代方案的更新讨论)]。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 是否有一些真正的优势。所以我的直截了当的问题是:“在编码 Vanilla Web 组件时导入”和“获取” html 文件,该文件预计将由支持本机 Web 组件的浏览器(例如 Chrome)直接呈现?

【问题讨论】:

  • 在谈论 Web 组件时,您确实希望将组件的 DOM 代码与 JS 紧密绑定,因为 Web 组件不是“JS”,而是“JS + (shadow) DOM它需要呈现自己”。无论您是通过 html 模板字符串还是基于 JS 的 DOM 构建来实现这一点,都取决于您,但要将所有内容放在一起。请记住,Web 组件应该附带,而且 附带呈现自身 所需的代码,仅此而已:子组件正确渲染是每个子组件的责任。
  • 我完全同意“你的组件的 DOM 代码与 JS 紧密相关”。我有兴趣分成两个文件,一个 html 和另一个 javascript,因为我相信从开发人员的角度来看它会更友好和更容易组织。我不打算重新使用与 html 分离的 javascript 文件。两者都将相互编码。顺便说一句,我的问题集中在两种方法上,以及它们是否比另一种更具优势。也许可能会建议第三种替代方案并且也很受欢迎。
  • 这感觉像是一种虚假的节省:获得一个好的代码编辑器或专用的 IDE,并将您的自定义组件代码保存在一个具有易于浏览结构的文件中。多个文件只是通过不链接正确的文件来无限容易地破坏您的自定义组件,甚至不需要链接。
  • 感谢您分享不将 js 与 html 分开的偏好。顺便说一句,我的主要问题是开放的。

标签: javascript html dom web-component native-web-component


【解决方案1】:

如果您不打算在各种页面中使用自定义元素,那么这两种解决方案都不错。

在第一个中它可能会更快,因为您将保存一个 HTTP 请求,因为 HTML 模板在主 HTML 页面中立即可用。

但如果您打算重用自定义元素(或为了更好的代码分离),第二种解决方案会更好,因为消费者与 Web 组件是分离的。

【讨论】:

  • 很好的解释。那么支持 nativa webcomponent 的浏览器移除 html 导入功能呢?您是否像几年前提到的文章一样意识到这一点?
  • 如果你有信心我不应该担心浏览器会删除“导入”而不是你肯定回答了我的问题
  • @JimC 抱歉,我不明白您想在第一个解决方案中使用 HTML 导入。我认为您想在主文件中包含
  • 不用担心。你基本上是说我应该更喜欢选项 2。
【解决方案2】:

您可以随时查看捆绑程序/打包程序。 Webpack 和其他人工作得很好。

我专门为 Web 组件编写了这个: https://www.npmjs.com/package/component-build-tools

它允许零个或多个模板作为真正的 HTML 文件,如果你想本地化你的组件,它还允许导入基于区域设置的字符串。

它还允许您使用 ES6 导入编写组件,然后在需要时交叉编译为 ES5,并允许输出为 ES6 模块文件、CJS 文件或简单的 IIFE 文件。

【讨论】:

  • 虽然不是直截了当我的问题标题,但我发现您的回答非常有用。我正在看这个。您的组件构建工具是为单元测试和集成测试设计的吗?我真的很怀念一些为具有测试强度的普通 web 组件编码的开源代码。在这个论坛中,您可能会发现我提出的几个问题以某种方式围绕着这个想法。特别是使用 Karma + Jasmine 时,当我们想到 weebcomponets 时,似乎有些桥梁不清楚。你可能会对我昨天的问题stackoverflow.com/questions/57384762/…感兴趣
  • 当我写这篇文章时,我将大部分逻辑放在单独的文件中,然后导入它们。这些文件中的每一个都可以导入 Karma 并进行测试。最好的一点是,通过创建这些小的、可重用的文件并在需要的地方导入它们,我大大减少了重复代码。为了测试整个组件,我还使用了 Karma 并仅测试了该组件的特定功能。
  • 我正在尝试将一个简单的 Vanilla Webcomponet 分成两个文件(html 与 javascript 分离)并使用 Karma 对其进行测试,但我不断收到“[web-server]: 404: stackoverflow.com/questions/57384762/….我创建了一个名为 to-try 的文件夹,其中包含 3 个 Web 组件:(1) js 和 html 在同一个文件中,(2) js 获取 html 文件和另一个 (3) html 导入 js。只有暂定的 1,业力测试运行而不会抱怨未定义的变量。 github.com/jimisdrpc/skyscanner-webcomponents。如果您能看到,非常感谢!
猜你喜欢
  • 2017-04-08
  • 2018-04-06
  • 2014-10-20
  • 2017-12-29
  • 2015-03-09
  • 1970-01-01
  • 2017-09-28
  • 2019-09-23
  • 2014-06-04
相关资源
最近更新 更多