kenju's blog

About Programming, Mathematics, Security and Blockchain

TypeScriptとRails Assets Pipelineを融合する`ts_assets`

github.com

自分で言うのもなんだけど、TypeScript & Rails を使っているWeb Application開発の場合、結構便利だと思う。

使い方

READMEに書いてある通り。rakeか何かでTsAssets.generate(include: "app/assets/images")を読んであげると、include:に指定したPATH配下のアセットを元に、TypeScriptから参照しやすい形でエクスポートしてくれる。

/** svg/ruby-icon.svg */
const PATH_SVG_RUBY_ICON = "/assets/svg/ruby-icon-486fbe77b2fa5354.svg";

/** svg/ruby-icon */
export function ImageSvgRubyIcon(props: React.HTMLProps<HTMLImageElement>) {
    return <img alt="ruby-icon"
                width={128}
                height={128}
                src={PATH_SVG_RUBY_ICON}
                srcSet={`${PATH_SVG_RUBY_ICON} 1x`}
                {...props}
                />;
}

今のところニーズ&リクエストがないので、React Componentsのみexportしている。

画像のPATHだけ使いたい、といった場合もチームによってはあると思うので、その場合はぜひPR送ってください。

特徴

エクスポート結果を見るとわかる通り、デフォルトでwidth/heightをセットしてくれる。これはfast_image gemを使って、ビルドするときに元画像のwidth/heightを取得している。

開発時Tips

アセットのdigestを取得する

Sprockets::Environmentを使う。digestは、アセットファイル本体が変わらない限り更新されないので、チーム開発の場合、ビルドされた生成結果をgitに含めてもいいと思う。

env = Sprockets::Environment
asset = env.find_asset(asset_path)
asset.digest_path # "/assets/svg/ruby-icon-486fbe77b2fa5354.svg";

テスト手法

テスト方法は少し変わっていて、gemなのにrubyで書いたテストが一つもない。

というのも、このgemの目的は「TypeScriptで読み込めるReact Componentsを出力すること」なので、むしろTypeScriptでテストを書くべき。逆に言うと、TypeScriptの実行環境でビルドされたファイルが正常に動くのであれば、公開APIの質を担保していることになるので、rubyで書くテストは必ずしも必要ない。

設計

models/には、モデルを扱うためのクラスを担当。 generators/は、モデルを利用してビルド結果を出力するロジックを担当。

lib
├── ts_assets
│   ├── application_generator.rb
│   ├── generators
│   │   ├── const_generator.rb
│   │   └── react_generator.rb
│   ├── models
│   │   ├── asset_meta_info.rb
│   │   └── content.rb
│   └── version.rb
└── ts_assets.rb

3 directories, 7 files