TL;DR
解決策の節をどうぞ。
この記事を書いた環境は次の通りです
- ruby: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
- rails: Rails 7.0.5
- node: v18.6.0
- yarn: 3.5.1
CSS Bundling for Rails
Rails7ではrails new
するときにCSSツールを指定できるオプション-c
/--css
があります。
$ bundle exec rails new --help
Usage:
rails new APP_PATH [options]
Options:
~~~ 省略
-c, [--css=CSS] # Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass] check https://github.com/rails/cssbundling-rails
~~~ 省略
tailwind、bootstrap、bulma、postcss、saasなど色々と選択肢があります。
私の場合Bootstrapを自身で組み込んで使うことが多いため、これは便利!と思い使ってみました。
$ bundle exec rails new . -c=bootstrap
ところが、以下のエラーが出て止まってしまいます。
Add build:css script
run npm pkg set scripts.build:css="sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" from "."
run yarn build:css from "."
Error: Can't find stylesheet to import.
╷
1 │ @import 'bootstrap/scss/bootstrap';
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
app/assets/stylesheets/application.bootstrap.scss 1:9 root stylesheet
ファイルが見つからないと言われているので探してみたところ.yarn/cache
ディレクトリの下に何か色々ありました。
...あれ? node_modules
ディレクトリ下ではないの? そもそもnode_modules
はいずこへ...?
Yarn 2 (Berry) なるもの
調べてみたところ、yarn v2にまつわる誤解 | Wantedly Engineer Blogという記事にたどり着きました。
node-modulesモードでは旧来のパッケージ管理ツールと同様にnode_modulesディレクトリが生成されるので、これによりかなりの互換性が担保されます。
まさにこれが原因では...
という訳で解決策です。
解決策
Add nodeLinker: node-modules in your .yarnrc.yml file
ということで、もう一度新しいディレクトリを作成、.yarnrc.yml
ファイルを以下のように作成。
nodeLinker: node-modules
✅node-modules
です。🛑node_modules
ではありません!!! 罠ですか?
続いてbundle init
してGemfile
を書いて、(bundle config
して)bundle
を実行、そしてrails new
をやり直してみました。
$ bundle exec rails new . -c=bootstrap
今度はnode_modules
ができました。
そしてコマンドは無事終了し、bin/dev
でサーバーを立ち上げるといつもの画面にアクセスできました。
まとめ
原因はRailsの外側、Yarnの仕様変更にあった、というお話でした。
もう少し詳しく調べていたところ、Rails本家のディスカッションに同じ回答がありました。1
が、どうも全体としては的を射ない流れになっているようです。
探し方の問題かも知れませんがこの他に情報らしい情報は見つけられませんでしたので、この機能を皆さん使っていないのか興味が無いのか...
Yarnという外部ツールに依存する形でRails側の実装を変えるべきなのか、といったことは私には何ともいえません。
願わくばRuby周りのことだけ考えていたいですね、という【RubyKaigi 2023連動イベント】みんなでRubyの知見を共有しよう向けの記事でした。