最近、モダンなフロントエンドの現場では、ReactやVue.jsといった技術が使用されることが増えました。
しかし今でも、ちょっとしたDOM操作をしたいときに、jQueryを使用すると便利な場面がたまにあります。
jQueryを使いたいけど、せめて、jQueryのインポートにはモダンな技術を使いたい。
というわけで、最近、jQueryをES Modules形式でインポートしようとしたのですが、
なかなかうまくいかず、苦戦しましたので、備忘録もかねて、解決策を解説させていただきます。
この記事で書かないこと
- Rollup の使い方
- ES Modulesについての説明
上記はこの記事では解説しません。適宜ご自身でお調べください。
(前提条件)Rollupの設定
前提条件として、今回は、Rollupでビルド・バンドルする場合の手順を解説いたします。
Rollupの設定は下記のとおりです(今回の解説に必要な最低限の構成にしています)。
import resolve from 'rollup-plugin-node-resolve'
export default {
input: 'src/js/hoge.js',
output: {
file: 'dist/js/hoge.js',
format: 'iife',
},
plugins: [ resolve() ]
}
発生するエラーとその原因
まず、npmでjQueryをインストールします。
npm i jquery
続きまして、 hoge.js というファイルで、次のように、jQueryをインポートしてみます。
import $ from 'jquery'
すると、ビルド時に、下記のエラーが発生します。
Error: 'default' is not exported by node_modules/jquery/dist/jquery.js, imported by hoge.js
原因は、jQueryのソースコードを読めば、すぐにわかります。
そもそもES Modules形式でのインポートがサポートされていないのです。
個人的にjQueryに期待していただけに、ちょっと残念でした…
解決策
jQueryのソースコードを読むと、 window.jQuery
と window.$
というグローバル変数をセットしているということがわかります。
そこで、次のようなファイルを作成すると、ES Modules形式でjQueryをエクスポートできます。
import 'jquery'
export default window.jQuery
しかし、せっかくES Modulesで管理しているのに、グローバルスコープが汚染されるのは気持ち悪いですよね。
そこで、jQueryの公式ドキュメントを読むと、 noConflict
メソッドを呼び出すと、jQueryがセットしたグローバル変数を消し去ることができるということがわかります。
https://api.jquery.com/jquery.noconflict/
そして、このメソッドは戻り値としてjQuery自身を返します。
ということは、先ほどのファイルを、次のように書き換えると、グローバルスコープを汚さずにjQueryをエクスポートできます。
import 'jquery'
export default window.jQuery.noConflict(true)
あとは、このファイルをふつうにインポートするだけでjQueryが使えます!
import $ from './jquery.esm'
おまけ
jQueryは便利な機能が多数搭載されている反面、ファイルサイズが大きくなりがちです。
アニメーションやAjax系のメソッドを使わないのであれば、Slim版を使用することによってファイルサイズを抑えることができます。
その場合、 jquery.esm.js を下記の通り書き換えましょう。
import 'jquery/dist/jquery.slim'
export default window.jQuery.noConflict(true)