rollup.js と babel で script タグと npm 両対応のライブラリを作った話

  • 2
    いいね
  • 2
    コメント

rollup.js を用いて <script> と npm 両対応のライブラリ smart-dropdown-menu を作成しました。

smart-dropdown-menu

ドロップダウンメニューを作成するためのライブラリです。
大きな特徴として、mousemove イベントを利用せず、カーソルの斜め移動時(サブメニューへの移動等)に、ホバー判定を継続する処理が入っています。

smart-dropdown-menu の仕組みについては、以下のブログ記事で解説しています。
ドロップダウンメニュー用のライブラリ smart-dropdown-menu を作った - 備忘録β版

rollup.js による <script> と npm 両対応

初めは browserify を用いていたのですが、rollup.js は出力形式に umd を指定できることから、<script> による読み込みと npm による管理の両方に対応するため、移行しました。

rollup.config.js
import babel from 'rollup-plugin-babel';

export default {
  entry: 'src/js/smart-dropdown-menu.js',
  dest: 'dist/js/smart-dropdown-menu.js',
  format: 'umd',
  moduleName: 'SmartDropdownMenu',
  plugins: [
    babel()
  ]
}
.babelrc
{
    "presets": [
        [
            "es2015",
            { "modules": false }
        ]
    ],
    "plugins": ["external-helpers"]
}

rollup.js で babel を用いる場合、以前は babel-preset-es2015-rollup を用いるようになっていましたが、現在は rollup.js 用の presets を使う必要は無くなっています。

babel-plugin-external-helpers については、私のブログに記載したものがありますのでよろしければどうぞ。
babel-plugin-external-helpers について - 備忘録β版

ビルド周り

普段は gulp を使っているのですが、rollup.js, babel, gulp の組み合わせは相性が悪かったので、npm-scripts ですべて行うことにしました。

参考:ES6のgulpfile.babel.jsがrollupのpresetとconflictしたときの対処法 - Qiita

npm-run-all を用いると glob で実行するタスクを指定できるため便利です。

package.json
{
  "scripts": {
    "build:sass": "node-sass src/scss -o dist/css",
    "build:sass:watch": "node-sass -w src/scss -o dist/css",
    "build:js": "rollup -c rollup.config.js & rollup -c rollup.config.minify.js",
    "build:js:watch": "rollup -w -m inline -c rollup.config.js & rollup -w -m inline -c rollup.config.minify.js",
    "browsersync": "browser-sync start -s --startPath example --files 'example/*.html, dist/js/**/*.js, dist/css/**/*.css'",
    "build": "npm-run-all -p build:*",
    "dev": "npm-run-all -p build:*:watch browsersync",
    "version": "npm run build && git add --all",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

browser-sync と npm-run-all

開発中にブラウザを自動リロードしてほしかったため browser-sync を用いていました。

以下のように npm-run-all で browser-sync のタスクも実行しようとしていたのですが、browsersync のみが実行され build:*:watch が実行されず悩まされました。

package.json
{
  "scripts": {
    "browsersync": "browser-sync start -s --startPath example --files 'example/*.html, dist/js/**/*.js, dist/css/**/*.css'",
    "dev": "npm-run-all browsersync -p build:*:watch"
  }
}

簡単に調べたところ browser-sync は npm-run-all で直列実行ができないようで、browsersync のタスクも並列実行に含めることで対応しました。
おそらく、browser-sync の exit status が0でないことが原因ではないかと思います。

まとめ

rollup.js を使うのは初めてでしたが <script> と npm の両対応が簡単に出来たので、用途によっては browserify ではなく rollup.js を用いることを検討しても良いかと思います。