teleporthq
プラットフォーム
ソリューション
連携
リソース

TeleportHQのクラウドコンポーネント

Cloud components in TeleportHQ

今回は、TeleportHQに新たに追加した機能、 クラウドコンポーネント.

クラウドコンポーネントの紹介

クラウドコンポーネント機能を使うと、 TeleportHQでビジュアルに作成したコンポーネントをインポート して、ほかの開発環境やTeleportHQの別のプロジェクトでも利用できます。コンポーネントは ReactおよびNext.jsに対応しており 、従来のパッケージマネージャーを使わず、CDNから直接インポートして利用できます。

この機能を実現するための詳細や、開発に取り組んだ内容を見ていきましょう。

ESモジュール

各モジュールは、読み込まれると実行されるコードの一部です。

exploringjs.com
es-modules-a-cartoon-deep-dive
es-modules-in-browsers
using-es-modules

ブラウザーの対応状況

主要なブラウザーは、基本的なサポートを提供しています es-modules。これらのモジュールのサポート状況は次のとおりです 94.45%.

「 dynamic-import 」や「 import-maps 」のような機能や言語構文は、まだ完全にはサポートされていません。 シムを使えば解決できます。シムについて詳しくは、 こちら

caniuse.com/es6-module

es-module-shims

ノードモジュールとCDNの比較

  • モジュールは個別にキャッシュできるため、2回目以降のアクセス時の読み込み時間を短縮できます。
  • 各モジュールは、CDNを使って個別にユーザーへ配信されます。
  • ベンダーモジュールのトランスパイル、ポリフィルの適用、最適化は、事前に行われます。

すべてのパッケージを配信するプロバイダーはいくつかあり、 npm

JSPM, skypack, esm.sh deno.land.

これらのモジュールCDNプロバイダーは、パッケージを変換し、必要に応じて( esm の場合)、 cjsに変換します。そして、これらのモジュールを本番環境向けに最適化したうえで配信し、ユーザーがブラウザーで直接利用できるようにします。

標準的な node_modules 開発モードでは、バンドラーを設定して、トランスパイルやポリフィル、さらには相互運用性の確保まで行う必要があります。

これはプロジェクトをビルドするたびに発生します。開発中にこれらの手順を省くことで、どれだけの時間を節約できるか想像してみてください。CIパイプラインでも時間を節約できます。

各CDNの詳細については、それぞれのページをご覧ください

モジュールCDNの仕組み:JSPM
Skypack CDN/APIリファレンス

TeleportHQ StudioのESモジュール

TeleportHQでは、このテーマについて以前から断続的に調査を続けてきました。現在のブラウザー対応状況に加え、バンドラーもこうしたワークフローを採用し始めていることから、今が最適なタイミングです。

これまでの取り組みには、次のようなものがあります

  • Studioからコンポーネントを npm インストール可能なパッケージとして配信すること。
  • また、 npm のミラーを作成し、すべてのパッケージを変換して esmに配信する取り組みも行いました。詳しくは こちら

モジュールは TeleportHQ で ベアモジュール指定子 をパッケージのインポートに使用します。これにより、 external-dependencies をどこから配信するかをエンドユーザーが制御できます。そのため、モジュールは常に、 studio と code-generatorsから生成されたコードのみを読み込みます。外部依存関係の読み込み元をユーザーが選択できるため、安心かつ安全に利用できます。

外部依存関係は、 node_modules と cdn を使って配信することもできます。詳しくはワークフローをご覧ください。

ワークフロー

TeleportHQのモジュールを使用する際、ユーザーは3種類のワークフローから選択できます。

スタジオによる最適化

すべてのモジュールは次のとおりです。

  • トランスパイル済み。
  • 相互にリンクされています。
  • グローバルCDNから配信されます。
  • バージョンが固定されています。

モジュールがネストされている場合、バンドルは行いません。代わりに、以下を使用してモジュール同士をリンクします。 imports.

モジュールが含まれるプロジェクトは、主に次の3つのカテゴリーに分けられます。

  • スタイル
  • グローバル設定とフォント
  • コンポーネント
Module categories for a project created in TeleportHQ studio

スタイル

では、 studio 複数の方法でスタイルを定義できます。 CSSクラス, タイポグラフィ 、 デザイントークン 、 レイアウトトークンなどです。これらはすべて、stylesという名前の es-module にまとめられます。また、モジュールを変更するたびに、その変更はバージョン管理されます。

import {
  projectStyleVariants,
  TOKENS,
} from 'https://jscdn.teleporthq.io/new-project-dqpb/style.js@35ff99074a6491e551432d47881ebdce23a21cef'

すべてのスタイルは styled-components と styled-systemを使用して管理されています。ただし、近日中にユーザーは react-jss を使ってモジュールを生成できるようになります。

スタイルモジュールは TOKENS と projectStyleVariantsをエクスポートします。 styles モジュールは、あらゆるプロジェクトで単独で使用できます。そのため、ユーザーはスタジオ内のデザインに、より忠実なデザイントークンを維持できます。

グローバル設定とフォント

スタジオでは、ユーザーは フォント や SEOなどのグローバル設定を定義できます。スタジオは、ユーザーが本格的なプロジェクトを構築できるよう設計されています。プロジェクトで使用するすべての globals は globals モジュールに抽象化されています。

import Globals from 'https://jscdn.teleporthq.io/new-project-dqpb/globals.js@646826692c3ac0769586600c4719b2024c8a399a'

すべてのコンポーネントは、モジュールが生成されるたびに Globals を継承します。一般的なコンポーネントは次のようになります。

import React from 'react'
import Globals from 'https://jscdn.teleporthq.io/new-project-dqpb/globals.js@646826692c3ac0769586600c4719b2024c8a399a';

const App = () =>. {
    return (
        <Fragment>
            <Globals />
            {/* ... */}
        </Fragment>    
    )
}

コンポーネント

スタジオ内の各コンポーネントは、個別のモジュールとして生成されます。コンポーネントは、使用状況に応じて相互に連携します。

すべてのモジュールを個別に分割することで、パフォーマンスが向上します。まず、モジュールのコンテンツが重複しません。.

次に、モジュールが複数回使用される場合、キャッシュから配信されます。.

モジュールは複数回インポートできますが、実行されるのは一度だけです。.

import Header from 'https://jscdn.teleporthq.io/new-project-dqpb/header.js@aa99dd13a8c20277795a17204d2f6dfba52e0737'

モジュールのバージョンが更新されるのは、コンポーネント自体、またはコンポーネントが依存するモジュールのいずれかが変更された場合のみです。

モジュールの @version は、 グローバル, スタイル または コンポーネント 自体が変更されると変わります。

アセット

Studioでは、コンポーネントの設計時にマルチメディアを使用できます。使用されるアセットもCDNから配信されます。

ソースマップ

末尾の拡張子を変更すると、任意のモジュールのソースマップを取得できます。

https://jscdn.teleporthq.io/new-project-dqpb/header.map@aa99dd13a8c20277795a17204d2f6dfba52e0737

フレームワークとコンポーネントの種類

Studioでコンポーネントを設計する際、ユーザーは routeLinks, seo-tags や、フレームワークに依存するさまざまな機能を使用できます。これらに対応するため、モジュールで使用するターゲット環境を選択できるようにしています。ほとんどの cient-side Reactアプリでは react-router を使用し、 NextJS では next/linkを使用します。また、 react-helmet と next/head.

これらの es-modules は、当社の open-source コードジェネレーターを使用して生成されます。ジェネレーターは GitHubで公開されています。また、ほかのフレームワークや、 style-flavour の組み合わせにも同様のサポートを提供する予定です。たとえば、 React + React-JSS, Next + React-JSS などです。

クラウドコンポーネントとインポートマップ

ESモジュールの導入により、モジュールごとにコードを整理できるようになりました。必要なモジュールをインポートできるほか、実行時に読み込むモジュールをより細かく制御できます。 動的インポート.

昔は、scriptタグを使ってブラウザーにJavaScriptを読み込んでいました。どのスクリプトが先に読み込まれるかを制御する方法はほとんどなく、スクリプト同士に依存関係がある場合は、読み込み順序を適切に調整することがJavaScript開発の大きな課題でした。

その後、バンドラーやタスクランナーが登場し、こうした手作業を担うようになりました。インポートマップを使えば、バンドラーやリゾルバーを一式導入せずにアプリケーションを開発できます。また、「ベアモジュール指定子」をそのまま使えるため、次のように記述できます。

import { useState } from 'react'

そして インポートマップ が、指定されたソースからReactを解決します。

ESモジュールについての発表記事「 TeleportHQのテレポート機能を備えたクラウドコンポーネント」で紹介したように、 components, styles と tokens はそれぞれ個別のモジュールとして利用できます。TeleportHQのモジュールでは「ベアモジュール指定子」が使われているため、外部依存関係の解決先をブラウザーに知らせるには、インポートマップが必要です。

ベアモジュール指定子を使わないESモジュール

ここでは react-dom のモジュールを skypackから読み込みます。パッケージの external 依存関係もURLを使ってインポートされていることが分かります。

<iframe height="300" style="width: 100%;" scrolling="no" title="Skypack Example" src="https://codepen.io/jkrishna/embed/preview/vYWEPZQ?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/jkrishna/pen/vYWEPZQ">
  Skypack Example</a> by Jaya Krishna (<a href="https://codepen.io/jkrishna">@jkrishna</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

また、 react-dom パッケージは内部で object-assign と scheduler を使用しており、これらも別の一意な事前マッピング済みURLから読み込んでいることが分かります。

js
import aa from "/-/react@v17.0.1-yH0aYV1FOvoIPeKBbHxg/dist=es2020,mode=imports/optimized/react.js";
import m from "/-/object-assign@v4.1.1-LbCnB3r2y2yFmhmiCfPn/dist=es2020,mode=imports/optimized/object-assign.js";
import r from "/-/scheduler@v0.20.2-PAU9F1YosUNPKr7V4s0j/dist=es2020,mode=imports/optimized/scheduler.js";

TeleportHQのモジュール

TeleportHQのモジュールでは、 bare-module-specifiers と事前にマッピングされた一意のURLを組み合わせています。そのため、依存関係の読み込みはユーザーが管理でき、 Studio に依存するすべてのモジュールは自動的に読み込まれます。

一般的なクラウドコンポーネントには、次のようなインポートがあります。

jsx
import React from 'react';
import { variant } from 'styled-system';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import Globals from 'https://jscdn.teleporthq.io/new-project-dqpb/globals.js@646826692c3ac0769586600c4719b2024c8a399a';
import { projectStyleVariants, TOKENS } from 'https://jscdn.teleporthq.io/new-project-dqpb/style.js@35ff99074a6491e551432d47881ebdce23a21cef';

オンラインで利用できる、または jspm パッケージとして入手できる npm を使って、 generator.jspm.io

使用している依存関係をすべて入力できます。今回の場合は、 react, react-dom, styled-components と prop-types と styled-systemです。このURLを使うと、ジェネレーターが読み込み、これらすべてのモジュールを含むインポートマップを作成します。

generator.jspm.io

すぐに使えるよう設定済みのテンプレートを紹介します。

<iframe height="500" style="width: 100%;" scrolling="no" title="teleportHQ - jspm - template" src="https://codepen.io/jkrishna/embed/VwMaWaN?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/jkrishna/pen/VwMaWaN">
  teleportHQ - jspm - template</a> by Jaya Krishna (<a href="https://codepen.io/jkrishna">@jkrishna</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

CodesandboxとCodepenのテンプレート。

Codepen
Codesandbox

「 import-maps 」について、詳しくはこちらをご覧ください。

Next.JSでクラウドコンポーネントを利用する

クラウドコンポーネントについて クラウドコンポーネント初めて知った方は、こちらの簡単な記事をご覧ください。すぐに読める内容です。記事は こちら

Next.JSでURLインポートを利用する

TeleportHQは創業当初から、Reactを使用した高性能なフレームワークであるNext.jsを、開発のしやすさ、デプロイ、拡張性の高さから愛用しています。

、 v@12 Next.jsは、リモートソースから urlImports モジュールを読み込むための新機能 JS を導入しました。これにより、毎回JavaScriptモジュールをバンドルしてトランスパイルする手順を完全になくせます。CDNからモジュールを読み込み、プロジェクト内でそのまま使用できます。

URLインポートとTeleportHQ

Studioのコンポーネント一覧で任意のコンポーネントを右クリックすると、固有のモジュールリンクを作成できます。そのモジュールは、あらゆるNext.jsプロジェクトで直接使用できます。

jsx
import Card from 'https://jscdn.teleporthq.io/new-project-68d4/card.js@be57bcf81f65fd2541ccd1a2e69a02b3e4c88a84'

const App = () => {
    return (
    <div>
       <Card />
    </div>
  )
}

export default App

プロジェクトで TeleportHQのコンポーネントを使用する設定方法については、 https://github.com/teleporthq/nextjs-http をご覧ください。新しいプロジェクトを始める際に使えるテンプレートが用意されています。

npx degit https://github.com/teleporthq/nextjs-http

既存プロジェクトの設定

既存のNextJSプロジェクトを設定するには、NextJSのバージョンが12以上である必要があります。

を開き、 next.config.jsを https://jscdn.teleporthq.io の urlImports セクションに追加します。これにより、Next-JSが特定のドメインからのみモジュールをインポートできるようになります。不明なドメインからのJavaScript実行は無効になります。詳しくは url-imports-security-model.

js
module.exports = {
  reactStrictMode: true,
  experimental: {
    urlImports: ['https://jscdn.teleporthq.io']
  }
}

次に、 styled-components と styled-system をプロジェクトに追加します。以下の方法で追加できます。

bash
npm install styled-components styled-system

「 TeleportHQ 」のモジュールは、プロジェクト内でスタイル、スタイルバリアント、デザイントークンを定義するために、これら2つのパッケージを使用します。また、外部モジュールのインポートにはすべて bare-module-specifiersを使用します。そのため、ユーザーは好みに応じてこれらの依存関係を配信できます。

次に、 next.config.jsを調整します。 エイリアスを設定 して、 next.config.js の esm バージョンの styled-componentsを使用する必要があります。この手順の詳細は こちら.

変更を加えると、next.config.jsは次のようになります。

js
module.exports = {
  reactStrictMode: true,
  webpack: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      'styled-components': require.resolve('./node_modules/styled-components/dist/styled-components.esm.js'),
    }

    return config
  },
  experimental: {
    styledComponents: true,
    urlImports: ['https://jscdn.teleporthq.io']
  }
}

これで準備完了です。次を実行してください……

bash
npm run dev

……すると、プロジェクトが次の場所で読み込まれます。 http://localhost:3000 🚀

その他

NextJSは next.lock を作成し、CDNから動的に読み込まれるすべてのモジュールを含めます。ただし、 Cache-Control: no-cacheで配信されるモジュールは除きます。詳しくは こちら.

製品

関連記事

コメント

コメントはまだありません。最初に感想を共有しましょう。

コメントを入力

メールアドレスが公開されることはありません。
コメントは表示される前に審査されます。