rollup が求めてたものだったかもしれない
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ バンドルしたものを export できる
◆ 元ファイルごとにはっきりわかれず 一つのスコープにまとめられる
◆ 元ファイルごとにはっきりわかれず 一つのスコープにまとめられる
rollup 使ってみた
あるライブラリのコードを見ていて すごく規則的ではあるんだけど無駄が多くて こんなこと手動でするかなぁ?と思うのがありましたいかにも機械的って感じですが webpack みたいなバンドルされたものって感じでもなく普通に書いたようなコードです
それでも global$1 と global$2 とか人が書かないような部分も多く気になってました
その後色々あって rollup がもしかしたらこれかもと思うことがあって 試してみたら正解でした
webpack や parcel と違って rollup はライブラリ向いてるとか聞いたことはありましたがその意味はよくわかってませんでした
ですが バンドル結果をみればその理由は明らかでした
rollup の良いところ
webpack や parcel は元のファイルの import/export 処理だけを書き換えてそれぞれを関数にするなど異なるファイルははっきりと分割されていますさらに 外部にエクスポートはしないので バンドルしたコード中の関数を外部で使いたいなどの用途には向きません
プラグインとかでどうにかできるかもですが 普通にやるとできなそうなのでグローバルに配置するなどで対処してます
1 ファイルにまとめたいけど それを外部から import したいというのには向いていません
それに比べて rollup はバンドル時にそれぞれのファイルを別に分けず変数名を変えることで 1 つのスコープにうまくマージしています
さらにエントリポイントのファイル中の export を 指定したフォーマットで export できます
いかにもライブラリ向きって感じです
以前書いた npm ライブラリが import にライブラリ名を使っていて依存解決できないせいで ES Modules をそのまま使える機会があまりないという問題も npm ライブラリのみ rollup でバンドルしてしまえば ES Modules をメインに使っていけます
バンドル結果
バンドル部分は同じスコープにまとめられますが export のフォーマットは選ぶことができます[index.js]
import x from "./x.js"
export default () => x() + 1
[x.js]
export default () => 100
[rollup.config.js]
const types = ["amd", "cjs", "esm", "system", "iife", "umd"]
module.exports = types.map(type => {
if (type === "iife" || type === "umd") {
return {
input: "index.js",
output: {
file: type + ".js",
format: type,
name: type + "_output",
},
}
} else {
return {
input: "index.js",
output: {
file: type + ".js",
format: type,
},
}
}
})
amd, cjs, esm, system, iife, umd のそれぞれを指定してバンドルしてみます
iife と umd は外側に配置するので名前も必要になります
名前は iife_output と umd_output にしてます
rollup では config ファイルを使う場合は明示的に -c を引数に設定しないといけません
名前が rollup.config.js だとパス指定は不要で -c だけでいいです
rollup -c
amd
define 関数は用意されないので このバンドルモジュールのロード前に自分で先にロードしておく必要がありますdefine(function () { 'use strict';
var x = () => 100;
var index = () => x() + 1;
return index;
});
cjs
Node.js で使える require/module.exports を使うフォーマットです'use strict';
var x = () => 100;
var index = () => x() + 1;
module.exports = index;
esm
おなじみの ESModules ですvar x = () => 100;
var index = () => x() + 1;
export default index;
system
聞いたことないですが system.js というものでロードするようのフォーマットらしいですSystem.register([], function (exports) {
'use strict';
return {
execute: function () {
var x = () => 100;
var index = exports('default', () => x() + 1);
}
};
});
iife
即時関数実行を使って返り値を外側の変数に代入します使う場所によって グローバルだったりローカルだったりです
var iife_output = (function () {
'use strict';
var x = () => 100;
var index = () => x() + 1;
return index;
}());
umd
環境に応じて適切に export してくれます(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.umd_output = factory());
}(this, function () { 'use strict';
var x = () => 100;
var index = () => x() + 1;
return index;
}));
node_modules
rollup はデフォルトだとパッケージ名を node_modules 内から探してくれませんlit-element をバンドルしようとしたら
import { TemplateResult } from 'lit-html';
というコードが残っていました
また コンソールには未解決の dependencies があると警告が出ていました
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
lit-html (imported by node_modules\lit-element\lit-element.js)
lit-html/lib/shady-render.js (imported by node_modules\lit-element\lit-element.js)
lit-html/lit-html.js (imported by node_modules\lit-element\lit-element.js)
node_modules のものをロードするには rollup-plugin-node-resolve というプラグインが必要です
こういう設定ファイルにするとバンドルできます
import resolve from "rollup-plugin-node-resolve"
module.exports = {
input: "node_modules/lit-element/lit-element.js",
output: {
file: "lit-element.js",
format: "esm",
},
plugins: [
resolve({
// pass custom options to the resolve plugin
customResolveOptions: {
moduleDirectory: "node_modules",
},
}),
],
}
出力された lit-element.js を使ってみます
[index.html]
<script type="module">
import { LitElement, html } from "./lit-element.js"
customElements.define("le-test", class extends LitElement {
render() {
return html`
<h1>lit-element is working</h1>
`
}
})
</script>
<le-test></le-test>
これを開くと h1 で lit-element is working というメッセージが表示されます
cjs
ここまでの例ではバンドル対象のファイルはすべて ES Modules でしたrollup は標準では ES Modules しか対応してません
あくまで JavaScript 標準の polyfill という立場だからみたいです
なので Node.js 用の cjs の require/module.exports を使ったファイルをバンドルしたいなら またプラグインが必要です
import commonjs from "rollup-plugin-commonjs"
module.exports = {
input: "index.js",
output: {
file: "index.bundle.js",
format: "cjs",
},
plugins: [commonjs()],
}