To understand your problem you need to know the difference between transpiler and polyfill, for example, check here What is the difference between polyfill and transpiler? or https://javascript.info/polyfills, simply put, transpiler for new grammar, polyfill for new api.
Babel is a transpiler, whose initial name called 6to5 but that was in 2015. So your words babel with the preset "env" transpiles later versions of ES into ES5 are NOT correct. Babel will transpile your codes for the browsers in your browserslist setting. If you have IE 11 in your browserslist it may transpile the code into ES5 for IE only, but not for other browsers.
But Babel doesn't do polyfill itself, it delegates that to corejs.
Then comes the core question, which part of your codes babel will transpile and which part of your codes babel will let corejs do polyfill. Your second assessment that this is the job that babel is meant to be doing by default is not correct. Babel do that based on browserslist setting in @babel/preset-env. So if your setting do not include IE, or maybe just { "browserslist": "> 1%, not dead" }
babel won't do any work for IE.
@babel/preset-env
in babel 7 makes babel setting a lot easier. I have several projects started before babel 7, so I have the preset setting like following (with this setting babel will transpile & polyfill for IE 10/11),
"presets": [
[
"env",
{
"targets": {
"browsers": [
"last 5 Chrome versions",
"last 1 Firefox versions",
"last 2 Safari versions",
"ie 10-11",
"last 3 edge versions"
]
}
}
]
],
PS, for why String.includes
belongs to polyfill but not transpiler, you can also check Compiling vs Polyfills with Babel (JavaScript) and Array.includes
is the same.