在多个项目中重复使用一个组件的需要在我身上发生过好几次了。解决方案?复制粘贴组件并将其带到需要它的项目中,并可能进行一些调整以使其工作。它会响铃吗?

原文:Create WebComponents with StencilJS and use them in different projects

当相关组件(例如按钮)从一个 React 项目转移到另一个 React 项目时,也许这对你有用,但是......如果一个项目来自 React、另一个来自 Angular 或另一个来自 Vue,你会怎么做?有必要为每个项目重新制作该按钮。也就是说,您将执行相同的功能三次。听起来不太好,是吗? 💩

好吧,如果您对这种情况感到认同,我很高兴我不是唯一一个。

如果我们只制作一次相同的按钮并将其用于我们的项目,您觉得如何?来吧,让我们开始吧。

目录

  • 简介

  • 什么是 StencilJS?

  • 使用 StencilJS 创建项目

  • 使用 StencilJS 创建可重用的按钮组件

  • 将 CSS 样式添加到 Web 组件

  • 如何查看使用 Stencil 创建的 Web 组件?

  • 生成分布

  • 在 Github 包中分发我们的 webcomponent

  • 使用 React 集成到项目中

  • 用Vue集成到一个项目中

  • 结论

简介

在本文中,我们将通过一个实际示例来了解如何使用 StencilJS(上面提到的按钮)实现一个组件,我们将在 Github 上将其发布为package,然后将其集成到我们的应用程序中,我们将进行集成在 Vue 中进行测试,在 React 中进行测试。听起来不错?到乱七八糟!

什么是 StencilJS?

StencilJS是Ionic的创建者的工具,他们将其定义为“可重用 Web 组件的神奇生成器”。换句话说,StencilJS 允许您轻松创建本地 Web 组件,而无需付出太多努力。

用StencilJS创建项目

显然,我们要做的第一件事就是创建项目,非常简单:

npm init stencil

进入全屏模式 退出全屏模式

它会自动询问我们它是什么类型的项目:

[Stencil 项目类型](https://res.cloudinary.com/practicaldev/image/fetch/s--G8E8AjaY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas.com /blog/webcomponents-stenciljs/project_type.jpg)

我们为项目类型提供了三个选项。我们将选择选项component,因为我们要创建的是组件集合。作为项目的名称,我们将输入custom-components-stencil(例如):

[项目安装确认与 Stencil](https://res.cloudinary.com/practicaldev/image/fetch/s--0_R6f9N6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas .com/blog/webcomponents-stenciljs/confirmacion_inicio_proyecto_stencil.jpg)

完美,我们已经用 Stencil 🚀 创建了我们的第一个项目,现在我们用我们最喜欢的 IDE 打开项目并开始:

cd custom-components-stencil
npm install
npm start

进入全屏模式 退出全屏模式

[安装依赖并运行项目](https://res.cloudinary.com/practicaldev/image/fetch/s--ao5Mk2uG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// alextomas.com/blog/webcomponents-stenciljs/install_stencil_dependencies.jpg)

好吧,一旦项目启动,它会告诉我们运行示例的 URL,在我的例子中是http://localhost:3333/,我们将在其中看到 StencilJS 默认为我们提供的基本示例。

使用 StencilJS 创建可重用的按钮组件

至此,我们已经安装了我们的第一个 StencilJS 项目。现在我们将创建我们的第一个可重用按钮类型的 web 组件。

首先,我们将查看src/index.html文件,我们将在其中看到 Stencil 已经为我们提供了一个使用名为my-component的组件的示例,请查看src/components/my-component文件夹,这是定义它的位置。基本上它是一个 div 接收三个道具(第一个,中间,最后一个)并将它们绘制在屏幕上。

好的,让我们创建我们的组件。我们将遵循以下步骤:

  1. 我们在src中创建一个文件夹,我们将其命名为at-button(来自 Alex Tomás 😜)

  2. src/components/at-button中,我们创建一个 .tsx 格式的文件,我们将其命名为at-button.tsx并添加以下内容:

import { Component, Prop, h } from '@stencil/core';

@Component({
    tag: 'at-button',
    styleUrl: 'at-button.css',
    shadow: true,
})
export class ATButton {
    @Prop() text: string;

    render() {
        return <button class='button'>{this.text}</button>;
    }
}

进入全屏模式 退出全屏模式

好吧,这有很多事情,但不要惊慌。让我们看看组件的组成部分是什么:

  • 装饰器@Component是我们指定组件名称及其样式文件的地方。

  • @Proptext 将成为我们将发送给组件的属性。这些默认属性在组件内是不可变的。要使它们可变,您必须使用@Prop({ mutable: true })对它们进行注释,但情况并非如此。

  • render方法,返回绘制组件所需的描述。正如您将看到的,我们使用 JSX 语法。如果您不了解 JSX,请转到解释JSX 是什么的 React 文档链接。

记得在src/components/at-button/at-button.css中创建样式文件

将 CSS 样式添加到 Web 组件

很容易。通过在@Component装饰器中添加 CSS 文件的名称,我们添加了我们想要的类。在我们的例子中,我们将类button添加到我们的按钮中。因此,我们为其添加了基本样式(请记住,我们正在学习 Web 组件的功能,而不是美学🙃):

.button {
    background-color: teal;
    border-radius: 30px;
    border: none;
    box-shadow: 2px 2px 9px 2px rgba(0, 0, 0, 0.28);
    cursor: pointer;
    padding: 10px 30px;
    color: white;
}
.button:hover {
    background-color: rgb(0, 146, 146);
}

进入全屏模式 退出全屏模式

好的,完美。我们在什么时候?

  1. 我们已经用 Stencil 启动了这个项目。

  2. 我们创建了一个名为at-button的 web 组件。

  3. 我们为您提供了 CSS 样式。

现在我怎么能看到它?

如何查看使用 Stencil 创建的 Web 组件?

请记住,在文章的开头,在创建项目时,我们使用命令npm run startnpm start在浏览器中查看项目。好的,但首先我们要编辑文件src/index.html,我们将其保留如下:

<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset="utf-8" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
        />
        <title>Stencil Component Starter</title>

        <script
            type="module"
            src="/build/custom-components-stencil.esm.js"
        ></script>
        <script nomodule src="/build/custom-components-stencil.js"></script>
    </head>
    <body>
        <at-button text="¡Hola mundo!"></at-button>
    </body>
</html>

进入全屏模式 退出全屏模式

如果我们访问 Stencil 在启动项目时告诉我们的 localhost,我们应该会看到我们的按钮:

[Webcomponent Hello World](https://res.cloudinary.com/practicaldev/image/fetch/s--ek_GzDrv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas.com /blog/webcomponents-stenciljs/hello_world_button_stencil.jpg)

生成分布

现在你已经用 StencilJS 创建了你的第一个 web 组件!我们将如何在其他项目中使用它?我们要做的第一件事是编译所有内容:

npm run build

进入全屏模式 退出全屏模式

什么应该生成文件夹distloader。完美,我们将在 Github 中创建我们的package

在 Github 包中分发我们的 webcomponent

我们需要的第一件事是创建一个存储库,如果您还没有创建一个,那么就这样做(我不会详述如何创建一个存储库并将更改上传到它,因为这不是主题这篇文章😌)。

在我的情况下,该项目将在以下 URL 公开:https://github.com/alextomas80/stencil-webcomponents

完美的。我已经将我的项目编译并上传到 Github。现在我们要创建我们的包。

在Github上生成token创建包

这里有一个小魔法。我们需要的第一件事是一个名为.npmrc的文件,我们将在其中添加以下内容:

//npm.pkg.github.com/:_authToken=TU_TOKEN
registry=https://npm.pkg.github.com/USUARIO

进入全屏模式 退出全屏模式

就我而言,它将是:

//npm.pkg.github.com/:_authToken=d7a031caf35....🤫
registry=https://npm.pkg.github.com/alextomas80

进入全屏模式 退出全屏模式

要创建令牌以将包发布到您的存储库,您需要访问 Github 上的设置 > 开发人员设置 > 个人访问令牌。

[在 Github 上创建个人令牌](https://res.cloudinary.com/practicaldev/image/fetch/s--4Tp5nhTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// alextomas.com/blog/webcomponents-stenciljs/crear_token_personal_github.jpg)

我们需要对我们的package.json进行更改:

{
    "name": "custom-components-stencil"
}

进入全屏模式 退出全屏模式

我们将为您提供给存储库的用户和名称更改它,在我的情况下,如下所示:

{
    "name": "@alextomas80/stencil-webcomponents"
}

进入全屏模式 退出全屏模式

好吧,我们已经准备好了,现在可以,将我们的包裹发送到 Github 🤞🏻

npm publish --access public

进入全屏模式 退出全屏模式

我们应该得到类似这样的响应:

[包subido一个Github](https://res.cloudinary.com/practicaldev/image/fetch/s--LG9BmR69--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas. com/blog/webcomponents-stenciljs/subir_package_github.jpg)

是的!现在是的!您已成功创建包。如何检查?访问以packages结尾的存储库的 URL:https://github.com/alextomas80/stencil-webcomponents/packages

[包subido一个Github](https://res.cloudinary.com/practicaldev/image/fetch/s--eJ1c8aki--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas. com/blog/webcomponents-stenciljs/listado_de_packages_github.jpg)

使用 React 集成到项目中

是时候看看这一切都起到了作用并且奏效了。我们将在一个项目中使用我们的 webcomponentat-button,我们将通过快速反应创建该项目。我不会花太多时间在这上面:

让我们创建我们的示例项目:

npx create-react-app test-with-react

进入全屏模式 退出全屏模式

我们启动项目,我们将看到典型的 React 欢迎屏幕:

npm run start

进入全屏模式 退出全屏模式

[反应闪屏](https://res.cloudinary.com/practicaldev/image/fetch/s--ab6K4CQW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas.com /blog/webcomponents-stenciljs/welcome_react.jpg)

现在让我们用我们的 webcomponent 安装我们的包。如果我们回到 Github 并查阅我们的包,我们会看到它告诉我们如何安装它。

[package subido a Github](https://res.cloudinary.com/practicaldev/image/fetch/s--0ZeRB89B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas. com/blog/webcomponents-stenciljs/instalar_package.jpg)

所以我们将使用 npm:

npm install @alextomas80/stencil-webcomponents@0.0.1

进入全屏模式 退出全屏模式

好的。现在让我们使用它。为此,我们来看看Stencil 文档与 React 集成,很简单,我给大家总结一下:

我们打开文件src/index.js并将其保留如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

// Importamos nuestro package que hemos creado en los anteriores pasos
import {
    applyPolyfills,
    defineCustomElements,
} from '@alextomas80/stencil-webcomponents/loader';

ReactDOM.render(<App />, document.getElementById('root'));

applyPolyfills().then(() => {
    defineCustomElements();
});

进入全屏模式 退出全屏模式

现在是的,最后,我们将使用并查看我们的 at 按钮。我们打开文件src/App.js并添加我们的按钮,如下所示:

<at-button text="Mi WebComponent en React" />

进入全屏模式 退出全屏模式

最后,我们将看到以下方式和样式的按钮:

[在 React中使用自定义 web 组件](https://res.cloudinary.com/practicaldev/image/fetch/s--oyPfRQxf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas .com/blog/webcomponents-stenciljs/webcomponent_en_react.jpg)

好的!如您所见,它的样式与我们使用 Stencil 创建组件时提供的样式相同。我们还可以传递属性text来定义按钮将具有的文本。一个奇迹。但是......我们不是说这篇文章的目的是创建一个组件并在 React 和 Vue 中使用它吗?

用Vue集成到项目中

让我们创建我们的示例 Vue 项目:

vue create test-with-vue

进入全屏模式 退出全屏模式

我们选择它要求的选项(Vue 版本等,我不打算详述这部分)。我们启动项目,我们将看到典型的 Vue 欢迎屏幕:

npm run serve

进入全屏模式 退出全屏模式

[欢迎来到VUe](https://res.cloudinary.com/practicaldev/image/fetch/s---e-XorGl---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// alextomas.com/blog/webcomponents-stenciljs/welcome_vue.jpg)

我们将做与 React 示例完全相同的操作。让我们用 npm 安装我们的包:

npm install @alextomas80/stencil-webcomponents@0.0.1

进入全屏模式 退出全屏模式

让我们再看一下Stencil 文档与 Vue 的集成,它也非常简单,与 React 非常相似:

我们打开文件src/main.js并将其保留如下:

import { createApp } from 'vue';
import App from './App.vue';

// Importamos nuestro package que hemos creado en los anteriores pasos
import {
    applyPolyfills,
    defineCustomElements,
} from '@alextomas80/stencil-webcomponents/loader';

applyPolyfills().then(() => {
    defineCustomElements();
});

createApp(App).mount('#app');

进入全屏模式 退出全屏模式

现在我们可以使用它了。为此,我们转到示例文件src/App.vue并添加:

<at-button text="Mi WebComponent en Vue" />

进入全屏模式 退出全屏模式

[在 Vue中使用自定义 web 组件](https://res.cloudinary.com/practicaldev/image/fetch/s--a_csUTZV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alextomas .com/blog/webcomponents-stenciljs/webcomponent_en_vue.jpg)

我们又得到了完全相同的按钮!

[WebComponents - 纯魔法](https://res.cloudinary.com/practicaldev/image/fetch/s--a6RmEoty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://alextomas. com/gifs/magic.gif)

结论

通过这个简单的示例,您已经能够看到和测试 Stencil 为我们提供的潜力以及它为我们提供的可能性。我们可以在任何类型的应用程序中快速创建完全可重用的组件,无论是一种技术还是另一种技术,甚至不需要像我们所做的那样背后的 JavaScript 框架。

所以,如果你想要拥有你的组件库,与不同的项目共享它,并与不同的队友一起工作......我完全推荐使用它。

就这样。我希望它可以为你服务😉

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐