LoginSignup
3
0
この記事誰得? 私しか得しないニッチな技術で記事投稿!

Shiny WidgetをTypeScript+webpackで作成する際のセットアップ

Last updated at Posted at 2023-06-17

概要

RShinyで使うWidgetを作成する際、デフォルトのテンプレートではTypeScriptを利用できないので、利用可能にするまでの設定を備忘録的に書き残します。

手順

packer::scaffold_widgetを実行しwebpack管理のテンプレートを作成する

webpackを利用すると最終的なJavaScript実行ファイルを一つにまとめられます。
これを利用したテンプレート作成ライブラリであるpackerを利用して必要なファイルを作成します。

# 必要なパッケージのインストール
install.packages("usethis")
install.packages("packer")

# テンプレートの作成(ライブラリ名は適宜読み替えてください)
usethis::create_package("playground")
packer::scaffold_widget("play")

TypeScript関連のモジュールのインストール

TypeScriptを実行するにあたって必要になるモジュールをコマンドライン上でインストールします。(nodeをインストールしている必要あり)

npm i -D typescript @types/node ts-loader

tsconfig.jsonファイルの作成

Typscript用の設定ファイルを作成します。
これで晴れてTypeScriptの世界になります。

npx tsc --init

各フォルダとファイルの名称変更

js用に出力されたフォルダとファイルをts用に変更していきます。

  • srcjsフォルダ → srctsフォルダ
  • srcts/modeles/header.js → srcts/modeles/header.ts
  • srcts/widgets/play.js → srcts/widgets/play.ts
  • srcts/index.js → srcts/index.ts

configファイルの修正

packerで出力された構造だとsrcts/configにwebpack用の設定が書かれていますのでこれを修正します。
entrypointの修正とloaderの情報の追記を行います。

srcts/config/entry_points.json
{
  "play": "./srcts/widgets/play.ts"
}
srcts/config/loaders.json
[
    {
        "test": "\\.tsx?$",
        "use": [
          {"loader": "ts-loader"}
        ]
    }
]

webpack.common.jsの修正

先のconfigファイル群のpathが変わっていると思いますので修正します。

webpack.common.js
var outputPathFile = './srcts/config/output_path.json',
    entryPointsFile = './srcts/config/entry_points.json',
    externalsFile = './srcts/config/externals.json',
    miscFile = './srcts/config/misc.json',
    loadersFile = './srcts/config/loaders.json';

外部ライブラリの型情報の追加

Shinyから使う場合、HTMLWidgetのJavaScriptライブラリは外部ライブラリ(srcts/config/externals.json内記載)として読み込まれるので型情報がありません。
そのままだとコンパイルエラーになるので、srcts/types/global.d.tsを作成してHTMLWidgetの型情報を書き込みます。

srcts/types/global.d.ts
declare namespace HTMLWidgets {
  interface Widget {
    name: string;
    type: string;
    factory: (el: HTMLElement, width: number, height: number) => {
      renderValue: (x: any) => void;
      resize: (width: number, height: number) => void;
    };
  }
  function widget(w: Widget): void;
}

各ファイルの修正

そのままだとIDE上(e.g. VSCode)でエラーが出ていると思いますので修正します。
この辺りは、TypeScriptの型付けの威力を享受できているからこそのエラーになります。

インポート先の修正

srcts/widgets/play.ts
// heder.jsをheaderに修正
import { asHeader } from '../modules/header'; 

型情報の追記

srcts/modules/header.ts
const asHeader = (x: {message: string}) => {
  return '<h1>' + x.message + '</h1>';
}

トランスパイル&実行

トランスパイル

以下のコマンドで必要なjsファイルをトランスパイル出来たら成功です。

npm run development

Rでの実行

Rでも実行できることを確認してください。

devtools::load_all()
play("This is a widget!")

image.png

これでセットアップが終わりましたので、適宜TypeScriptで好きなライブラリをインストールして利用してください。

参考

3
0
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
3
0