Asset
static
Phoenix

PhoenixでStatic Fileをサーブする

 Phoenixをお手軽なWebサーバとして使い、いろいろな検証や実験にも使って行きたいと考えました。そんな用途にはnodeとか使ってきたのですが、切り替えていきたいと思っています。Elixir Cowboyを直に使ってもいいのですがね。

1.PhoenixでStatic Fileをサーブする

 とりあえずWebサーバという事で、htmlとか画像ファイルとかを使えればよいわけです。phoenixプロジェクトを開始します。

mix phx.new phoenix_static --no-ecto

 endpoint.exのPlug.Staticのonlyをコメントアウトします。そうすればassets/static下に置いたファイルは、htmlでもjpgブラウザから表示できるようになります。その他のrouteの変更とかは必要ありません。

lib/phoenix_static_web/endpoint.ex
#
  plug Plug.Static,
    at: "/", from: :phoenix_static, gzip: false,
    # only: ~w(css fonts images js favicon.ico robots.txt)
#

やりたいことは以上です。終了。

2.もう少し説明

 とはいえ、わかる範囲でもう少し説明を加えておきたいと思います。

 まずはPlug.Staticのドキュメントを参照してみます。

 よくわからない部分も多いのですが、:atはリクエストパスで、今は"/"が指定されています。:fromはサーバのファイルが置いてあるディレクトリですが、atomで:phoenix_staticと指定されています。これは"priv/static"を意味しているようです。

 つまりURLとファイルの関係は以下のようになっています。

http://www.mypress.jp:4001/abc.html ==> priv/static/abc.html
http://www.mypress.jp:4001/css/app.css  ==> priv/static/css/app.css
http://www.mypress.jp:4001/js/app.js  ==> priv/static/js/app.js

 これはphoenixのassets管理を行っているBrunchの仕様に沿った形なのでしょうか。 Phoenixの公式ドキュメントを参照してみます。

 まずPhoenixはassets管理にBrunchを利用していると述べ、次のように続けています。ディレクトリassets/staticにあるファイルは、変更されることなくpriv/static/ にコピーされます。これは以下のbrunch-config.jsのconventionsのコメントと同じです。

assets/brunch-config.js
exports.config = {
  // See http://brunch.io/#documentation for docs.
  files: {
    javascripts: {
      joinTo: "js/app.js",

      // To use a separate vendor.js bundle, specify two files path
      // http://brunch.io/docs/config#-files-
      // joinTo: {
      //   "js/app.js": /^js/,
      //   "js/vendor.js": /^(?!js)/
      // }
      //
      // To change the order of concatenation of files, explicitly mention here
      // order: {
      //   before: [
      //     "vendor/js/jquery-2.1.1.js",
      //     "vendor/js/bootstrap.min.js"
      //   ]
      // }
    },
    stylesheets: {
      joinTo: "css/app.css"
    },
    templates: {
      joinTo: "js/app.js"
    }
  },
  conventions: {
    // This option sets where we should place non-css and non-js assets in.
    // By default, we set this to "/assets/static". Files in this directory
    // will be copied to `paths.public`, which is "priv/static" by default.
    assets: /^(static)/
  },

  // Phoenix paths configuration
  paths: {
    // Dependencies and current project directories to watch
    watched: ["static", "css", "js", "vendor"],
    // Where to compile files to
    public: "../priv/static"
  },

  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/vendor/]
    }
  },

  modules: {
    autoRequire: {
      "js/app.js": ["js/app"]
    }
  },

  npm: {
    enabled: true
  }
};

 この時endpoint.exのPlug.Staticにある:only optionで指定されたもののみがroot path("/")にマウントされるようになります。:only optionを削除すればこの制限も消えます。Plug.StaticとBrunchの関係がイマイチよくわかりませんね。

 まあ、しかしPhoenixにStatic Fileをサーブさせたいときは、assets/staticにファイルを置けばOKのようです。例えばassets/static/cssにapp9.cssファイルを置けば、priv/static/css/app9.cssにコピーしてくれるので、アクセス可能になります。

以上です。