Does @babel/preset-env preserve ES modules when modules is auto?
0 reputation · 26 Apr 2021, 09:37 UTC
0 reputation · 26 Apr 2021, 09:37 UTC
Goal: Determine whether @babel/preset-env with modules set to "auto" preserves ES import/export syntax or converts it to CommonJS in a given build pipeline.
Constraint: Babel 7.x defaults modules to "auto", which defers the module transform decision to the calling tool. The Babel CLI may resolve auto to CommonJS, while Rollup or webpack configured for ES modules may leave import/export statements intact for tree-shaking. Identical .babelrc or babel.config.json can therefore emit different syntax depending on the integration.
Uncertainty: Without knowing which caller resolves the option, it is unclear whether a shared configuration produces stable module output across CLI and bundler workflows.
Which caller controls the final module syntax when modules is "auto"? Can the same preset config safely target both Babel CLI and an ESM-aware bundler without explicit modules overrides? What output should be expected when no bundler caller is present?
When modules is set to "auto" in @babel/preset-env, Babel does not make a fixed decision on whether to preserve ES modules; instead, it defers the transformation to the caller (the tool invoking Babel).
The final output depends entirely on the integration used to run the compilation. Because "auto" is a signal to check the caller's preferences, the same configuration file can produce different results in different environments:
babel-loader) or Rollup typically signal Babel to preserve ES modules. This allows the bundler to perform tree-shaking by analyzing the static import and export statements."auto" to "commonjs", transforming ES modules into require and module.exports.A shared configuration using modules: "auto" is not stable across different workflows. If your pipeline uses both the Babel CLI (e.g., for quick tests or legacy scripts) and a bundler (e.g., for production builds), you will get inconsistent module syntax.
To guarantee that ES modules are preserved regardless of the caller, you must explicitly disable module transformation:
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
To verify how your current environment resolves the "auto" setting, you can run these two tests:
npx babel src --out-dir dist. If the output files contain require() instead of import, the CLI is resolving "auto" to CommonJS.import statements remain, the bundler is successfully requesting ESM preservation.Diagnostic Note: To provide a more specific recommendation, please specify if you are using a custom babel-loader configuration or a specific version of the Babel CLI.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.