はじめに
magical_makeというmake commandを叩くときに魔方陣が描画されるCLIを作りました。
その時に静的なファイル諸々の扱いを学べたので、記しておきます。
静的ファイルの配置場所
目撃したpath
- lib/assets/*
- lib/hoges/* ※ imagesやtexts等
- assets/*
- public/*
- priv/*
採用path
- priv/assets/
Phoenix等のライブラリではpriv/*
への配置が多かったです。多分Erlangの作法だと思います。
priv - Optional. Used for application specific files.
:code.priv_dir(:my_app)
というfunction(Erlangから参照)も用意されている為、こちらの構成がよさそうでした。Phoenixだとmigration系のファイルもここに配置されます。
priv/assets/aaa.txt
|> File.read が落ちる
こちらのコマンド、開発中のときは問題ないのですが、hexやescript等でコンパイルしてしまうとpathの参照ができなくなってしまいます。
escriptの方でもサポートはしていないようです。
Note: escripts do not support projects and dependencies that need to store or read artifacts from the priv directory
コンパイル後のライブラリで静的ファイルを上手く参照するには
調べてみると Application.app_dir
や :code.priv_dir
を用いた参照であれば上手くいきそうな情報がありましたが、なんともうまくいきません。
さらに探すと以下forumに辿り着きました。
この中で José Valiam の回答で答えを発見。
To confirm: although priv is the appropriate place, we can’t load files from priv inside escripts. What I usually do is to load the file at compilation time and store it as a module attribute:
@external_resource "priv/foo/bar"
@bar_contents File.read! "priv/foo/bar"
def bar_contents, do: @bar_contents
同じ方法で確認
defmodule MagicalMake.Make do
@text elem(File.read("priv/assets/aaa.txt"), 1)
def text do
@text
end
end
MagicalMake.Make.font
=> aaa
成功!!!