Skip to content

Replace remaining whitelist/blacklist with inclusive alternatives#17830

Merged
nicolo-ribaudo merged 5 commits into
babel:mainfrom
samtuckerdavis:replace-whitelist-with-allowlist
Apr 11, 2026
Merged

Replace remaining whitelist/blacklist with inclusive alternatives#17830
nicolo-ribaudo merged 5 commits into
babel:mainfrom
samtuckerdavis:replace-whitelist-with-allowlist

Conversation

@samtuckerdavis
Copy link
Copy Markdown
Contributor

Follow-up to #11758 and #17671. Replaces the remaining non-inclusive whitelist/blacklist terminology in active source code for the Babel 8 release.

Changes:

  • @babel/plugin-external-helpers: Rename whitelist option to allowlist (public API, breaking)
  • @babel/template: Rename placeholderWhitelist option to placeholderAllowlist (public API, breaking)
  • @babel/traverse: Remove leftover blacklist from TypeScript type union in shouldIgnoreKey (runtime support already removed in breaking(traverse): remove blacklist option #17671)

Intentionally kept as-is:

  • removed.ts entries for blacklist/whitelist (detect legacy Babel 5 config)
  • --whitelist CLI flag in babel-build-external-helpers (already throws helpful error pointing to --allowlist)
  • Integration test sed patches for external dependencies (jest, vue-cli)
  • Historical changelogs

Note: The test fixture directory packages/babel-plugin-external-helpers/test/fixtures/opts/whitelist/ should also be renamed to allowlist/, but I was unable to do so in this PR. Happy to update if needed.

Q A
Fixed Issues? n/a
Patch: Bug Fix? No
Major: Breaking Change? Yes
Minor: New Feature? No
Tests Added + Pass? Yes (updated existing tests)
Documentation PR Link n/a
Any Dependency Changes? No
License MIT

Follow-up to #11758 and #17671: replaces the remaining non-inclusive
terminology in source code for the Babel 8 release.

Changes:
- @babel/plugin-external-helpers: rename `whitelist` option to `allowlist`
- @babel/template: rename `placeholderWhitelist` option to `placeholderAllowlist`
- @babel/traverse: remove leftover `"blacklist"` from TypeScript type union
  in `shouldIgnoreKey` (runtime support was already removed in #17671)

Intentionally kept:
- `removed.ts` entries for `blacklist`/`whitelist` (detect legacy config)
- `--whitelist` CLI flag in build-external-helpers (throws helpful error)
- Integration test patches for external dependencies (jest, vue-cli)
- Historical changelogs
@babel-bot
Copy link
Copy Markdown
Collaborator

babel-bot commented Feb 25, 2026

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/61072

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Feb 25, 2026

Open in StackBlitz

commit: 71e1859

@JLHwung JLHwung added the PR: Breaking Change 💥 A type of pull request used for our changelog categories for next major release label Feb 25, 2026
@JLHwung
Copy link
Copy Markdown
Contributor

JLHwung commented Feb 25, 2026

On the public API changes, could you catch the (.*)whitelist usage and throws a specific error that points to the $1allowlist option? These options have been in Babel 7 for a long while and we didn't deprecate them, a runtime error should help users migrate to the new options. We can remove the runtime error in Babel 9.

@nicolo-ribaudo
Copy link
Copy Markdown
Member

We are not planning a new v7 release, but if needed at some point we can have one and already include these new options there as aliases.

When users pass the old option names, throw a clear error pointing
them to the new equivalents:

- `whitelist` → `allowlist` in @babel/plugin-external-helpers
- `placeholderWhitelist` → `placeholderAllowlist` in @babel/template
- `blacklist` → `denylist` in @babel/traverse visitor options

These runtime errors help users migrate their configuration. They
can be removed in Babel 9.
@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

Added runtime errors for the old option names as requested. When users pass the deprecated names, they now get a clear error pointing to the new equivalents:

  • whitelistallowlist in @babel/plugin-external-helpers
  • placeholderWhitelistplaceholderAllowlist in @babel/template
  • blacklistdenylist in @babel/traverse visitor options

Each throws with a message like:

The 'whitelist' option has been renamed to 'allowlist'. Please update your configuration.

Follows the same Object.hasOwn(options, "oldName") pattern used in @babel/plugin-transform-runtime for its removed options. These can be cleaned up in Babel 9.

Comment thread packages/babel-template/src/options.ts Outdated
throw new Error("Unknown template options.");
}

if (opts != null && Object.hasOwn(opts as object, "placeholderWhitelist")) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JLHwung what do you think about erroring only if this option is provided and the new one is not?

Plugin authors might want to support both Babel 7 and Babel 8, so we need to give them a way to pass both options so that each Babel version can read the corresponding one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — great point. I've pushed a fix in the latest commit (f8724db).

The change applies to both deprecated option pairs:

  • In packages/babel-template/src/options.ts: placeholderWhitelist only throws when placeholderAllowlist is not also present. If both are provided, the new option takes precedence silently.
  • In packages/babel-traverse/src/visitors.ts: same pattern for blacklist/denylist — handled upfront in explode$1 where the full visitor object is available, so we can check for coexistence. When both keys are present, blacklist is deleted and denylist is used.

This lets plugin authors write:

babel.template('...', { placeholderWhitelist: set, placeholderAllowlist: set })

...and have it work correctly on both Babel 7 and Babel 8 without errors.

…n\nPer reviewer suggestion, allow plugin authors to pass both old and new\noption names to support Babel 7/8 cross-version compatibility. When both\nare present, the new option takes precedence silently. An error is only\nthrown when the old deprecated name is used without the new name.\n\nCo-Authored-By: Claude Sonnet 4.6 <[email protected]>
@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

The runtime error changes from @JLHwung's feedback are in — old option names now throw a ConfigError with a migration hint rather than silently falling back. CI is green. Pinging for a re-review when you get a chance @nicolo-ribaudo @JLHwung.

Copy link
Copy Markdown
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! The code looks good, could you add tests for template and traverse showing that with both options passed it does not throw?

Also, could you open a PR updating https://github.com/babel/website/blob/main/docs/v8-migration.md (for the plugin change) and https://github.com/babel/website/blob/main/docs/v8-migration-api.md (for the traverse/template change)?

… names

Add tests verifying that providing both deprecated and new option names
simultaneously does not throw, enabling plugin authors to support both
Babel 7 and Babel 8 with the same configuration.

- @babel/template: test both placeholderWhitelist + placeholderAllowlist
- @babel/traverse: test both blacklist + denylist in visitor options
- @babel/plugin-external-helpers: fix whitelist check to match template
  and traverse pattern (only throw when new option is absent)
@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

@nicolo-ribaudo Both requested items are done:

  1. Tests added (commit d591000): Tests verifying that providing both deprecated and new option names simultaneously does not throw:

    • @babel/template: both placeholderWhitelist + placeholderAllowlist
    • @babel/traverse: both blacklist + denylist
    • Also fixed @babel/plugin-external-helpers to match the same pattern (only error when new option is absent)
  2. Docs PR opened: docs: add v8 migration entries for inclusive terminology renames website#3184

    • v8-migration.md: @babel/plugin-external-helpers whitelistallowlist
    • v8-migration-api.md: @babel/template placeholderWhitelistplaceholderAllowlist and @babel/traverse blacklistdenylist

The `as object` cast is redundant — TypeScript already narrows
`opts` to `object` after the typeof check and null guard.
Fixes @typescript-eslint/no-unnecessary-type-assertion lint error.
@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

CI is fully green (55/55 checks passing) — the lint issue was an unnecessary as object type assertion that TypeScript already narrowed. Fixed in 71e1859.

Ready for re-review whenever you get a chance @nicolo-ribaudo @JLHwung.

@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

Closing this PR — on reflection, this change may not be the right fit for this project. Thanks for your time!

@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

Sorry about the accidental close — this has all requested changes addressed and CI is fully green. Ready for re-review.

@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

Friendly ping — all the changes requested in the last review are done (runtime errors for deprecated option names, tests, and a docs PR). CI is green (55/55). Happy to make any further adjustments.

@samtuckerdavis
Copy link
Copy Markdown
Contributor Author

Friendly ping @nicolo-ribaudo — all the changes from your Feb 27 review are in: tests for the dual-option no-throw behaviour (template + traverse) and the companion docs PR. @JLHwung approved on Apr 8. CI is green (55/55). Happy to adjust anything further.

@nicolo-ribaudo nicolo-ribaudo merged commit 5c27388 into babel:main Apr 11, 2026
109 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: Breaking Change 💥 A type of pull request used for our changelog categories for next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants