rollup の rollup-starter-lib を試した。
https://github.com/rollup/rollup-starter-lib の README の Getting started に従う。
$ git clone https://github.com/rollup/rollup-starter-lib # ... $ cd rollup-starter-lib $ npm install # ... $ exa -T --git-ignore --group-directories-first . ├── src │ ├── lunchtime.js │ ├── main.js │ └── millisecondsUntil.js ├── test │ └── test.js ├── LICENSE ├── package-lock.json ├── package.json ├── README.md └── rollup.config.js
package.json
まずは package.json
を見る
{ "name": "rollup-starter-lib", "version": "1.0.0", "main": "dist/how-long-till-lunch.cjs.js", "module": "dist/how-long-till-lunch.esm.js", "browser": "dist/how-long-till-lunch.umd.js", "dependencies": { "ms": "^2.0.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^11.0.1", "@rollup/plugin-node-resolve": "^7.0.0", "rollup": "^1.29.0" }, "scripts": { "build": "rollup -c", "dev": "rollup -c -w", "test": "node test/test.js", "pretest": "npm run build" }, "files": ["dist"] }
main
/ module
/ browser
でエントリポイントを書き分けてあるのが印象的だ。各環境に一気に対応できるのだろう。あとで dist
に生成されるものを確認する。
dependencies
の ms
は用意されている例 src/main.js
から使われているようだ。
devDependencies
の @rollup/plugin-*
が気になるけど後回しにする。
scripts
は rollup -c
を何かしら動かすっぽい。 rollup -c -w
の -w
はたぶん watch
だろう。
$ (npm bin)/rollup --help rollup version 1.29.0 ===================================== Usage: rollup [options] <entry file> Basic options: -c, --config <filename> Use this config file (if argument is used but value is unspecified, defaults to rollup.config.js) -d, --dir <dirname> Directory for chunks (if absent, prints to stdout) -e, --external <ids> Comma-separate list of module IDs to exclude -f, --format <format> Type of output (amd, cjs, esm, iife, umd) -g, --globals <pairs> Comma-separate list of `moduleID:Global` pairs -h, --help Show this help message -i, --input <filename> Input (alternative to <entry file>) -m, --sourcemap Generate sourcemap (`-m inline` for inline map) -n, --name <name> Name for UMD export -o, --file <output> Single output file (if absent, prints to stdout) -v, --version Show version number -w, --watch Watch files in bundle and rebuild on changes --amd.id <id> ID for AMD module (default is anonymous) --amd.define <name> Function to use in place of `define` --assetFileNames <pattern> Name pattern for emitted assets --banner <text> Code to insert at top of bundle (outside wrapper) --chunkFileNames <pattern> Name pattern for emitted secondary chunks --compact Minify wrapper code --context <variable> Specify top-level `this` value --dynamicImportFunction <name> Rename the dynamic `import()` function --entryFileNames <pattern> Name pattern for emitted entry chunks --environment <values> Settings passed to config file (see example) --no-esModule Do not add __esModule property --exports <mode> Specify export mode (auto, default, named, none) --extend Extend global variable defined by --name --footer <text> Code to insert at end of bundle (outside wrapper) --no-freeze Do not freeze namespace objects --no-indent Don't indent result --no-interop Do not include interop block --inlineDynamicImports Create single bundle when using dynamic imports --intro <text> Code to insert at top of bundle (inside wrapper) --namespaceToStringTag Create proper `.toString` methods for namespaces --noConflict Generate a noConflict method for UMD globals --no-strict Don't emit `"use strict";` in the generated modules --outro <text> Code to insert at end of bundle (inside wrapper) --preferConst Use `const` instead of `var` for exports --preserveModules Preserve module structure --preserveSymlinks Do not follow symlinks when resolving files --shimMissingExports Create shim variables for missing exports --silent Don't print warnings --sourcemapExcludeSources Do not include source code in source maps --sourcemapFile <file> Specify bundle position for source maps --strictDeprecations Throw errors for deprecated features --no-treeshake Disable tree-shaking optimisations --no-treeshake.annotations Ignore pure call annotations --no-treeshake.propertyReadSideEffects Ignore property access side-effects --treeshake.pureExternalModules Assume side-effect free externals Examples: # use settings in config file rollup -c # in config file, process.env.INCLUDE_DEPS === 'true' # and process.env.BUILD === 'production' rollup -c --environment INCLUDE_DEPS,BUILD:production # create CommonJS bundle.js from src/main.js rollup --format=cjs --file=bundle.js -- src/main.js # create self-executing IIFE using `window.jQuery` # and `window._` as external globals rollup -f iife --globals jquery:jQuery,lodash:_ \ -i src/app.js -o build/app.js -m build/app.js.map Notes: * When piping to stdout, only inline sourcemaps are permitted For more information visit https://rollupjs.org
-w
は --watch
で正解だった。 -c
は --config rollup.config.js
のことだった。
rollup.config.js
rollup.config.js
を見る。
import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs"; import pkg from "./package.json"; export default [ // browser-friendly UMD build { input: "src/main.js", output: { name: "howLongUntilLunch", file: pkg.browser, format: "umd", }, plugins: [ resolve(), // so Rollup can find `ms` commonjs(), // so Rollup can convert `ms` to an ES module ], }, // CommonJS (for Node) and ES module (for bundlers) build. // (We could have three entries in the configuration array // instead of two, but it's quicker to generate multiple // builds from a single configuration where possible, using // an array for the `output` option, where we can specify // `file` and `format` for each target) { input: "src/main.js", external: ["ms"], output: [ { file: pkg.main, format: "cjs" }, { file: pkg.module, format: "es" }, ], }, ];
export default [ /* ... */ ];
で 2 つの要素が指定されている。
1 つめの要素は UMD ビルド。 src/main.js
を入力にして package.json
の browser
で指定された位置に umd
として出力する。プラグインとして @rollup/plugin-node-resolve
と @rollup/plugin-commonjs
を使用している。プラグインは素朴に import
して関数を呼び出す形で適用するようだ。 node-resolve
はおそらく TypeScript の moduleResolution: node
相当の動作を実現するもので commonjs
は CJS で書かれた ms
パッケージを ESM に変換するためのものだろう。
2 つめの要素は CJS および ESM ビルド。先のものとは出力先やプラグインなどが異なる。そういう基準で要素を分割しているのだろう。src/main.js
を読んで package.json
の main
/ module
にそれぞれ CJS と ESM で出力する。さっきのもそうだが package.json
の記述を流用しているのが良い。 external
はバンドル対象から外して外部のままにしておくのだろう。
ドキュメントを読んでいないので推測だけどわりと雰囲気で読める設定だ。
npm run build
README.md
の手順に戻って npm run build
しよう。 rollup --config rollup.config.js
相当だ。
$ npm run build # ... src/main.js → dist/how-long-till-lunch.umd.js... created dist/how-long-till-lunch.umd.js in 46ms src/main.js → dist/how-long-till-lunch.cjs.js, dist/how-long-till-lunch.esm.js... created dist/how-long-till-lunch.cjs.js, dist/how-long-till-lunch.esm.js in 6ms $ exa -T dist/ dist ├── how-long-till-lunch.cjs.js ├── how-long-till-lunch.esm.js └── how-long-till-lunch.umd.js
dist/
に 3 ファイルが生成されている。
ざっと中身を確認したあともとのファイルである src/
を見る。
$ exa -T src/ src ├── lunchtime.js ├── main.js └── millisecondsUntil.js
各環境向けに 3 ファイルを 1 つにバンドルしているようだ。
src/main.js
からの ↓ で参照している箇所が消えている。
import lunchtime from "./lunchtime.js"; import millisecondsUntil from "./millisecondsUntil.js";
rollup.config.js
の指定どおりではあるが dist/*.cjs.js
と dist/*.esm.js
には ms
が外部モジュールを参照する形で残っている。 dist/*.umd.js
では ms
もバンドルされている。
なるほど。
umd の設定を変えてみる
rollup.config.js
の UMD の設定を変えてみる。
// ... { input: "src/main.js", external: ["ms"], // external を追加 output: { name: "howLongUntilLunch", file: pkg.browser, format: "umd", globals: { // output.globals を追加 ms: "globalMs", }, }, // plugins を削除 } // ...
最初 external: ["ms"]
だけを追加して npm run build
したら ↓ のように output.globals
を指定しろと言われた。
src/main.js → dist/how-long-till-lunch.umd.js... (!) Missing global variable name Use output.globals to specify browser global variable names corresponding to external modules ms (guessing 'ms') created dist/how-long-till-lunch.umd.js in 27ms
予想通りバンドル対象から ms が外れて代わりに global.globalMs
が参照されるようになった。
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('ms')) : typeof define === 'function' && define.amd ? define(['ms'], factory) : (global = global || self, global.howLongUntilLunch = factory(global.globalMs)); }(this, (function (ms) { 'use strict'; // ...
npm run dev
& npm test
npm run build
(rollup -c
) を watch して動かすだけなので特に書くことはなさそうだ。
npm test
も特に固有の要素はなさそうなので飛ばす。
TypeScript
README に https://github.com/rollup/rollup-starter-lib/tree/typescript
に TypeScript の例もあるっぽいので試してみる。
違いを挙げる。
package.json
のdevDependencies
にrollup-plugin-typescript
とts-node
とtslib
とtypescript
が追加された。ts-node
はnpm test
のためのものっぽい。
rollup.config.js
の各ビルドのplugins
にtypescript()
が追加された。tsconfig.json
が追加された。- 拡張子が js -> ts に変更された。
うん。良さそうだ。
リングフィットアドベンチャー 10 日目 レベル 30 ワールド 4 を終えた。
ABC172 死。