概要
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の情報の追記を行います。
{
"play": "./srcts/widgets/play.ts"
}
[
{
"test": "\\.tsx?$",
"use": [
{"loader": "ts-loader"}
]
}
]
webpack.common.jsの修正
先のconfigファイル群のpathが変わっていると思いますので修正します。
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の型情報を書き込みます。
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の型付けの威力を享受できているからこそのエラーになります。
インポート先の修正
// heder.jsをheaderに修正
import { asHeader } from '../modules/header';
型情報の追記
const asHeader = (x: {message: string}) => {
return '<h1>' + x.message + '</h1>';
}
トランスパイル&実行
トランスパイル
以下のコマンドで必要なjsファイルをトランスパイル出来たら成功です。
npm run development
Rでの実行
Rでも実行できることを確認してください。
devtools::load_all()
play("This is a widget!")
これでセットアップが終わりましたので、適宜TypeScriptで好きなライブラリをインストールして利用してください。
参考