This page looks best with JavaScript enabled

『パーフェクトRuby on Rails』4章

 ·   ·  ☕ 4 分で読めます
✏️

4章

Webpackerについて

app/javascript配下で作業し、ビルド結果をpublic/packs/jsへ出力する。

$ rails webpacker:compileで明示的なビルドを行う。

app/javascript/packs配下のJSファイルが、実際にエントリーポイントとなるファイルへビルドされる。
例えば、app/javascript/packs/hello.jsを作成してコンパイルすると、public/packs/jsには以下のようなファイルが生成される。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ ls -1 public/packs/js
application-dd6e88065a32b23f8e21.js
application-dd6e88065a32b23f8e21.js.br
application-dd6e88065a32b23f8e21.js.gz
application-dd6e88065a32b23f8e21.js.map
application-dd6e88065a32b23f8e21.js.map.br
application-dd6e88065a32b23f8e21.js.map.gz
hello-5eb7da4f66eb445d6332.js
hello-5eb7da4f66eb445d6332.js.br
hello-5eb7da4f66eb445d6332.js.gz
hello-5eb7da4f66eb445d6332.js.map
hello-5eb7da4f66eb445d6332.js.map.br
hello-5eb7da4f66eb445d6332.js.map.gz
<!DOCTYPE html>
<html>
  <head>
    ...
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
  ...
</html>

javascript_pack_tagの第一引数でエントリーファイルを指定する。
なので、先程のhello.jsを読み込む場合は、<%= javascript_pack_tag 'hello', 'data-turbolinks-track': 'reload' %>と書く必要がある。
(まあ実際は大概application.jsでいろいろrequireする)

1
2
// app/javascript/calendar/index.jsを読み込む
require("calendar")
p.181 パス 内容
app/javascript/packs エントリーファイルを置く場所
app/javascript/ エントリーファイルから読み込まれるモジュールを置く場所
config/webpacker.yml Webpackerの設定ファイル
config/webpack/*.js 最終的なwebpackの設定を出力するファイル
babel.config.js babel用の設定ファイル
.browserlistrc コンパイル対象となるブラウザ環境を記述するファイル

CSSや画像もWebpackerで管理する

CSSの場合

例えばapp/javascript/stylesheets/application.cssを読み込む場合、

1
require("stylesheets/application")
1
<%= stylesheet_pack_tag "application" %>

こうすればいい(development環境ではこれがなくても表示されるらしい)。

画像の場合

パスをapp/javascript/images/sample.png、エントリーポイントをapp/javascript/images/とするとき

1
require.context("../images", true)

ビューで画像を表示するときは<%= image_pack_tag("media/images/sample.png") %>
ファイルパスを表示するときは<%= image_tag(assert_pack_path("media/images/sample.png")) %>

Webpackerの拡張

loaderを追加する

$ rails webpacker:install:erbでrails-erb-loaderパッケージと設定が導入される。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ rails webpacker:install:erb

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 /Users/k_end/study/perfect_rails/hello_rails/app/javascript/packs
      create  app/javascript/packs/hello_erb.js.erb
Installing all Erb dependencies
         run  yarn add rails-erb-loader from "."
yarn add v1.22.5
...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
module.exports = {
  test: /\.erb$/,
  enforce: 'pre',
  exclude: /node_modules/,
  use: [{
    loader: 'rails-erb-loader',
    options: {
      runner: (/^win/.test(process.platform) ? 'ruby ' : '') + 'bin/rails runner'
    }
  }]
}
1
2
3
4
5
const { environment } = require('@rails/webpacker')
const erb = require('./loaders/erb') // 追加された行

environment.loaders.prepend('erb', erb) // 追加された行
module.exports = environment

environment.loadersにはWebpackerが管理しているloaderの設定ファイルが格納されている。
このenvironment変数はmodule.exports = environmentでエクスポートされ、config/webpack/development.jsなどの中でenvironment.toWebpackConfig()とされて最終的なwebpackの設定オブジェクトになる。

1
2
3
4
5
process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')

module.exports = environment.toWebpackConfig()

environment.jsに書いたenvironmentファイルはどの環境でもrequireされるので、どの環境でも利用する場合はenvironment.jsに書く。
しかし、開発環境のみで利用するときはdevelopment.js、本番環境のみのときはproduction.jsに直接記述を書く。

environment.js→環境.js→webpack というイメージ。

1
2
3
4
5
6
process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')
const erb = require('./loaders/erb') // こんな感じ
environment.loaders.prepend('erb', erb) // こんな感じ
module.exports = environment.toWebpackConfig()

pluginを追加する

ProvidePlugin(明示的なrequireをしなくてもライブラリを参照できるplugin)を利用する。
各ファイルごとにimport $ from 'jquery'を書くのを省略できる。

$ yarn add jqueryでjQueryを追加。
config/webpack/plugins/provide.jsを作成して、以下のように定義する。

1
2
3
4
5
const webpack = require('webpack')
module.exports = new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery'
});

loaderと同じようにenvironment.jsから呼び出す。

1
2
3
4
5
const { environment } = require('@rails/webpacker')
const provide = require('./plugins/provide') // 追加する

environment.plugins.prepend('provide', provide) // 追加する
module.exports = environment

これによって、requireなしでも$jQueryが使えるようになる。

Sprockets

省略。

Railsに組み込まれているJavaScriptの機能

  • rails-ujs
    • 画面制御(二重送信の防止)
    • local: trueによるAjax通信
  • Turbolinks
    • 画面遷移時にbodyタグのみ切り替える
    • window.fooのようにグローバルなオブジェクトにデータを保存すると、データが初期化されない
    • rails newのときに--skip-turbolinksで外すことができる
  • Stimulus
    • 控えめなフレームワーク
Share on

aiandrox
Written by
aiandrox
今日も楽しく明日も楽しく

目次