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