Slide 1

Slide 1 text

Importmapを使ったJavaScriptの 読み込みとブラウザアドオンの影響 2024/10/26 Kaigi on Rails 2024 swamp09

Slide 2

Slide 2 text

沼田 周 @swamp09 株式会社 永和システムマネジメント 現在はECサイトの開発プロジェクトに所属

Slide 3

Slide 3 text

● import mapsの概要 ● importmap-railsを使う経緯 ● 実際に使ってみて起こった問題

Slide 4

Slide 4 text

私のプロジェクトでのRailsアップデート業 Rails 6 -> Rails 7

Slide 5

Slide 5 text

Rails 7

Slide 6

Slide 6 text

Rails 7 Hotwire登場!

Slide 7

Slide 7 text

Webpackerの終わり

Slide 8

Slide 8 text

https://github.com/rails/webpacker

Slide 9

Slide 9 text

移行先

Slide 10

Slide 10 text

移行先 js-bundling-rails or importmap-rails

Slide 11

Slide 11 text

js-bundling-rails Webpackやesbuildを使うもの

Slide 12

Slide 12 text

Rails 7 でデフォルトになった importmap-rails ってなに?

Slide 13

Slide 13 text

// HTTPパス import dayjs from 'https://cdn.skypack.dev/[email protected]' // 相対パス import dayjs from './node_modules/dayjs' Import maps

Slide 14

Slide 14 text

{ "imports": { "dayjs": "https://cdn.skypack.dev/[email protected]", } } import dayjs from 'dayjs'; // ↓と同じになる // import dayjs from 'https://cdn.skypack.dev/[email protected]' Import maps

Slide 15

Slide 15 text

import dayjs from 'dayjs' JSモジュールをCDNから node_modulesへダウンロード node_modulesにあるものを importする Webpackやesbuildのようなビルドツールで application.jsなどにビルドする いままでは

Slide 16

Slide 16 text

node_modulesを使わず ブラウザ上でモジュールを読み込める ビルドしなくていい

Slide 17

Slide 17 text

https://caniuse.com/import-maps モダンブラウザでは安心して使える

Slide 18

Slide 18 text

importmap-rails # config/importmap.rb pin "dayjs", to: "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js"

Slide 19

Slide 19 text

importmap-rails # config/importmap.rb pin "dayjs", to: "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js" # application.html.erb <%= javascript_importmap_tags %>

Slide 20

Slide 20 text

importmap-rails # config/importmap.rb pin "dayjs", to: "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js" # application.html.erb <%= javascript_importmap_tags %> { "imports": { "dayjs": "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js" } }

Slide 21

Slide 21 text

これがなんでRails 7から デフォルトになったのか

Slide 22

Slide 22 text

https://world.hey.com/dhh/modern-web-apps-without-javascrip t-bundling-or-transpiling-a20f2755

Slide 23

Slide 23 text

Babelでのトランスパイル 不要になった

Slide 24

Slide 24 text

HTTP2が当たり前に使われるようになった 一つのJSファイルにまとめなくていい

Slide 25

Slide 25 text

私のプロジェクト Webpackerからの移行

Slide 26

Slide 26 text

Webpackのままjs-bundling-rails使うか?

Slide 27

Slide 27 text

https://bun.sh/docs/bundler/vs-esbuild

Slide 28

Slide 28 text

importmap-rails使う?

Slide 29

Slide 29 text

Q. ビルドツールいらないの?

Slide 30

Slide 30 text

A. いらない TypeScript: 使ってなかった Vue.js: ちょっと使ってた、けどStimulusに移行する方針で決まった

Slide 31

Slide 31 text

https://twitter.com/robbyrussell/status/1712134715434819872

Slide 32

Slide 32 text

https://www.youtube.com/watch?v=-cEn_83zRFw

Slide 33

Slide 33 text

JSをno buildにして importmap-railsでやっていく

Slide 34

Slide 34 text

しばらくして

Slide 35

Slide 35 text

サーバーサイドに奇妙なエラー

Slide 36

Slide 36 text

ログを調査していると

Slide 37

Slide 37 text

Processing by PostsController#update as TURBO_STREAM のようなリクエストのはずが、 Processing by PostsController#update as HTML となっている

Slide 38

Slide 38 text

直接リクエストしている疑い?

Slide 39

Slide 39 text

直接リクエストしている疑い? ログを見た限りそんなことはない

Slide 40

Slide 40 text

Turbo が動いていないかも

Slide 41

Slide 41 text

Honeybadgerという エラートラッキングサービスを 使っているが通知はなし https://www.honeybadger.io/

Slide 42

Slide 42 text

ユーザーの環境の問題?

Slide 43

Slide 43 text

ユーザーの環境の問題? エラーユーザーは最新バージョンのブラウザを使っている ChromeやFirefoxユーザーがいる

Slide 44

Slide 44 text

同じブラウザでも再現しない

Slide 45

Slide 45 text

同じブラウザでも再現しない Addonか?

Slide 46

Slide 46 text

よく使われるAddonってなに?

Slide 47

Slide 47 text

Adblockをいれるとエラーになる

Slide 48

Slide 48 text

// application.js import "@hotwired/turbo-rails" import { Application } from "@hotwired/stimulus" import Honeybadger from "@honeybadger-io/js" Honeybadger.configure({ apiKey: ’aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa’ , }) const application = Application.start()

Slide 49

Slide 49 text

Adblockはいろいろある

Slide 50

Slide 50 text

Adblockが使うフィルターリスト

Slide 51

Slide 51 text

https://github.com/easylist/easylist

Slide 52

Slide 52 text

EasyPrivacyの中に関係あるものを発見

Slide 53

Slide 53 text

なるほど?

Slide 54

Slide 54 text

# config/importmap.rb pin "@honeybadger-io/js", to: "https://ga.jspm.io/npm:@honeybadger-io/[email protected]/dist/browser/honeybadger.js" { "imports": { "@honeybadger-io/js": "https://ga.jspm.io/npm:@honeybadger-io/[email protected]/dist/browser/honeybadger.js", ... } }

Slide 55

Slide 55 text

importmap-railsに移行して起きた問題

Slide 56

Slide 56 text

importmap-railsで使用するモジュールを ダウンロードする

Slide 57

Slide 57 text

この問題が起きた時使用していたのは importmap-rails v1.2 bin/importmap pin xxx --download のようにdownloadオプションを使用して vendorディレクトリに保存する

Slide 58

Slide 58 text

# config/importmap.rb pin "@honeybadger-io/js" , to: "@honeybadger-io--js.js" { "imports": { "@honeybadger-io/js": "/assets/@honeybadger-io--js-98f68298ce509dfd7b221dfbdde2cf6c4fe60e97359d baed12ddaa7ad7c8c403.js", ... } } SprocketsかPropshaftでフィンガープリントがつく

Slide 59

Slide 59 text

importmap-rails v2では vendorへのダウンロードが デフォルトの挙動になった

Slide 60

Slide 60 text

引き続き外部CDNの使用もしている importmap-railsのダウンロードで うまく使えないものもある

Slide 61

Slide 61 text

JSのライブラリの中には 1つのエントリポイントに 機能がまとまっていない場合がある

Slide 62

Slide 62 text

importmap-railsでは 一つのエントリファイルしか ダウンロードしない

Slide 63

Slide 63 text

さっくりダウンロードできるもの以外は 外部CDNをそのまま使っている

Slide 64

Slide 64 text

外部CDNを使う場合は Adblockにブロックされるかも

Slide 65

Slide 65 text

似たような問題が起きたときに 気づけるようにしたい 主要な機能でのTurbo Streamリクエストに リクエスト形式チェックを入れている

Slide 66

Slide 66 text

まとめ

Slide 67

Slide 67 text

● importmap-railsはjsのビルドの手間が改善できてよかった ● importしたいJSモジュールがAdblockによってブロックされる ケースがある ● 最新のimportmap-railsはデフォルトでvendorへJSモジュール をダウンロードする ● JSモジュールがAdblockにブロックされることは今後もあるかも しれないので、そうなったときに気づけるようにしたい まとめ

Slide 68

Slide 68 text

おわり ● Turboを使っている場合はリクエストの形式で違和感に気づく ことができるが、他にいい方法あるんだろうか? ● importmap使っていて困ったことがあったらぜひ共有してほし いです

Slide 69

Slide 69 text

おまけ

Slide 70

Slide 70 text

nodelessにできていない ESLintはいらないの? Playwrightを使いたい おまけ