🌩️

[Salesforce] LWCでJavascriptライブラリを使う

2023/06/29に公開

TERASSでSalesforceをやったりやらなかったりしているimslpです。

弊社は現時点でJavascriptライブラリを使ったLWC開発をしていません。勿論ダメなわけではなく必要が無い場合が多いです。が、いつ必要になるか分かりませんので、このあたりで試しておきます。
通常の開発ではnpm installなりyarn addで済むところですが、salesforceの場合はそう簡単にはいきません。組織からライブラリを参照できるようにする必要があります。

大体のやり方はsalesforce developersに載っていますのでこれを参考にしながらやっていきます。
https://developer.salesforce.com/docs/component-library/documentation/ja-jp/57.0/lwc/lwc.js_third_party_library

つくるもの

こういう時に試すライブラリはChart.jsをよく使います。視覚的にも分かりやすくていいですね。
ということで私の趣味であるCoCを題材にキャラクターのステータスをレーダーチャートで表示してみたいと思います。
https://www.chartjs.org/

ライブラリのJSファイルをダウンロードする

Chart.jsのInstallationによるとjsDelivrからダウンロードできそうですので、早速ダウンロードします。
Filesタブをクリックし、一番上のファイルを右クリックから保存します。ファイル名は何でもよいですが、後述する静的リソースをmetaデータから作成する場合は少し注意が必要です。
jsDelivr
https://www.chartjs.org/docs/latest/getting-started/installation.html
https://www.jsdelivr.com/package/npm/chart.js?path=dist

ライブラリを静的リソースとしてアップロードする

ライブラリのダウンロードが完了したら、ライブラリを静的リソースとしてSalesforceにアップロードします。
名前は何でもいいですが、静的リソース内でユニークである必要があるのと、コード内で読み込むときに使うのでわかりやすい名前が良いです。
静的リソースは設定 > カスタムコード > 静的リソースでたどり着けます。

ちなみに、勿論ですが静的リソースをmetaデータから作成・管理することも可能です。
その場合はこんな感じのmetaデータとダウンロードしたファイルをforce-app\main\default\staticresources配下に置いてデプロイします。

chartjs.resource-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Private</cacheControl>
    <contentType>text/javascript</contentType>
</StaticResource>

ファイル名に関してですが、jsファイル名がchartjsの場合、metaデータのファイル名はchartjs.resource-meta.xml となります。

この辺りのルールとか書き方を覚えるのはメンドクサイので私はブラウザでできることはブラウザでやってしまいたいタイプです。この程度ならブラウザでやったほうが早いと思います。

いざ実装

jsで静的リソースを読み込んで使うだけなので特に難しいところは無いです。
VSCodeでLWCを作成し、以下のコードを記述します。


chartjs.js-meta.xml
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>57.0</apiVersion>
    <isExposed>true</isExposed>
  <targets>
    <target>lightning__HomePage</target>
  </targets>
</LightningComponentBundle>

今回はホームページに表示するだけで良いのでlightning__HomePageを指定しています。用途によって適宜変更してください。
isExposedをtrueにするのを忘れずに!(私はよく忘れる)


chartjs.html
<template>
  <lightning-card title="探索者の能力値" >
    <canvas></canvas>
  </lightning-card>
</template>

グラフの描画用にcanvasを置いています。


chartjs.js
import { LightningElement } from "lwc";
import chartjs from "@salesforce/resourceUrl/chartjs"; 
import { loadScript } from "lightning/platformResourceLoader";

export default class Chartjs extends LightningElement {
  chart;

  connectedCallback() {
    Promise.all([loadScript(this, chartjs)])
      .then(() => {
        this.renderChart();
      })
      .catch((e) => console.error("library loading error", e));
  }

  renderChart() {
    const config = {
      type: "radar",
      data: {
        labels: ["STR", "DEX", "CON", "POW", "APP", "SIZ", "INT", "EDU"],
        datasets: [
          {
            label: "筋肉谷 武",
            data: [18, 8, 14, 13, 11, 17, 9, 12],
            fill: true,
            backgroundColor: "rgba(255, 99, 132, 0.1)",
            borderColor: "rgb(255, 99, 132)",
            pointBackgroundColor: "rgb(255, 99, 132)",
            pointBorderColor: "#fff",
            pointHoverBackgroundColor: "#fff",
            pointHoverBorderColor: "rgb(255, 99, 132)"
          },
          {
            label: "速川 駿",
            data: [8, 18, 14, 12, 13, 15, 12, 14],
            fill: true,
            backgroundColor: "rgba(54, 162, 235, 0.1)",
            borderColor: "rgb(54, 162, 235)",
            pointBackgroundColor: "rgb(54, 162, 235)",
            pointBorderColor: "#fff",
            pointHoverBackgroundColor: "#fff",
            pointHoverBorderColor: "rgb(54, 162, 235)"
          },
          {
            label: "頭脳 明晰",
            data: [7, 12, 10, 11, 14, 12, 18, 22],
            fill: true,
            backgroundColor: "rgba(75, 192, 192, 0.1)",
            borderColor: "rgb(75, 192, 192)",
            pointBackgroundColor: "rgb(75, 192, 192)",
            pointBorderColor: "#fff",
            pointHoverBackgroundColor: "#fff",
            pointHoverBorderColor: "rgb(75, 192, 192)"
          }
        ]
      },
      options: {
        scales: {
          r: {
            min: 3,
            max: 18,
            stepSize: 1
          }
        }
      }
    };

    const ctx = this.template.querySelector("canvas").getContext("2d");
    this.chart = new window.Chart(ctx, config);
  }
}
chartjs.js
import chartjs from "@salesforce/resourceUrl/chartjs"; 
import { loadScript } from "lightning/platformResourceLoader";

静的リソースとライブラリをロードするためのモジュールをimportしています

chartjs.js
  connectedCallback() {
    Promise.all([loadScript(this, chartjs)])
      .then(() => {
        this.renderChart();
      })
      .catch((e) => console.error("library loading error", e));
  }

connectedCallbakでライブラリをロードしたあとにグラフの描画用処理を呼び出しています。
Promise.allを使っていますが、複数のライブラリを読み込まない場合はloadScriptだけでも良いと思います。

chartjs.js
  const ctx = this.template.querySelector("canvas").getContext("2d");

canvasオブジェクトを取得しています。
LWCではDOM要素を取得する時にdocumentではなく、this.templateを使うことに注意です。

デプロイして確認する

ここまでできたらあとは組織にデプロイし、アプリケーションビルダーからホームページにLWCを配置して確認します。


いい感じに表示できました!

おわり

以外にも簡単にライブラリを使うことができました。

ただ、バージョンアップや別ライブラリの使用、プラグイン等、それぞれで毎回静的リソースをアップロードしたりするのはめんどくさい感じもしますね。
ただ今のところは大量のライブラリを使うケースも無いので良しとします。

調べてみると、どうやらライブラリをLWC化して使う方法もあるみたいですね、またいずれチャレンジしてみたいと思います。

ご覧いただきありがとうございました。

Terass Tech Blog

Discussion