GulpでRollupを使う / rollup-stream、rollup

GulpでRollupを使う / rollup-stream、rollup

gulpでRollupを動かして、Babelで処理するJavaScriptライブラリ作成の環境づくりを試してみました。主にrollup-streamとrollupについて触れてます。

プロジェクトの準備

npm init -ytouchするなどして、Gulpを使う前提のプロジェクトを用意します。

環境

  • node: 12.3.1
  • npm: 6.9.0
  • gulp: 4.0.2
  • macOS: 10.14

ファイルの基本構成

rollupの設定はgulfile.jsではなくrollup.config.jsにCommonJS形式で記述し、pugからコンパイルされたhtmlにスクリプトを読み込んで挙動を確認する前提の構成です。

project-name/
    ├ _src/ // 作業ディレクトリ
    │   ├ pug/ // 静的サイトファイル作成用
    │   └ js/ // javascript管理用
    │      └ app.js // 本体
    │      └ foo.js // クラス
    ├ .project.json // pug用
    ├ .babelrc // Babel用の設定ファイル
    ├ build/ // コンパイルファイル格納用
    │   ├ index.html // 挙動確認用html
    │   └ js/
    │      └ bundle.js // コンパイルファイルされたjavascript
    ├ node_modules/
    ├ gulpfile.js
    ├ package.json
    └ rollup.config.js // Rollup用の設定ファイル

foo.jsとapp.js / ES2015

コンソールログを返すだけのクラスを定義したfoo.jsをapp.jsに読み込ませてコンパイルします。

foo.js

class Foo {
  bar() {
    console.log('bar');
  }
}
export default Foo;

app.js

import Foo from "./foo.js";
let foo = new Foo;
foo.bar();

JavaScriptの出力内容

ブラウザとnode両方で挙動を確認したかったので、UMD形式で出力します。

Babelの設定

あらかじめ、Babelの設定を済ませておきます。Babel本体とトランスパイル(変換)する内容を指定するための@babel/present-envをインストールします。

npm i -D @babel/core @babel/preset-env

.babelrc

対応ブラウザを記述しておきます。Rollupの場合、"modules": falseは必要ないかもしれませんが、一応入れておきます。

今回は、必要最低限のコードとして出力させたかったので「loose」モードを指定してあります。指定するとコンパイル後のスクリプトから、下記のコードが除外されます。

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

Rollupでバベるためのモジュールをインストール

rollup-plugin-babel

今回はrollup.config.jsに読み込んで使います。

npm i -D rollup-plugin-babel

これでBabelの設定は最低限できました。

rollup-streamを使う

rollup-streamを動かすためにモジュールを追加インストールする必要があったり、pipeで繋げるべき内容で迷ったりして、少しハマリました。

npm i -D rollup-stream vinyl-buffer vinyl-source-stream

rollup.config.js

gulpfile.js

rollupを使う

gulpfile.js内にrollupの方法で記述したので変に迷うことはなかったです。追加モジュールも必要ないし、こちらの方がラクかもしれません。

npm i -D rollup

rollup.config.js

gulpfile.js

コンパイル結果

bundle.js

(function (factory) {
  typeof define === 'function' && define.amd ? define(factory) :
  factory();
}(function () { 'use strict';

  var Foo =
  /*#__PURE__*/
  function () {
    function Foo() {}

    var _proto = Foo.prototype;

    _proto.bar = function bar() {
      console.log('bar');
    };

    return Foo;
  }();

  var foo = new Foo();
  foo.bar();

}));

以上の内容でブラウザのコンソールとnodeで「bar」を確認できました。exportsやmodule.exportsを使ってモジュールファイル(今回の場合はfoo.js)を作り、requireさせて実行するようなファイル構成にした場合は、下記のような始まりになるようです。

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.test = factory());
}(this, function () { 'use strict';
...

node

$ node build/js/bundle.js
bar

実際に使う場合は、rollup.config.jsのpluginにCommonJS用のモジュールなどを指定する必要はありますが、必要最低限の動作検証はできました。

ちなみにJSをトランスパイルして、まとめる作業を「コンパイル」と呼んでいいのかは定かではないです。

通常のRollupのように使う(2019.6.11追記)

元々、Rollupの設定ファイルはESNextで記述することになっていて、ファイル名を「rollup.config.js」にすることで設定内容が自動で読み込まれます。そのようにする方法がCreating a React library using Rollup & Gulp – Gilad lev-ari – Mediumで紹介されていましたので、記事を参考に書き直してみました。gulpタスク内でsrcの読み込みをfalseにしたうえで、gulp-shellを使ってRollupをシェルで実行させれば済むようです。

npm i -D gulp-shell

rollup.config.js

gulpfile.js

gulpfileに設定を記述する方法

Rollup公式のドキュメントに掲載されてます(あとで気づきました)。

bubleを使う(2019.9.02追記)

babelの代わりにbubleを使うと、設定が少しラクです。

インストール

npm i -D rollup-plugin-buble

rollup.config.js

以上です。

参考