5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vite + TypeScript + React で kintone のchrome拡張を開発する

Last updated at Posted at 2023-12-18

はじめに

本記事は kintone Advent Calendar 2023 19日目の記事です。

今回はkintoneカスタマイズをchrome拡張で作ったので、その環境構築編を書きます。

アドベントカレンダーの投稿は初なので、何か間違いを見つけたよ!こうしたら良いよ!というFBは随時コメントください。

対象者

この記事は下記のような人を対象にしています。

  • kintoneカスタマイズをchrome拡張版で作りたい方
  • Vite + typescript (+ react) で chrome拡張を作りたい方

目次

環境

$ sw_vers
ProductName:		macOS
ProductVersion:		14.1
BuildVersion:		23B74

$ node -v
v18.14.2

$npm -v
9.5.0

# ここからは必要なし
$ bun -v
1.0.1

(今回の個人開発では bun.js というランタイムを使っていますが、npmで大丈夫です)

Viteプロジェクトの作成

$ cd <任意のディレクトリ>

$ npm create vite@4.4.1
Need to install the following packages:
  create-vite@4.4.1
Ok to proceed? (y) y
✔ Project name: … <任意のプロジェクト名>
✔ Select a framework: › React
✔ Select a variant: › TypeScript

Scaffolding project in (指定したディレクトリ)...

Done. Now run:

  cd vite-project
  npm install
  npm run dev

vite@latestで作成しない理由は後ほど説明します

作成できたらnpm installを実行する

プロジェクト生成後のディレクトリ構造は以下の通りです。

$ tree 
.
├── README.md
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── public
│   └── vite.svg
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── assets
│   ├── index.css
│   ├── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

パッケージのインストール

@crxjs/vite-plugin@beta@kintone/dts-gen@types/chrome をインストール

$ npm install --save-dev @crxjs/vite-plugin@beta @types/chrome @kintone/dts-gen

@crxjs/vite-plugin@beta

CRXJS Vite Plugin は、Vite を使ったchrome拡張開発に役立つパッケージです。迷わずインストールしましょう。

※プロジェクト作成において、vite@latestでなくてバージョンを指定しているのは、latestでインストールされるバージョンのメジャーが新しくなっていて(作成時点(2023年12月4日)ではv5.0.0)、CRXJSの対応が間に合っていないようです。chrome拡張の content_scripts を含めるとエラーが出てビルドできなかったです。メジャーが4の中でもnpm create vite@<version>で作成できる最新のプロジェクトが4.4.1だったためバージョンを指定しています。

@kintone/dts-gen

TypeScriptを使用してkintoneカスタマイズを実装するにはあると便利。
詳しくはこちら(目指せ!JavaScript カスタマイズ中級者(5)〜TypeScript 編〜)

@types/chrome

Chrome の型を定義したパッケージchrome拡張を開発するときには欠かせない型定義。
オートコンプリートが効くようになるため、入れておきます。

設定ファイルの編集

tsconfig.json

下記を追加

tsconfig.json
"files": [
  "./node_modules/@kintone/dts-gen/kintone.d.ts"
]

vite.config.ts

vite.config.ts
import { crx, defineManifest } from '@crxjs/vite-plugin';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

const manifest = defineManifest({
  manifest_version: 3,
  description: 'example chrome extension',
  name: 'example',
  version: '0.1.0',
});

export default defineConfig({
  plugins: [react(), crx({ manifest })],
  server: {
    port: 5174,
    strictPort: true,
    hmr: {
      port: 5174,
    },
  },
});

ディレクトリ構成の変更

chrome拡張は大きく分けて三つのjsファイルで構成されます。
そのためsrcフォルダにその三つのディレクトリを作成して管理するような構成します。

追加

$ mkdir src/popup
$ mkdir src/content
$ mkdir src/background
$ touch src/content/content.ts
$ touch src/background/background.ts

$ mkdir icons

iconsというディレクトリを作成しましたが、chrome拡張のアイコン用です。
特に絶対ではないのですが、今回はわかりやすくchrome拡張の設定のためのディレクトリとして独立させています。

今回はなんとなく歯車のアイコンをフリーでDLしてきましたが、なんでもOKです。

移動

$ mv src/assets src/popup/
$ mv src/App.css src/popup/
$ mv src/App.tsx src/popup/
$ mv src/index.css src/popup/
$ mv src/main.tsx src/popup/
$ mv index.html src/popup/
$ mv public/vite.svg src/popup/assets

削除

$ rm -rf public

今の構造はこんな感じです。

$ tree 
.
├── README.md
├── dist
├── icons
│   ├── icon.png
├── package-lock.json
├── package.json
├── src
│   ├── background
│   │   └── background.ts
│   ├── content
│   │   └── content.ts
│   ├── popup
│   │   ├── App.css
│   │   ├── App.tsx
│   │   ├── assets
│   │   ├── index.css
│   │   ├── index.html
│   │   └── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

ファイルの書き換え

vite.config.ts
const manifest = defineManifest({
  manifest_version: 3,
  description: 'example chrome extension',
  name: 'example',
  version: '0.1.0',
  + action: {
  +   default_icon: 'icons/icon.png',
  +   default_title: 'example',
  +   default_popup: 'src/popup/index.html',
  + },
});

アクションを設定することでchrome拡張のアイコンを押したらポップアップ画面(index.html)がでるようになります。

diff_src/popup/App.tsx
- import viteLogo from '/vite.svg'
+ import viteLogo from './assets/vite.svg'
diff_src/popup/index.html
- <link rel="icon" type="image/svg+xml" href="vite.svg" />
+ <link rel="icon" type="image/svg+xml" href="./assets/vite.svg" />

- <script type="module" src="src/main.tsx"></script>
+ <script type="module" src="main.tsx"></script>

ビルド

$ npm run build

built in なんとか ms がでればOKです!
上記の処理で何かが抜けてたらエラーが出ますが、焦らず解決してください。

ビルドできると、プロジェクトのルートに dist というディレクトリが作成されます。
distの中身がchrome拡張の中身になっています。これを後にchromeに適用することでchromeを使えるようになります。

chrome拡張の適用

自環境のchromeに拡張をアップロードする

今回は、作成されたdistをchromeにアップロードします。

自作のchrome拡張のアップロードの仕方は公式サイトを参考にしてみてください!

カスタムの Chrome アプリと拡張機能を作成して公開する

テスト

動画のようにpopupで初期画面を出すことができました。
test.gif

コーディング

それでは次に kintone カスタマイズです。
今回は環境構築編なので REST API を動かすまでにしておきます。

chrome拡張で kintone カスタマイズを作る際には、やりたいことによって大きく構成が変わります。

重要なこととしては、content/background/popup の3つの中で content 以外は chrome-extension:// のようなドメインになるため、REST APIを実行したい時にCORSで引っかかります。

REST APIを実行させたい場合は、 kintone を表示させたタブ(つまり同一ドメイン)で実行することが肝になります。そこで登場するのは content script です。

content.js は拡張機能が呼び出されたタブ、今回でいうと kintone の画面で呼び出すため、ドメインが同一ドメインとなり、REST API がCORSで引っかかることがなくなります。

content script をchrome拡張に組み込みたい場合はvite.config.tsに次の内容を加え、manifestに定義する必要があります。

vite.config.ts
const manifest = defineManifest({
  manifest_version: 3,
  description: 'example chrome extension',
  name: 'example',
  version: '0.1.0',
  action: {
    default_icon: 'icons/icon.png',
    default_title: 'example',
    default_popup: 'src/popup/index.html',
  },
  + content_scripts: [
  +   {
  +     matches: ['https://*.cybozu.com/k/*'],
  +     js: ['src/content/content.ts'],
  +     run_at: 'document_end',
  +   },
  + ],
});

ちなみに matches は content_scripts に必須の項目で、content scripts が動作する対象を URL で指定します。ワイルドカードを使うと便利です。
run_at は script をいつ走らせるかという名前の通りの項目ですが、必須ではありません。

今回はcontent scripts に REST API CLIENT を使用して適当なアプリから一件レコードを取得してみます。

src/content.ts
import { KintoneRestAPIClient } from '@kintone/rest-api-client';
{
  const resp = await new KintoneRestAPIClient({}).record
    .getRecord({
      app: <任意のアプリ>,
      id: <任意のレコードID>,
    })
    .then((resp) => resp)
    .catch((err) => {
      console.log(err);
    });
  console.log(resp);
}

export {};

このようにコンソール上で実行したレスポンスを確認できました!

rest.png

実際の開発では、content script ⇄ popup 等でやりとりできるAPIがあるため、popup側に取得してきたデータを渡したい場合は chrome API でやりとりすることでpopup側で取得してきたデータを扱うことができます。

開発中の拡張機能チラ見せ

今回は環境構築と簡単な REST API の実行だけでしたが、下記の動画のようなものを開発しています。
後日別記事にします。

内容は、めんどくさい kintone のレコードオブジェクトを簡単に作成する拡張機能です。
kin-obj.gif

まとめ

  • Vite + TypeScript + React で kintone カスタマイズするchrome拡張開発環境を準備しました。
  • 簡単な kintone REST API を実行できるまでの環境を作成できました。

参考文献

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?