rails/webpackerを使ってRailsで定義した定数をTypeScript(JavaScript)内で使う

環境

  • Rails5.1.4
  • rails/webpacker 3.2.1

公式のdocumentにあるerb-loaderを利用する。 https://github.com/rails/webpacker#erb

ubuntu@ubuntu-xenial:~/rails/yuyuyui$ bundle exec rails webpacker:install:erb
rails aborted!
Don't know how to build task 'webpacker:install:erb' (see --tasks)

taskがないと言われた(この時点ではrails/webpacker 3.0.1あたりだった)。webpackerをupgradeする

ubuntu@ubuntu-xenial:~/rails/yuyuyui$ bundle update webpacker
ubuntu@ubuntu-xenial:~/rails/yuyuyui$ bundle exec rake -T | grep erb
rake webpacker:install:erb              # Install everything needed for Erb

タスクができたので再実行する

ubuntu@ubuntu-xenial:~/rails/yuyuyui$ bundle exec rails webpacker:install:erb
Webpacker is installed �
sing /home/ubuntu/rails/yuyuyui/config/webpacker.yml file for setting up webpack paths
Copying erb loader to config/webpack/loaders
create  config/webpack/loaders/erb.js
Adding erb loader to config/webpack/environment.js
insert  config/webpack/environment.js
insert  config/webpack/environment.js
Updating webpack paths to include .erb file extension
insert  config/webpacker.yml
Copying the example entry file to /home/ubuntu/rails/yuyuyui/app/javascript/packs
create  app/javascript/packs/hello_erb.js.erb
Installing all Erb dependencies
run  yarn add rails-erb-loader from "."

いろいろファイルができた。とりあえずwebpack-dev-serverを起動してみる

ubuntu@ubuntu-xenial:~/rails/yuyuyui$ bundle exec bin/webpack-dev-server
/home/ubuntu/rails/yuyuyui/config/webpack/environment.js:4
environment.loaders.append('erb', erb)
^
TypeError: environment.loaders.append is not a function

appendがないと言われる。理由はわからないがとりあえず config/webpack/environment.js 内のappendをsetにして回避する(情報求)

environment.loaders.set('erb', erb)

これで使えるようになる。今回はTypeScriptに書きたいので、config/webpack/loaders/erb.jstest: を以下のように書き換える。

module.exports = {
test: /\.(erb|ts)$/,
enforce: 'pre',
exclude: /node_modules/,
use: [{
loader: 'rails-erb-loader',
options: {
runner: 'bin/rails runner'
}
}]
}

これで例えばconfig gemを利用して以下のようなTypeScriptが書ける。

    getCards(): Observable<Card[]> {
let url = "http://<%= Settings['api_host'] %>/api/cards.json";
return this.http.get<Card[]>(url);
}
Pocket