RailsにjQueryとBootstrap 5を入れる方法を調べながら、Rails 7のCSSとJavaScriptの新機能を調べてみました。次のようなコードを動かすのが目標です。BootstrapのjQueryプラグインを使うものです。
$('[data-bs-toggle="tooltip"]').tooltip()
あるいは、次のようにjQueryプラグインを使わない方法でもよしとします。
$('[data-bs-toggle="tooltip"]').each((idx, elm) => {
new bootstrap.Tooltip(elm)
})
Webpacker(Rails 6.1)
まず、Rails 7の新機能を使わず、Rails 6にWebpackerで導入する方法です。yarnでBootstrap 5、Popper 2、jQueryを入れます。
% yarn add bootstrap @popperjs/core jquery
BootstrapのCSS部分を導入します。app/javascript の下に stylesheets というフォルダを作り、application.scss を作成して、次のように記述します。
@import "~bootstrap/scss/bootstrap";
これを packs/application.js で import します。
import "../stylesheets/application"
レイアウトに stylesheet_pack_tag を加えます。
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
BootstrapのJavaScript部分を導入します。Rails 6にjQueryとBootstrapを入れる で紹介した ProvidePlugin を使う方法は、Bootstrap 5では効きません。
そこで、グローバル変数として使えるように、単純に window オブジェクトに $ と jQuery を加えることにします。ついでに bootstrap もグローバル変数として使えるようにしておきます。
import jquery from "jquery"
window.$ = window.jQuery = jquery
import * as bootstrap from "bootstrap"
window.bootstrap = bootstrap
import "../stylesheets/application"
esbuild(Rails 7)
※ここから先を読まれる方は、別記事 JavaScript BundlingとCSS Bundlingのしくみ を先にごらんください。
Rails 7とesbuildの組み合わせを試します。次のコマンドでRailsアプリケーションを作成します。yarnによって、esbuild、Bootstrap、Popper、およびsassが node_module 下にインストールされます。
% rails new app -j esbuild --css bootstrap
jQueryをyarnで入れておきます。
% yarn add jquery
BootstrapのCSSは、application.bootstrap.scss で取り込まれます。自分のCSSを追加するには、このscssに追加するか、このscssにインポートします。なお、別記事に書いたように、このファイル名は好きに変えられます。
@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons';
JavaScript側は、app/javascript/packs ではなく、app/javascript ディレクトリのすぐ下にエントリーポイントとなる application.js ができます。
上記のWebpacker(Rails 6.1)と同じコードを試します。すると、BootstapのjQueryプラグインが効きません。
import jquery from "jquery"
window.$ = window.jQuery = jquery
import * as bootstrap from "bootstrap"
window.bootstrap = bootstrap
これは、import * as bootstrap from "bootstrap"
が window.$ = window.jQuery = jquery
よりも先に実行されるためです。Bootstrapが初期化されるときに window.jQuery
が存在しないのでjQueryプラグインが設定されない、というわけです。
require を使えば、Bootstrapの初期化を後にしてjQueryプラグインが使えるようになります。
import jquery from "jquery"
window.$ = window.jQuery = jquery
window.bootstrap = require("bootstrap")
「今どきのJavaScriptでグローバル変数はダサい」という方は、各JSファイルにimportを書きましょう。
import $ from 'jquery'
import { Tooltip } from "bootstrap"
$('[data-bs-toggle="tooltip"]').each((idx, elm) => {
new Tooltip(elm)
})
package.jsonの中身を確認しておきましょう。コマンドyarn build
を実行すると、esbuildコマンドでJSファイルが変換されます。コマンドyarn build:css
では、sassコマンドでCSSファイルが変換されます。
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
binディレクトリの下のdevコマンドでRailsを起動します。JSやCSSのファイルが更新されるごとに自動的にファイルが変換されるようになります。
% bin/dev
webpack(Rails 7)
Rails 7とwebpackの組み合わせを試します。Webpackerなしでwebpackを使うものです。次のコマンドでRailsアプリケーションを作成します。yarnによって、webpack、Bootstrap、Popper、sassが node_module 下にインストールされます。
% rails new app -j webpack --css bootstrap
yarnでjQueryを入れておきます。
% yarn add jquery
esbuildの場合と同じく、BootstrapのCSSは、application.bootstrap.scss で取り込まれます。
@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons';
esbuildの場合と同じく、BootstrapのjQueryプラグインを使うには、jQueryをグローバル変数にしたあとでrequireを使ってBootstrapを取り込む必要があります(同じwebpackなのにWebpackerを使った場合と挙動が変わる原因は不明)。
import jquery from "jquery"
window.$ = window.jQuery = jquery
window.bootstrap = require("bootstrap")
package.jsonの中身を見てみましょう。コマンドyarn build
を実行すると、webpackコマンドでJSファイルが変換されます。webpackの設定ファイルはアプリケーションのルートにできる webpack.config.js です。
"scripts": {
"build": "webpack --config webpack.config.js",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
webpack.config.js に少し手を加えます。オブジェクトprocess.env
で環境変数RAILS_ENV
とNODE_ENV
が使えるようにしておいて、modeオプションにproduction
かdevelopment
を指定します。こうしておくと、JSがminify(圧縮)されるのはproduction環境の場合だけになります。
エントリーポイントとなるJSファイルの名前や場所を変えたいときは、application: "./app/javascript/application.js"
の行を修正します。
const path = require("path")
const webpack = require("webpack")
process.env.RAILS_ENV = process.env.RAILS_ENV || 'development'
process.env.NODE_ENV = process.env.NODE_ENV || process.env.RAILS_ENV
module.exports = {
mode: ['development', 'production'].includes(process.env.NODE_ENV) ? process.env.NODE_ENV : 'development',
devtool: "source-map",
entry: {
application: "./app/javascript/application.js"
},
output: {
filename: "[name].js",
sourceMapFilename: "[name].js.map",
path: path.resolve(__dirname, "app/assets/builds"),
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
]
}
binディレクトリの下のdevコマンドでRailsを起動します。JSやCSSのファイルが更新されるごとに自動的にファイルが変換されるようになります。
% bin/dev
rollup(Rails 7)
rollupを使った場合はどうもうまくいきませんでした。jQueryがインポートできない、Popperが動かない。あきらめるとこととします。
importmap(Rails 7)
importmapを使った例は、「Rails 6/7にjQueryとBootstrap 5を入れる(その2)」に書く予定です。
esbuild/webpack(Rails 6.1)
Rails 6を使いつつRails 7のJavaScriptに移行するつもりなら、Rails 6にJavaScript BundlingとCSS Bundlingを導入して、esbuildやwebpackを使ってみるとよいでしょう。
まず、JavaScript BundlingとCSS BundlingをBundlerで入れます。
gem "jsbundling-rails"
gem "cssbundling-rails"
% bundle install
次のコマンドでインストールと初期設定ができます。webpackの場合はbin/rails javascript:install:webpack
とします。
% bin/rails javascript:install:esbuild
% bin/rails css:install:bootstrap
yarnでjQueryを入れておきます。
% yarn add jquery
CSS Bundlingのエントリーポイントとなる application.bootstrap.scss を確認します。
@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons';
JavaScript Bundlingのエントリーポイントとなる application.js でjQueryとBootstrapをインポートします。上記の「esbuild(Rails7)」での説明をごらんください。
import jquery from "jquery"
window.$ = window.jQuery = jquery
window.bootstrap = require("bootstrap")
package.jsonに追加されたコマンドを確認します。内容については、上記の「esbuild(Rails7)」での説明をごらんください。また、webpackの場合は上記の「webpack(Rails 7)」と同様に、webpack.config.js で設定をカスタマイズできます。
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
binディレクトリの下のdevコマンドでRailsを起動します。
% bin/dev
既存のアプリケーションで作ったJavaScriptやCSSを生かしつつ、JavaScript BundlingとCSS Bundlingを使うには、既存のJavaScript/CSSと同居させるを参照してください。