◆ 入れたい機能を選択できるけど minify 機能がないなど設定はあまりできない
◆ バンドラーは webpack

polyfill を bundle に含める必要なさそう

前の記事でも書いたように @babel/polyfill が deprecated になりました
代わりの core-js を使って import して bundle に含める方法は使ってみたのですが bundle に含めない方法は触れてませんでした
@babel/polyfill では minify 済みのファイルも用意されていて単純にロードすることもできました

考えてみると自分が作る部分の bundle.js ファイルと polyfill の JavaScript ファイルはまとめる必要がないと思います
毎回更新する bundle.js に polyfill を含めると毎処理ごとに polyfill まで解析したり結合したりが必要になります
分けておいたほうがバンドル処理が高速になると思いますし ブラウザに送るときも変化があった部分だけを送信して 変わらない polyfill 部分はキャッシュが使われるなどのメリットもありそうです
あとはこっちの記事などで書いたように読み込み順によっては IE でスタックオーバーフローが発生します
確認してるものはどれも polyfill を一番最初にロードすれば回避できるので別ファイルにして最初にロードするのが安全です

core-js 版の polyfill ファイル

@babel/polyfill には polyfill だけを 1 ファイルにバンドルして minify までしたものがありました
core-js もこういうファイルがほしいと探してみると core-js-bundle というパッケージが用意されてました

中には minify していない index.js と minify 済みの minified.js があります
ライブラリだと rollup が多そうですがバンドラーには webpack が使われていました

これをそのまま使うのでも良いのですが core-js プロジェクトにはカスタムしたバンドルを作成するための core-js-builder というのもあります
せっかくなので これを使ってみることにします

core-js-builder

core-js-builder 自体はすごく小さなもので 50 行くらいの index.js で webpack を呼び出しています

設定も少なくて 含める modules の配列と そこから除外する blacklist の配列と ターゲットのブラウザと 出力ファイル名くらいです
モジュールやターゲットブラウザから含めるモジュールファイルをフィルタしてそれを webpack の entry に設定します

webpack のモードは none 固定で webpack オプションを渡すこともできないので minify はできません
自分でやる必要ありです
webpack の設定をいろいろいじりたいなら core-js-builder の処理を参考に自分で builder を作ったほうが良いと思います

私の場合は minify だけできればよかったので terser で別に minify しました

const fs = require("fs")
const { join } = require("path")
const builder = require("core-js-builder")
const { minify } = require("terser")

const dirname = join(__dirname, "lib")
const full = "ie-polyfill.js"
const mini = "ie-polyfill.min.js"

const build_options = {
modules: ["es"],
blacklist: [],
targets: ["IE 11"],
}

const minify_options = {}

builder(build_options)
.then(code => {
const result = minify(code, minify_options)
if(result.error) throw result.error
full && fs.writeFileSync(join(dirname, full), code)
mini && fs.writeFileSync(join(dirname, mini), result.code)
})
.catch(err => console.error("build failed", err))

core-js-compat

今の所 core-js プロジェクトには 5 つのパッケージがあって core-js, core-js-builder, core-js-bundle の他には core-js-pure と core-js-compat があります
pure の方は名前通り純粋な関数で既存オブジェクトなどを拡張しないものです
compat はバージョン情報やモジュールのリストなどの情報が保存されています
ブラウザバージョンからどの機能が必要かを判断するのに使っています

core-js-builder を使う場合の modules や blacklist のモジュール指定は

const modulesList = Object.keys(require('core-js-compat/data'));

で取得した modulesList にあるものからしか選択できません
core-js のプロジェクトだと es, web, stable, features などがありますが modulesList には stable などがないので stable の指定はできません

core-js-compat/data.json
{
"es.symbol": {
"edge": "15",
"chrome": "49",
"firefox": "51",
"safari": "10.0",
"opera": "36",
"node": "6.0",
"samsung": "5.0",
"electron": "0.37",
"ios": "10.0"
},
"es.symbol.description": {
"chrome": "70",
"firefox": "63",
"safari": "12.1",
"opera": "57",
"node": "11.0",
"electron": "5.0"
},
"es.symbol.async-iterator": {
"chrome": "63",
"firefox": "55",
"safari": "12.0",
"opera": "50",
"node": "10.0",
"samsung": "8.2",
"electron": "3.0",
"ios": "12.0"
},
"es.symbol.has-instance": {
"edge": "15",
"chrome": "50",
……
……
……

data.json はこういうフォーマットで 各オブジェクトのキーを完全一致か 「.」 区切りのネームスペースの前方一致で指定できます

JavaScript 自体の機能は es.
stage 4 になってないプロポーザルの機能は esnext.
whatwg に仕様があるようなブラウザの機能は web.

のネームスペースになってます
未確定機能は esnext になるので stable にしたければ es を指定しておけばよいです