Missing core‑js polyfills after @babel/preset‑env compilation
0 reputation · 27 Sept 2023, 15:24 UTC
0 reputation · 27 Sept 2023, 15:24 UTC
When compiling a project with @babel/preset-env, the resulting bundle runs in Node 10 and throws ReferenceError: Promise is not defined. The Babel configuration is Babel 7.12, preset‑env targets es2015, corejs is set to 3, but useBuiltIns is omitted. The build is produced with babel-cli and executed in an older runtime.
The error suggests a missing polyfill, yet the configuration does not explicitly request core‑js imports. It is unclear whether Babel injects polyfills automatically when useBuiltIns is not set, and how the presence of both .babelrc and babel.config.js might affect the preset options.
Questions:
@babel/preset-env automatically emit core‑js polyfills when useBuiltIns is not specified?useBuiltIns: 'usage' and 'entry' in terms of polyfill injection and import placement?.babelrc and babel.config.js exist, which file controls preset-env settings such as corejs and useBuiltIns?No, @babel/preset-env does not automatically emit polyfills if the useBuiltIns option is omitted. By default, it only transforms modern JavaScript syntax (e.g., arrow functions to standard functions) but does not provide missing global objects or methods (like Promise) required by older runtimes.
To resolve the ReferenceError: Promise is not defined, you must explicitly configure useBuiltIns. The behavior differs significantly between the two primary options:
| Option | Mechanism | Requirement |
|---|---|---|
'entry' |
Replaces a single global import with a list of all polyfills needed for the target environment. | You must add import "core-js/stable"; at the very top of your entry file. |
'usage' |
Analyzes each file and injects import statements only for the specific features used in that file. |
No manual imports required; Babel handles injection automatically. |
When both babel.config.js and .babelrc exist, Babel 7 treats them differently based on scope:
babel.config.js: A project-wide configuration file. It is typically used for root-level settings and is applied to all files, including those in node_modules if configured to do so..babelrc: A file-relative configuration. It applies only to the directory it resides in and its subdirectories.If both are present, Babel merges them. However, settings in .babelrc generally override those in babel.config.js for files within that specific directory. If your preset-env options are split across both files, the resulting configuration may be inconsistent.
preset-env options into a single babel.config.js to avoid override conflicts.useBuiltIns:
{
"presets": [
[
"@babel/preset-env",
{
"targets": { "node": "10" },
"useBuiltIns": "usage",
"corejs": 3
}
]
]
}
core-js is listed in your package.json dependencies (not devDependencies), as it must be present in the production runtime.To confirm which configuration is actually being applied, run the following command in your terminal:
npx babel --show-config
Check the output to ensure useBuiltIns is correctly set to usage or entry.
Diagnostic Detail Needed: Are you compiling files inside node_modules? If so, .babelrc files within those packages may be overriding your project-wide settings.
Use comments to ask for clarification. Post a solution as an answer.
33,775 reputation · 27 Sept 2023, 16:27 UTC
useBuiltIns is setIn Babel 7, omitting useBuiltIns means @babel/preset‑env performs only syntax transforms; the corejs option is ignored. Consequently, globals like Promise remain undefined in runtimes that don’t provide them, which is why the bundle throws a ReferenceError on Node 10 if you’re running inside a sandbox that lacks the built‑in.
When useBuiltIns is present:
'entry' expects an explicit import \"core-js/stable\"; at the application entry point and rewrites that import into targeted polyfills.'usage' scans each file and automatically inserts the minimal core-js imports needed for used features, which can lead to duplicate imports across modules if not deduped.Regarding configuration files, babel.config.js applies project‑wide, while any .babelrc in a sub‑folder overrides the root settings for files under that folder. Prefer a single root config unless you need scoped overrides.
To confirm the cause, run babel --show-config on a source file and inspect the resolved preset‑env options, and verify the runtime’s global Promise presence with node -p \"typeof Promise\".