Rails 7 Alpha 1, 2 が公開されたので、今回は、Rails 7 Alpha 2 を動かしてみます。
中でも気になっているのは、importmap なので、こちらをメインで試していきます。
参考
Rails 7 Alpha 2 導入
以下ファイルを用意。
.env1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| NODE_V=14.18.0 RUBY_V=3.0.2
APP_NAME_SUFFIX=
APP_PORT=
MYSQL_PORT=
MYSQL_ROOT_PASSWORD=
RAILS_DATABASE_PORT=
|
Dockerfile1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| FROM amazonlinux:latest
ARG NODE_V="14.10.0" ARG RUBY_V="3.0.0" ARG APP_PORT="3000"
RUN yum update -y && \ yum install -y wget which systemd-sysv crontabs && \ wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-devel-3.8.11-1.fc21.x86_64.rpm && \ wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-3.8.11-1.fc21.x86_64.rpm && \ yum install -y sqlite-3.8.11-1.fc21.x86_64.rpm sqlite-devel-3.8.11-1.fc21.x86_64.rpm && \ yum install -y git tar gcc gcc-c++ make openssl-devel zlib-devel sqlite sqlite-devel bzip2 readline-devel mysql-devel && \ yum --enablerepo=epel,remi,rpmforge install -y libxml2 libxml2-devel && \ yum install -y curl libcurl libcurl-devel && \
git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile && \ source ~/.bash_profile && \ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile && \ source ~/.bash_profile && \ mkdir -p "$(rbenv root)"/plugins && \ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build && \ rbenv install $RUBY_V && \ rbenv global $RUBY_V
ENV PATH /root/.rbenv/shims:/root/.rbenv/bin:/root/.nodenv/shims:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN mkdir /usr/src/app WORKDIR /usr/src/app
EXPOSE $APP_PORT
|
docker-compose.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| version: "3" services: app: build: context: . dockerfile: Dockerfile args: - NODE_V=${NODE_V:-14.10.1} - RUBY_V=${RUBY_V:-3.0.0} networks: - default privileged: true command: /sbin/init ports: - "127.0.0.1:${APP_PORT:-3000}:${APP_PORT:-3000}" volumes: - .:/usr/src/app:cached - /usr/src/app/vendor - /usr/src/app/tmp - /usr/src/app/log - /usr/src/app/.git tty: true environment: - RAILS_DATABASE_HOST=db - RAILS_DATABASE_PORT=${RAILS_DATABASE_PORT:-3306} - RAILS_DATABASE_USER=root - RAILS_DATABASE_PASS=${MYSQL_ROOT_PASSWORD:-password_root} - BINDING=0.0.0.0 - HOST=0.0.0.0 - PORT=${APP_PORT:-3000} - APP_NAME_SUFFIX=${APP_NAME_SUFFIX:-app}
|
以上を用意して、以下のコマンドを実行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $ docker-compose build $ docker-compose up -d $ docker-compose exec app bash
$ bundle init
$ bundle install $ bundle exec rails new .
$ bundle exec rails s
|
これで localhost:3000 にアクセスして、みるといつもの楽しそうな画が出ます。
画は変わらない様子。
この時点で、Node.js は一切導入せずに使えています。
標準で webpacker が不要になったので、警告も出ず。
アクセスしてみると、ファイルはバンドルされず個別に取得されてるのが見えます。
importmap を使って plotly.js 導入
よく見かけるのは React の導入なので、今回は plotly.js を導入してみます。
一旦現在の状況。
plotly.js 導入前のimportmap1 2 3 4 5 6 7 8 9 10 11 12
| $ ./bin/importmap json { "imports": { "application": "/assets/application-37f365cbecf1fa2810a8303f4b6571676fa1f9c56c248528bc14ddb857531b95.js", "@hotwired/turbo-rails": "/assets/turbo-7c5e418c7a4d154780d11e54c0fbd17ca23ba401e915c299c4166410c90db9df.js", "@hotwired/stimulus": "/assets/stimulus-24c1fe138493d69738cc137a0b8412877d0ffac33385b62d153012a3e7a13db5.js", "@hotwired/stimulus-importmap-autoloader": "/assets/stimulus-importmap-autoloader-7366d931317007a1e7e62c8dd8198dbc6d6b438207ff8d8539d06019597bf2f7.js", "controllers/application": "/assets/controllers/application-0a88d7da94dddbd4b5db3a7e58aba83c761c0de29f578c197e4e41a3a79d014f.js", "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js", "controllers": "/assets/controllers/index-f6aa019eef4d0e13975a27efdf6d17ba2c6446417bfcb3139efd889f948a5dfc.js" } }
|
plotly.js を導入します。
plotly.js 導入と導入後のimportmap1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $ ./bin/importmap pin plotly.js-dist-min
$ ./bin/importmap json { "imports": { "application": "/assets/application-37f365cbecf1fa2810a8303f4b6571676fa1f9c56c248528bc14ddb857531b95.js", "@hotwired/turbo-rails": "/assets/turbo-7c5e418c7a4d154780d11e54c0fbd17ca23ba401e915c299c4166410c90db9df.js", "@hotwired/stimulus": "/assets/stimulus-24c1fe138493d69738cc137a0b8412877d0ffac33385b62d153012a3e7a13db5.js", "@hotwired/stimulus-importmap-autoloader": "/assets/stimulus-importmap-autoloader-7366d931317007a1e7e62c8dd8198dbc6d6b438207ff8d8539d06019597bf2f7.js", "plotly.js-dist-min": "https://ga.jspm.io/npm:plotly.js-dist-min@2.5.1/plotly.min.js", "controllers/application": "/assets/controllers/application-0a88d7da94dddbd4b5db3a7e58aba83c761c0de29f578c197e4e41a3a79d014f.js", "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js", "controllers": "/assets/controllers/index-f6aa019eef4d0e13975a27efdf6d17ba2c6446417bfcb3139efd889f948a5dfc.js" } }
|
導入後の importmap には、plotly.js-dist-min が含まれているのがわかります。
パッケージのダウンロードがされているわけでもないので動作は高速。
plotly.js-dist-min の取得先は、https://ga.jspm.io
です。
JSPMが管理する importmap 用モジュールを提供してくれる CDN だそうです。
適当なルーティングを作成して、erb に以下のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div id="glaph"></div> <script type="module"> import Plotly from "plotly.js-dist-min";
const data = [ { x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], }, ];
Plotly.newPlot("glaph", data); </script>
|
これで再度作成した URL にアクセスすると、グラフが作成されました。
開発者ツールのネットワークを見てみます。
plotly.js-dist-min は、https://ga.jspm.io/npm:plotly.js-dist-min@2.5.1/plotly.min.jsから取得されているのがわかります。
スクリプトタグは <script type="module">
で書かないと、import Plotly from "plotly.js-dist-min";
でエラーになるのが注意事項。
esbuild も試してみる
開発者ツールのネットワークを見てみると stimulus は、rails から配信されています。
rake assets:precompile で js のビルドされることがわかります。
ここで、Rails 7 は別の js のビルド環境も用意しているということで試してみます。
rails/jsbundling-rails を見てみます。
以下のように、アプリケーションの作成時に指定できることがわかります。
1
| $ rails new myapp -j [esbuild|rollup|webpack]
|
この方法でアプリケーションを作成してみます。
Dockerfile を変更して、今回は Node.js を導入しておきます。
Dockerfile1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| FROM amazonlinux:latest
ARG NODE_V="14.10.0" ARG RUBY_V="3.0.0" ARG APP_PORT="3000"
RUN yum update -y && \ yum install -y wget which systemd-sysv crontabs && \ wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-devel-3.8.11-1.fc21.x86_64.rpm && \ wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-3.8.11-1.fc21.x86_64.rpm && \ yum install -y sqlite-3.8.11-1.fc21.x86_64.rpm sqlite-devel-3.8.11-1.fc21.x86_64.rpm && \ yum install -y git tar gcc gcc-c++ make openssl-devel zlib-devel sqlite sqlite-devel bzip2 readline-devel mysql-devel && \ yum --enablerepo=epel,remi,rpmforge install -y libxml2 libxml2-devel && \ yum install -y curl libcurl libcurl-devel && \
git clone https://github.com/nodenv/nodenv.git ~/.nodenv && \ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile && \ source ~/.bash_profile && \ echo 'eval "$(nodenv init -)"' >> ~/.bash_profile && \ source ~/.bash_profile && \ mkdir -p "$(nodenv root)"/plugins && \ git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build && \ nodenv install $NODE_V && \ nodenv global $NODE_V && \
git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile && \ source ~/.bash_profile && \ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile && \ source ~/.bash_profile && \ mkdir -p "$(rbenv root)"/plugins && \ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build && \ rbenv install $RUBY_V && \ rbenv global $RUBY_V && \
wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo && \ curl --silent --location https://rpm.nodesource.com/setup_14.x | bash - && \ yum install yarn -y
ENV PATH /root/.rbenv/shims:/root/.rbenv/bin:/root/.nodenv/shims:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN mkdir /usr/src/app WORKDIR /usr/src/app
EXPOSE $APP_PORT
|
https://rpm.nodesource.com/setup_6.x としていたが、https://rpm.nodesource.com/setup_14.xに変更。
そもそもが古すぎた。
https://rpm.nodesource.com/setup_6.x だと yarn が見つからない?ということも起きた。
以下コマンドで準備。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| $ docker-compose build $ docker-compose up -d $ docker-compose exec app bash
$ bundle init
$ bundle install $ bundle exec rails new . -j esbuild
$ bin/dev
|
ここまでやって、いつもの画面が出ます。
コンソールを見るとわかることですが、以下のメッセージがコンソールに上がります。
$ esbuild app/javascript/*.* --bundle --outdir=app/assets/builds --watch
app/javascript/
以下が、監視されているので書き換えると、以下のメッセージが上がります。
[watch] build started (change: "app/javascript/controllers/application.js")
試しに、こちらでも plotly.js-dist-min を導入してみます。
1
| $ npm install plotly.js-dist-min
|
適当なルーティングを追加して、app/javascript/graph.js を作成。
app/javascript/graph.js1 2 3 4 5 6 7 8 9 10
| import Plotly from "plotly.js-dist-min";
const data = [ { x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], }, ];
Plotly.newPlot("glaph", data);
|
読み込み側で追記。
app/javascript/application.js1 2 3 4
| import "@hotwired/turbo-rails"; import "./controllers"; import "./graph";
|
以上で、<div id="glaph"></div>
のタグが有るページには、plotly.js で作成されたグラフが出るようになりました。
esbuild を使用できました。
開発者ツールのネットワークを見てみると、js ファイルはビルド済みの1つだけ取得されていています。
js のロードは esbuild では、次のようになっています。
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
対して、importmap は、<%= javascript_importmap_tags %>
でした。
あいも変わらずヘルパーは便利です。
今回は、Rails 7 Alpha 2 を動かしてみましたが、importmap を使った場合でも stimulus はビルドして返されていました。
アプリケーションと強く結びつく stimulus は必須なのでそうするが、それ以外はそれこそ塩をまぶすような使い方の想定を感じます。
対して、本当に外部ライブラリも含めたアプリケーションを作る、外部ライブラリが動作できないとアプリケーションとして成立しない。
というときに esbuild などを選択するといった具合に。
foreman がインストールされたりと便利なのですが、Gemfile に記載がない形で導入されています。
そのためチームで開発していて、途中参入した人は「素直に bundle install しても、動かないんですが」ということも発生しそうではあります。
Docker での導入では、既存環境の構成という前提が無いので、再現性もあるし何をするかはっきりしてやはりイイです。
ではでは。